blob: ce646846dfbe83ae3e4813614fd6e3431b34cfd4 [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
Steve Dowercc16be82016-09-08 10:35:16 -0700167#define HAVE_WSPAWNV 1
168#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#define HAVE_SYSTEM 1
171#define HAVE_CWAIT 1
172#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000173#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000174#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175/* Unix functions that the configure script doesn't check for */
176#define HAVE_EXECV 1
177#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000179#define HAVE_FORK1 1
180#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_GETEGID 1
182#define HAVE_GETEUID 1
183#define HAVE_GETGID 1
184#define HAVE_GETPPID 1
185#define HAVE_GETUID 1
186#define HAVE_KILL 1
187#define HAVE_OPENDIR 1
188#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000189#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000193#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000194
Victor Stinnera2f7c002012-02-08 03:36:25 +0100195
Larry Hastings61272b72014-01-07 12:41:53 -0800196/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000197# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800198module os
Larry Hastings61272b72014-01-07 12:41:53 -0800199[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000200/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100201
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000204#if defined(__sgi)&&_COMPILER_VERSION>=700
205/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
206 (default) */
207extern char *ctermid_r(char *);
208#endif
209
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000210#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
220#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(char *);
222extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chdir(const char *);
225extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000228/*#ifdef HAVE_FCHMOD
229extern int fchmod(int, mode_t);
230#endif*/
231/*#ifdef HAVE_LCHMOD
232extern int lchmod(const char *, mode_t);
233#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chown(const char *, uid_t, gid_t);
235extern char *getcwd(char *, int);
236extern char *strerror(int);
237extern int link(const char *, const char *);
238extern int rename(const char *, const char *);
239extern int stat(const char *, struct stat *);
240extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000243#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_UTIME_H
252#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000255#ifdef HAVE_SYS_UTIME_H
256#include <sys/utime.h>
257#define HAVE_UTIME_H /* pretend we do for the rest of this file */
258#endif /* HAVE_SYS_UTIME_H */
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#ifdef HAVE_SYS_TIMES_H
261#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_PARAM_H
265#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
268#ifdef HAVE_SYS_UTSNAME_H
269#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000276#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#include <direct.h>
278#define NAMLEN(dirent) strlen((dirent)->d_name)
279#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
301#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
322#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000323static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000324#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000325#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#if defined(PATH_MAX) && PATH_MAX > 1024
329#define MAXPATHLEN PATH_MAX
330#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#endif /* MAXPATHLEN */
334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000335#ifdef UNION_WAIT
336/* Emulate some macros on systems that have a union instead of macros */
337
338#ifndef WIFEXITED
339#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
340#endif
341
342#ifndef WEXITSTATUS
343#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
344#endif
345
346#ifndef WTERMSIG
347#define WTERMSIG(u_wait) ((u_wait).w_termsig)
348#endif
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350#define WAIT_TYPE union wait
351#define WAIT_STATUS_INT(s) (s.w_status)
352
353#else /* !UNION_WAIT */
354#define WAIT_TYPE int
355#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000356#endif /* UNION_WAIT */
357
Greg Wardb48bc172000-03-01 21:51:56 +0000358/* Don't use the "_r" form if we don't need it (also, won't have a
359 prototype for it, at least on Solaris -- maybe others as well?). */
360#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
361#define USE_CTERMID_R
362#endif
363
Fred Drake699f3522000-06-29 21:12:41 +0000364/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000365#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000366#undef FSTAT
367#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200368#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700370# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200371# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800372# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000373#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define FSTAT fstat
377# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000378#endif
379
Tim Peters11b23062003-04-23 02:39:17 +0000380#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#include <sys/mkdev.h>
382#else
383#if defined(MAJOR_IN_SYSMACROS)
384#include <sys/sysmacros.h>
385#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000386#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
387#include <sys/mkdev.h>
388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000389#endif
Fred Drake699f3522000-06-29 21:12:41 +0000390
Victor Stinner6edddfa2013-11-24 19:22:57 +0100391#define DWORD_MAX 4294967295U
392
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100394#define INITFUNC PyInit_nt
395#define MODNAME "nt"
396#else
397#define INITFUNC PyInit_posix
398#define MODNAME "posix"
399#endif
400
401#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200402/* defined in fileutils.c */
403PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
404PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
405 ULONG, struct _Py_stat_struct *);
406#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700407
408#ifdef MS_WINDOWS
409static int
410win32_warn_bytes_api()
411{
412 return PyErr_WarnEx(PyExc_DeprecationWarning,
413 "The Windows bytes API has been deprecated, "
414 "use Unicode filenames instead",
415 1);
416}
417#endif
418
419
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420#ifndef MS_WINDOWS
421PyObject *
422_PyLong_FromUid(uid_t uid)
423{
424 if (uid == (uid_t)-1)
425 return PyLong_FromLong(-1);
426 return PyLong_FromUnsignedLong(uid);
427}
428
429PyObject *
430_PyLong_FromGid(gid_t gid)
431{
432 if (gid == (gid_t)-1)
433 return PyLong_FromLong(-1);
434 return PyLong_FromUnsignedLong(gid);
435}
436
437int
438_Py_Uid_Converter(PyObject *obj, void *p)
439{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700440 uid_t uid;
441 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200442 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200443 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444 unsigned long uresult;
445
446 index = PyNumber_Index(obj);
447 if (index == NULL) {
448 PyErr_Format(PyExc_TypeError,
449 "uid should be integer, not %.200s",
450 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200451 return 0;
452 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700453
454 /*
455 * Handling uid_t is complicated for two reasons:
456 * * Although uid_t is (always?) unsigned, it still
457 * accepts -1.
458 * * We don't know its size in advance--it may be
459 * bigger than an int, or it may be smaller than
460 * a long.
461 *
462 * So a bit of defensive programming is in order.
463 * Start with interpreting the value passed
464 * in as a signed long and see if it works.
465 */
466
467 result = PyLong_AsLongAndOverflow(index, &overflow);
468
469 if (!overflow) {
470 uid = (uid_t)result;
471
472 if (result == -1) {
473 if (PyErr_Occurred())
474 goto fail;
475 /* It's a legitimate -1, we're done. */
476 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200477 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700478
479 /* Any other negative number is disallowed. */
480 if (result < 0)
481 goto underflow;
482
483 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200484 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700485 (long)uid != result)
486 goto underflow;
487 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200488 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700489
490 if (overflow < 0)
491 goto underflow;
492
493 /*
494 * Okay, the value overflowed a signed long. If it
495 * fits in an *unsigned* long, it may still be okay,
496 * as uid_t may be unsigned long on this platform.
497 */
498 uresult = PyLong_AsUnsignedLong(index);
499 if (PyErr_Occurred()) {
500 if (PyErr_ExceptionMatches(PyExc_OverflowError))
501 goto overflow;
502 goto fail;
503 }
504
505 uid = (uid_t)uresult;
506
507 /*
508 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
509 * but this value would get interpreted as (uid_t)-1 by chown
510 * and its siblings. That's not what the user meant! So we
511 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100512 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 */
514 if (uid == (uid_t)-1)
515 goto overflow;
516
517 /* Ensure the value wasn't truncated. */
518 if (sizeof(uid_t) < sizeof(long) &&
519 (unsigned long)uid != uresult)
520 goto overflow;
521 /* fallthrough */
522
523success:
524 Py_DECREF(index);
525 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 return 1;
527
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200529 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 "uid is less than minimum");
531 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200534 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 "uid is greater than maximum");
536 /* fallthrough */
537
538fail:
539 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200540 return 0;
541}
542
543int
544_Py_Gid_Converter(PyObject *obj, void *p)
545{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546 gid_t gid;
547 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200548 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200549 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550 unsigned long uresult;
551
552 index = PyNumber_Index(obj);
553 if (index == NULL) {
554 PyErr_Format(PyExc_TypeError,
555 "gid should be integer, not %.200s",
556 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200557 return 0;
558 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700559
560 /*
561 * Handling gid_t is complicated for two reasons:
562 * * Although gid_t is (always?) unsigned, it still
563 * accepts -1.
564 * * We don't know its size in advance--it may be
565 * bigger than an int, or it may be smaller than
566 * a long.
567 *
568 * So a bit of defensive programming is in order.
569 * Start with interpreting the value passed
570 * in as a signed long and see if it works.
571 */
572
573 result = PyLong_AsLongAndOverflow(index, &overflow);
574
575 if (!overflow) {
576 gid = (gid_t)result;
577
578 if (result == -1) {
579 if (PyErr_Occurred())
580 goto fail;
581 /* It's a legitimate -1, we're done. */
582 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200583 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700584
585 /* Any other negative number is disallowed. */
586 if (result < 0) {
587 goto underflow;
588 }
589
590 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592 (long)gid != result)
593 goto underflow;
594 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200595 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700596
597 if (overflow < 0)
598 goto underflow;
599
600 /*
601 * Okay, the value overflowed a signed long. If it
602 * fits in an *unsigned* long, it may still be okay,
603 * as gid_t may be unsigned long on this platform.
604 */
605 uresult = PyLong_AsUnsignedLong(index);
606 if (PyErr_Occurred()) {
607 if (PyErr_ExceptionMatches(PyExc_OverflowError))
608 goto overflow;
609 goto fail;
610 }
611
612 gid = (gid_t)uresult;
613
614 /*
615 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
616 * but this value would get interpreted as (gid_t)-1 by chown
617 * and its siblings. That's not what the user meant! So we
618 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100619 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 */
621 if (gid == (gid_t)-1)
622 goto overflow;
623
624 /* Ensure the value wasn't truncated. */
625 if (sizeof(gid_t) < sizeof(long) &&
626 (unsigned long)gid != uresult)
627 goto overflow;
628 /* fallthrough */
629
630success:
631 Py_DECREF(index);
632 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200633 return 1;
634
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 "gid is less than minimum");
638 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642 "gid is greater than maximum");
643 /* fallthrough */
644
645fail:
646 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200647 return 0;
648}
649#endif /* MS_WINDOWS */
650
651
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700652#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800653
654
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200655#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
656static int
657_Py_Dev_Converter(PyObject *obj, void *p)
658{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200659 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200660 if (PyErr_Occurred())
661 return 0;
662 return 1;
663}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800664#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200665
666
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400668/*
669 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
670 * without the int cast, the value gets interpreted as uint (4291925331),
671 * which doesn't play nicely with all the initializer lines in this file that
672 * look like this:
673 * int dir_fd = DEFAULT_DIR_FD;
674 */
675#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700676#else
677#define DEFAULT_DIR_FD (-100)
678#endif
679
680static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300681_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200682{
683 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684 long long_value;
685
686 PyObject *index = PyNumber_Index(o);
687 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 return 0;
689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300691 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 long_value = PyLong_AsLongAndOverflow(index, &overflow);
693 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300694 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200695 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700696 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 return 0;
699 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200700 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700703 return 0;
704 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700705
Larry Hastings9cf065c2012-06-22 16:30:09 -0700706 *p = (int)long_value;
707 return 1;
708}
709
710static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200711dir_fd_converter(PyObject *o, void *p)
712{
713 if (o == Py_None) {
714 *(int *)p = DEFAULT_DIR_FD;
715 return 1;
716 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300717 else if (PyIndex_Check(o)) {
718 return _fd_converter(o, (int *)p);
719 }
720 else {
721 PyErr_Format(PyExc_TypeError,
722 "argument should be integer or None, not %.200s",
723 Py_TYPE(o)->tp_name);
724 return 0;
725 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700726}
727
728
Larry Hastings9cf065c2012-06-22 16:30:09 -0700729/*
730 * A PyArg_ParseTuple "converter" function
731 * that handles filesystem paths in the manner
732 * preferred by the os module.
733 *
734 * path_converter accepts (Unicode) strings and their
735 * subclasses, and bytes and their subclasses. What
736 * it does with the argument depends on the platform:
737 *
738 * * On Windows, if we get a (Unicode) string we
739 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700740 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700741 *
742 * * On all other platforms, strings are encoded
743 * to bytes using PyUnicode_FSConverter, then we
744 * extract the char * from the bytes object and
745 * return that.
746 *
747 * path_converter also optionally accepts signed
748 * integers (representing open file descriptors) instead
749 * of path strings.
750 *
751 * Input fields:
752 * path.nullable
753 * If nonzero, the path is permitted to be None.
754 * path.allow_fd
755 * If nonzero, the path is permitted to be a file handle
756 * (a signed int) instead of a string.
757 * path.function_name
758 * If non-NULL, path_converter will use that as the name
759 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700760 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 * path.argument_name
762 * If non-NULL, path_converter will use that as the name
763 * of the parameter in error messages.
764 * (If path.argument_name is NULL it uses "path".)
765 *
766 * Output fields:
767 * path.wide
768 * Points to the path if it was expressed as Unicode
769 * and was not encoded. (Only used on Windows.)
770 * path.narrow
771 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700772 * or it was Unicode and was encoded to bytes. (On Windows,
773 * is an non-zero integer if the path was expressed as bytes.
774 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700775 * path.fd
776 * Contains a file descriptor if path.accept_fd was true
777 * and the caller provided a signed integer instead of any
778 * sort of string.
779 *
780 * WARNING: if your "path" parameter is optional, and is
781 * unspecified, path_converter will never get called.
782 * So if you set allow_fd, you *MUST* initialize path.fd = -1
783 * yourself!
784 * path.length
785 * The length of the path in characters, if specified as
786 * a string.
787 * path.object
788 * The original object passed in.
789 * path.cleanup
790 * For internal use only. May point to a temporary object.
791 * (Pay no attention to the man behind the curtain.)
792 *
793 * At most one of path.wide or path.narrow will be non-NULL.
794 * If path was None and path.nullable was set,
795 * or if path was an integer and path.allow_fd was set,
796 * both path.wide and path.narrow will be NULL
797 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200798 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799 * path_converter takes care to not write to the path_t
800 * unless it's successful. However it must reset the
801 * "cleanup" field each time it's called.
802 *
803 * Use as follows:
804 * path_t path;
805 * memset(&path, 0, sizeof(path));
806 * PyArg_ParseTuple(args, "O&", path_converter, &path);
807 * // ... use values from path ...
808 * path_cleanup(&path);
809 *
810 * (Note that if PyArg_Parse fails you don't need to call
811 * path_cleanup(). However it is safe to do so.)
812 */
813typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100814 const char *function_name;
815 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 int nullable;
817 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300818 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700819#ifdef MS_WINDOWS
820 BOOL narrow;
821#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300822 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700823#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 int fd;
825 Py_ssize_t length;
826 PyObject *object;
827 PyObject *cleanup;
828} path_t;
829
Steve Dowercc16be82016-09-08 10:35:16 -0700830#ifdef MS_WINDOWS
831#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
832 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
833#else
Larry Hastings2f936352014-08-05 14:04:04 +1000834#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
835 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700836#endif
Larry Hastings31826802013-10-19 00:09:25 -0700837
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838static void
839path_cleanup(path_t *path) {
840 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200841 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700842 }
843}
844
845static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300846path_converter(PyObject *o, void *p)
847{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700848 path_t *path = (path_t *)p;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700849 PyObject *bytes, *to_cleanup = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700850 Py_ssize_t length;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700851 int is_index, is_buffer, is_bytes, is_unicode;
852 /* Default to failure, forcing explicit signaling of succcess. */
853 int ret = 0;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300854 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700855#ifdef MS_WINDOWS
856 PyObject *wo;
857 const wchar_t *wide;
858#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859
860#define FORMAT_EXCEPTION(exc, fmt) \
861 PyErr_Format(exc, "%s%s" fmt, \
862 path->function_name ? path->function_name : "", \
863 path->function_name ? ": " : "", \
864 path->argument_name ? path->argument_name : "path")
865
866 /* Py_CLEANUP_SUPPORTED support */
867 if (o == NULL) {
868 path_cleanup(path);
869 return 1;
870 }
871
Brett Cannon3f9183b2016-08-26 14:44:48 -0700872 /* Ensure it's always safe to call path_cleanup(). */
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 path->cleanup = NULL;
874
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300875 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700877#ifdef MS_WINDOWS
878 path->narrow = FALSE;
879#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700881#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 path->length = 0;
883 path->object = o;
884 path->fd = -1;
885 return 1;
886 }
887
Brett Cannon3f9183b2016-08-26 14:44:48 -0700888 /* Only call this here so that we don't treat the return value of
889 os.fspath() as an fd or buffer. */
890 is_index = path->allow_fd && PyIndex_Check(o);
891 is_buffer = PyObject_CheckBuffer(o);
892 is_bytes = PyBytes_Check(o);
893 is_unicode = PyUnicode_Check(o);
894
895 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
896 /* Inline PyOS_FSPath() for better error messages. */
897 _Py_IDENTIFIER(__fspath__);
898 PyObject *func = NULL;
899
900 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
901 if (NULL == func) {
902 goto error_exit;
903 }
904
905 o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL);
906 Py_DECREF(func);
907 if (NULL == o) {
908 goto error_exit;
909 }
910 else if (PyUnicode_Check(o)) {
911 is_unicode = 1;
912 }
913 else if (PyBytes_Check(o)) {
914 is_bytes = 1;
915 }
916 else {
917 goto error_exit;
918 }
919 }
920
921 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -0700923 wide = PyUnicode_AsWideCharString(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100924 if (!wide) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700925 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926 }
Victor Stinner59799a82013-11-13 14:17:30 +0100927 if (length > 32767) {
928 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700929 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300931 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 goto exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300934 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935
936 path->wide = wide;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 path->length = length;
938 path->object = o;
939 path->fd = -1;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700940 ret = 1;
941 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300943 if (!PyUnicode_FSConverter(o, &bytes)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700944 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300945 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946#endif
947 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700948 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300949 bytes = o;
950 Py_INCREF(bytes);
951 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300953 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
954 "%s%s%s should be %s, not %.200s",
955 path->function_name ? path->function_name : "",
956 path->function_name ? ": " : "",
957 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700958 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
959 "integer or None" :
960 path->allow_fd ? "string, bytes, os.PathLike or integer" :
961 path->nullable ? "string, bytes, os.PathLike or None" :
962 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300963 Py_TYPE(o)->tp_name)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700964 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300965 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300966 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 if (!bytes) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 }
970 }
Steve Dowercc16be82016-09-08 10:35:16 -0700971 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300972 if (!_fd_converter(o, &path->fd)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700973 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300974 }
975 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700976#ifdef MS_WINDOWS
977 path->narrow = FALSE;
978#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300979 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700980#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300981 path->length = 0;
982 path->object = o;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700983 ret = 1;
984 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300985 }
986 else {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 error_exit:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300988 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
989 path->function_name ? path->function_name : "",
990 path->function_name ? ": " : "",
991 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700992 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
993 "integer or None" :
994 path->allow_fd ? "string, bytes, os.PathLike or integer" :
995 path->nullable ? "string, bytes, os.PathLike or None" :
996 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300997 Py_TYPE(o)->tp_name);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700998 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700999 }
1000
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001003 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001004 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001006 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 }
1008
Steve Dowercc16be82016-09-08 10:35:16 -07001009#ifdef MS_WINDOWS
1010 wo = PyUnicode_DecodeFSDefaultAndSize(
1011 narrow,
1012 length
1013 );
1014 if (!wo) {
1015 goto exit;
1016 }
1017
1018 wide = PyUnicode_AsWideCharString(wo, &length);
1019 Py_DECREF(wo);
1020
1021 if (!wide) {
1022 goto exit;
1023 }
1024 if (length > 32767) {
1025 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
1026 goto exit;
1027 }
1028 if (wcslen(wide) != length) {
1029 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
1030 goto exit;
1031 }
1032 path->wide = wide;
1033 path->narrow = TRUE;
1034#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 path->wide = NULL;
1036 path->narrow = narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001037#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 path->length = length;
1039 path->object = o;
1040 path->fd = -1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001041 if (bytes == o) {
1042 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 ret = 1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 }
1045 else {
1046 path->cleanup = bytes;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001047 ret = Py_CLEANUP_SUPPORTED;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001049 exit:
1050 Py_XDECREF(to_cleanup);
1051 return ret;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052}
1053
1054static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001055argument_unavailable_error(const char *function_name, const char *argument_name)
1056{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001057 PyErr_Format(PyExc_NotImplementedError,
1058 "%s%s%s unavailable on this platform",
1059 (function_name != NULL) ? function_name : "",
1060 (function_name != NULL) ? ": ": "",
1061 argument_name);
1062}
1063
1064static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001065dir_fd_unavailable(PyObject *o, void *p)
1066{
1067 int dir_fd;
1068 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001070 if (dir_fd != DEFAULT_DIR_FD) {
1071 argument_unavailable_error(NULL, "dir_fd");
1072 return 0;
1073 }
1074 *(int *)p = dir_fd;
1075 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076}
1077
1078static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001079fd_specified(const char *function_name, int fd)
1080{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 if (fd == -1)
1082 return 0;
1083
1084 argument_unavailable_error(function_name, "fd");
1085 return 1;
1086}
1087
1088static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001089follow_symlinks_specified(const char *function_name, int follow_symlinks)
1090{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 if (follow_symlinks)
1092 return 0;
1093
1094 argument_unavailable_error(function_name, "follow_symlinks");
1095 return 1;
1096}
1097
1098static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001099path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1100{
Steve Dowercc16be82016-09-08 10:35:16 -07001101 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1102#ifndef MS_WINDOWS
1103 && !path->narrow
1104#endif
1105 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106 PyErr_Format(PyExc_ValueError,
1107 "%s: can't specify dir_fd without matching path",
1108 function_name);
1109 return 1;
1110 }
1111 return 0;
1112}
1113
1114static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001115dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1116{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001117 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1118 PyErr_Format(PyExc_ValueError,
1119 "%s: can't specify both dir_fd and fd",
1120 function_name);
1121 return 1;
1122 }
1123 return 0;
1124}
1125
1126static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001127fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1128 int follow_symlinks)
1129{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130 if ((fd > 0) && (!follow_symlinks)) {
1131 PyErr_Format(PyExc_ValueError,
1132 "%s: cannot use fd and follow_symlinks together",
1133 function_name);
1134 return 1;
1135 }
1136 return 0;
1137}
1138
1139static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001140dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1141 int follow_symlinks)
1142{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1144 PyErr_Format(PyExc_ValueError,
1145 "%s: cannot use dir_fd and follow_symlinks together",
1146 function_name);
1147 return 1;
1148 }
1149 return 0;
1150}
1151
Larry Hastings2f936352014-08-05 14:04:04 +10001152#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001153 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001154#else
Larry Hastings2f936352014-08-05 14:04:04 +10001155 typedef off_t Py_off_t;
1156#endif
1157
1158static int
1159Py_off_t_converter(PyObject *arg, void *addr)
1160{
1161#ifdef HAVE_LARGEFILE_SUPPORT
1162 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1163#else
1164 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001165#endif
1166 if (PyErr_Occurred())
1167 return 0;
1168 return 1;
1169}
Larry Hastings2f936352014-08-05 14:04:04 +10001170
1171static PyObject *
1172PyLong_FromPy_off_t(Py_off_t offset)
1173{
1174#ifdef HAVE_LARGEFILE_SUPPORT
1175 return PyLong_FromLongLong(offset);
1176#else
1177 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001178#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001179}
1180
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001181#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182
1183static int
Brian Curtind25aef52011-06-13 15:16:04 -05001184win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001185{
Martin Panter70214ad2016-08-04 02:38:59 +00001186 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1187 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001189
1190 if (0 == DeviceIoControl(
1191 reparse_point_handle,
1192 FSCTL_GET_REPARSE_POINT,
1193 NULL, 0, /* in buffer */
1194 target_buffer, sizeof(target_buffer),
1195 &n_bytes_returned,
1196 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001197 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001198
1199 if (reparse_tag)
1200 *reparse_tag = rdb->ReparseTag;
1201
Brian Curtind25aef52011-06-13 15:16:04 -05001202 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001203}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001204
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001205#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001206
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001208#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001209/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001210** environ directly, we must obtain it with _NSGetEnviron(). See also
1211** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001212*/
1213#include <crt_externs.h>
1214static char **environ;
1215#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218
Barry Warsaw53699e91996-12-10 23:23:01 +00001219static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001220convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221{
Victor Stinner8c62be82010-05-06 00:08:46 +00001222 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001224 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001225#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001227#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001228
Victor Stinner8c62be82010-05-06 00:08:46 +00001229 d = PyDict_New();
1230 if (d == NULL)
1231 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001232#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 if (environ == NULL)
1234 environ = *_NSGetEnviron();
1235#endif
1236#ifdef MS_WINDOWS
1237 /* _wenviron must be initialized in this way if the program is started
1238 through main() instead of wmain(). */
1239 _wgetenv(L"");
1240 if (_wenviron == NULL)
1241 return d;
1242 /* This part ignores errors */
1243 for (e = _wenviron; *e != NULL; e++) {
1244 PyObject *k;
1245 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001246 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001247 if (p == NULL)
1248 continue;
1249 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1250 if (k == NULL) {
1251 PyErr_Clear();
1252 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001253 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1255 if (v == NULL) {
1256 PyErr_Clear();
1257 Py_DECREF(k);
1258 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001259 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001260 if (PyDict_GetItem(d, k) == NULL) {
1261 if (PyDict_SetItem(d, k, v) != 0)
1262 PyErr_Clear();
1263 }
1264 Py_DECREF(k);
1265 Py_DECREF(v);
1266 }
1267#else
1268 if (environ == NULL)
1269 return d;
1270 /* This part ignores errors */
1271 for (e = environ; *e != NULL; e++) {
1272 PyObject *k;
1273 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001274 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 if (p == NULL)
1276 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001277 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 if (k == NULL) {
1279 PyErr_Clear();
1280 continue;
1281 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001282 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 if (v == NULL) {
1284 PyErr_Clear();
1285 Py_DECREF(k);
1286 continue;
1287 }
1288 if (PyDict_GetItem(d, k) == NULL) {
1289 if (PyDict_SetItem(d, k, v) != 0)
1290 PyErr_Clear();
1291 }
1292 Py_DECREF(k);
1293 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001294 }
1295#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001296 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297}
1298
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299/* Set a POSIX-specific error from errno, and return NULL */
1300
Barry Warsawd58d7641998-07-23 16:14:40 +00001301static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001302posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305}
Mark Hammondef8b6542001-05-13 08:04:26 +00001306
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001307#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001308static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001309win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001310{
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 /* XXX We should pass the function name along in the future.
1312 (winreg.c also wants to pass the function name.)
1313 This would however require an additional param to the
1314 Windows error object, which is non-trivial.
1315 */
1316 errno = GetLastError();
1317 if (filename)
1318 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1319 else
1320 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001321}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001322
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001323static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001324win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001325{
1326 /* XXX - see win32_error for comments on 'function' */
1327 errno = GetLastError();
1328 if (filename)
1329 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001330 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001331 errno,
1332 filename);
1333 else
1334 return PyErr_SetFromWindowsErr(errno);
1335}
1336
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001337#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338
Larry Hastings9cf065c2012-06-22 16:30:09 -07001339static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001340path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001341{
1342#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001343 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1344 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001345#else
Victor Stinner292c8352012-10-30 02:17:38 +01001346 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001347#endif
1348}
1349
Larry Hastings31826802013-10-19 00:09:25 -07001350
Larry Hastingsb0827312014-02-09 22:05:19 -08001351static PyObject *
1352path_error2(path_t *path, path_t *path2)
1353{
1354#ifdef MS_WINDOWS
1355 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1356 0, path->object, path2->object);
1357#else
1358 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1359 path->object, path2->object);
1360#endif
1361}
1362
1363
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364/* POSIX generic methods */
1365
Larry Hastings2f936352014-08-05 14:04:04 +10001366static int
1367fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001368{
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001370 int *pointer = (int *)p;
1371 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001373 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001374 *pointer = fd;
1375 return 1;
1376}
1377
1378static PyObject *
1379posix_fildes_fd(int fd, int (*func)(int))
1380{
1381 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001382 int async_err = 0;
1383
1384 do {
1385 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001386 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001387 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001388 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001389 Py_END_ALLOW_THREADS
1390 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1391 if (res != 0)
1392 return (!async_err) ? posix_error() : NULL;
1393 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001394}
Guido van Rossum21142a01999-01-08 21:05:37 +00001395
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001396
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001397#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398/* This is a reimplementation of the C library's chdir function,
1399 but one that produces Win32 errors instead of DOS error codes.
1400 chdir is essentially a wrapper around SetCurrentDirectory; however,
1401 it also needs to set "magic" environment variables indicating
1402 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001403static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404win32_wchdir(LPCWSTR path)
1405{
Victor Stinnered537822015-12-13 21:40:26 +01001406 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 int result;
1408 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 if(!SetCurrentDirectoryW(path))
1411 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001412 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 if (!result)
1414 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001415 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001416 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 if (!new_path) {
1418 SetLastError(ERROR_OUTOFMEMORY);
1419 return FALSE;
1420 }
1421 result = GetCurrentDirectoryW(result, new_path);
1422 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001423 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return FALSE;
1425 }
1426 }
1427 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1428 wcsncmp(new_path, L"//", 2) == 0)
1429 /* UNC path, nothing to do. */
1430 return TRUE;
1431 env[1] = new_path[0];
1432 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001433 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001434 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436}
1437#endif
1438
Martin v. Löwis14694662006-02-03 12:54:16 +00001439#ifdef MS_WINDOWS
1440/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1441 - time stamps are restricted to second resolution
1442 - file modification times suffer from forth-and-back conversions between
1443 UTC and local time
1444 Therefore, we implement our own stat, based on the Win32 API directly.
1445*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001446#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001447#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001448
Victor Stinner6036e442015-03-08 01:58:04 +01001449static void
Steve Dowercc16be82016-09-08 10:35:16 -07001450find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1451 BY_HANDLE_FILE_INFORMATION *info,
1452 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001453{
1454 memset(info, 0, sizeof(*info));
1455 info->dwFileAttributes = pFileData->dwFileAttributes;
1456 info->ftCreationTime = pFileData->ftCreationTime;
1457 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1458 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1459 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1460 info->nFileSizeLow = pFileData->nFileSizeLow;
1461/* info->nNumberOfLinks = 1; */
1462 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1463 *reparse_tag = pFileData->dwReserved0;
1464 else
1465 *reparse_tag = 0;
1466}
1467
Guido van Rossumd8faa362007-04-27 19:54:29 +00001468static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001469attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001470{
Victor Stinner8c62be82010-05-06 00:08:46 +00001471 HANDLE hFindFile;
1472 WIN32_FIND_DATAW FileData;
1473 hFindFile = FindFirstFileW(pszFile, &FileData);
1474 if (hFindFile == INVALID_HANDLE_VALUE)
1475 return FALSE;
1476 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001477 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001478 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001479}
1480
Brian Curtind25aef52011-06-13 15:16:04 -05001481static BOOL
1482get_target_path(HANDLE hdl, wchar_t **target_path)
1483{
1484 int buf_size, result_length;
1485 wchar_t *buf;
1486
1487 /* We have a good handle to the target, use it to determine
1488 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001489 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1490 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001491 if(!buf_size)
1492 return FALSE;
1493
Victor Stinnerc36674a2016-03-16 14:30:16 +01001494 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001495 if (!buf) {
1496 SetLastError(ERROR_OUTOFMEMORY);
1497 return FALSE;
1498 }
1499
Steve Dower2ea51c92015-03-20 21:49:12 -07001500 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001501 buf, buf_size, VOLUME_NAME_DOS);
1502
1503 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001504 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001505 return FALSE;
1506 }
1507
1508 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001509 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001510 return FALSE;
1511 }
1512
1513 buf[result_length] = 0;
1514
1515 *target_path = buf;
1516 return TRUE;
1517}
1518
1519static int
Steve Dowercc16be82016-09-08 10:35:16 -07001520win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001521 BOOL traverse)
1522{
Victor Stinner26de69d2011-06-17 15:15:38 +02001523 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001524 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001525 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001527 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001528 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529
Steve Dowercc16be82016-09-08 10:35:16 -07001530 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001531 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001532 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 0, /* share mode */
1534 NULL, /* security attributes */
1535 OPEN_EXISTING,
1536 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001537 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1538 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001539 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001540 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1541 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001542 NULL);
1543
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 /* Either the target doesn't exist, or we don't have access to
1546 get a handle to it. If the former, we need to return an error.
1547 If the latter, we can use attributes_from_dir. */
1548 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001549 return -1;
1550 /* Could not get attributes on open file. Fall back to
1551 reading the directory. */
1552 if (!attributes_from_dir(path, &info, &reparse_tag))
1553 /* Very strange. This should not fail now */
1554 return -1;
1555 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1556 if (traverse) {
1557 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001559 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001562 } else {
1563 if (!GetFileInformationByHandle(hFile, &info)) {
1564 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001565 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001566 }
1567 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001568 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1569 return -1;
1570
1571 /* Close the outer open file handle now that we're about to
1572 reopen it with different flags. */
1573 if (!CloseHandle(hFile))
1574 return -1;
1575
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001576 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001577 /* In order to call GetFinalPathNameByHandle we need to open
1578 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001579 hFile2 = CreateFileW(
1580 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1581 NULL, OPEN_EXISTING,
1582 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1583 NULL);
1584 if (hFile2 == INVALID_HANDLE_VALUE)
1585 return -1;
1586
1587 if (!get_target_path(hFile2, &target_path))
1588 return -1;
1589
Steve Dowercc16be82016-09-08 10:35:16 -07001590 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001591 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 return code;
1593 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001594 } else
1595 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001596 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001597 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001598
1599 /* Set S_IEXEC if it is an .exe, .bat, ... */
1600 dot = wcsrchr(path, '.');
1601 if (dot) {
1602 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1603 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1604 result->st_mode |= 0111;
1605 }
1606 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607}
1608
1609static int
Steve Dowercc16be82016-09-08 10:35:16 -07001610win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001611{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001612 /* Protocol violation: we explicitly clear errno, instead of
1613 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001614 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001615 errno = 0;
1616 return code;
1617}
Brian Curtind25aef52011-06-13 15:16:04 -05001618/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001619
1620 In Posix, stat automatically traverses symlinks and returns the stat
1621 structure for the target. In Windows, the equivalent GetFileAttributes by
1622 default does not traverse symlinks and instead returns attributes for
1623 the symlink.
1624
1625 Therefore, win32_lstat will get the attributes traditionally, and
1626 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001627 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001628
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001629static int
Steve Dowercc16be82016-09-08 10:35:16 -07001630win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001631{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001632 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001633}
1634
Victor Stinner8c62be82010-05-06 00:08:46 +00001635static int
Steve Dowercc16be82016-09-08 10:35:16 -07001636win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001637{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001638 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001639}
1640
Martin v. Löwis14694662006-02-03 12:54:16 +00001641#endif /* MS_WINDOWS */
1642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001643PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001644"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001645This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001646 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001647or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1648\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001649Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1650or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001651\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001652See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001653
1654static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001655 {"st_mode", "protection bits"},
1656 {"st_ino", "inode"},
1657 {"st_dev", "device"},
1658 {"st_nlink", "number of hard links"},
1659 {"st_uid", "user ID of owner"},
1660 {"st_gid", "group ID of owner"},
1661 {"st_size", "total size, in bytes"},
1662 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1663 {NULL, "integer time of last access"},
1664 {NULL, "integer time of last modification"},
1665 {NULL, "integer time of last change"},
1666 {"st_atime", "time of last access"},
1667 {"st_mtime", "time of last modification"},
1668 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001669 {"st_atime_ns", "time of last access in nanoseconds"},
1670 {"st_mtime_ns", "time of last modification in nanoseconds"},
1671 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001672#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001673 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001674#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001675#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001677#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001678#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001679 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001680#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001681#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001683#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001684#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001686#endif
1687#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001689#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001690#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1691 {"st_file_attributes", "Windows file attribute bits"},
1692#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001693 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001694};
1695
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001696#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001697#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001698#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001699#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001700#endif
1701
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001702#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001703#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1704#else
1705#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1706#endif
1707
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001708#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001709#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1710#else
1711#define ST_RDEV_IDX ST_BLOCKS_IDX
1712#endif
1713
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001714#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1715#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1716#else
1717#define ST_FLAGS_IDX ST_RDEV_IDX
1718#endif
1719
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001720#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001721#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001722#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001723#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001724#endif
1725
1726#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1727#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1728#else
1729#define ST_BIRTHTIME_IDX ST_GEN_IDX
1730#endif
1731
Zachary Ware63f277b2014-06-19 09:46:37 -05001732#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1733#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1734#else
1735#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1736#endif
1737
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001738static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 "stat_result", /* name */
1740 stat_result__doc__, /* doc */
1741 stat_result_fields,
1742 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001743};
1744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001746"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1747This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001748 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001749or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001752
1753static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 {"f_bsize", },
1755 {"f_frsize", },
1756 {"f_blocks", },
1757 {"f_bfree", },
1758 {"f_bavail", },
1759 {"f_files", },
1760 {"f_ffree", },
1761 {"f_favail", },
1762 {"f_flag", },
1763 {"f_namemax",},
1764 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765};
1766
1767static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 "statvfs_result", /* name */
1769 statvfs_result__doc__, /* doc */
1770 statvfs_result_fields,
1771 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001772};
1773
Ross Lagerwall7807c352011-03-17 20:20:30 +02001774#if defined(HAVE_WAITID) && !defined(__APPLE__)
1775PyDoc_STRVAR(waitid_result__doc__,
1776"waitid_result: Result from waitid.\n\n\
1777This object may be accessed either as a tuple of\n\
1778 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1779or via the attributes si_pid, si_uid, and so on.\n\
1780\n\
1781See os.waitid for more information.");
1782
1783static PyStructSequence_Field waitid_result_fields[] = {
1784 {"si_pid", },
1785 {"si_uid", },
1786 {"si_signo", },
1787 {"si_status", },
1788 {"si_code", },
1789 {0}
1790};
1791
1792static PyStructSequence_Desc waitid_result_desc = {
1793 "waitid_result", /* name */
1794 waitid_result__doc__, /* doc */
1795 waitid_result_fields,
1796 5
1797};
1798static PyTypeObject WaitidResultType;
1799#endif
1800
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001801static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802static PyTypeObject StatResultType;
1803static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001804#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001805static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001806#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001807static newfunc structseq_new;
1808
1809static PyObject *
1810statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1811{
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 PyStructSequence *result;
1813 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001814
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 result = (PyStructSequence*)structseq_new(type, args, kwds);
1816 if (!result)
1817 return NULL;
1818 /* If we have been initialized from a tuple,
1819 st_?time might be set to None. Initialize it
1820 from the int slots. */
1821 for (i = 7; i <= 9; i++) {
1822 if (result->ob_item[i+3] == Py_None) {
1823 Py_DECREF(Py_None);
1824 Py_INCREF(result->ob_item[i]);
1825 result->ob_item[i+3] = result->ob_item[i];
1826 }
1827 }
1828 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001829}
1830
1831
1832
1833/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001834static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001835
1836PyDoc_STRVAR(stat_float_times__doc__,
1837"stat_float_times([newval]) -> oldval\n\n\
1838Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001839\n\
1840If value is True, future calls to stat() return floats; if it is False,\n\
1841future calls return ints.\n\
1842If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001843
Larry Hastings2f936352014-08-05 14:04:04 +10001844/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001845static PyObject*
1846stat_float_times(PyObject* self, PyObject *args)
1847{
Victor Stinner8c62be82010-05-06 00:08:46 +00001848 int newval = -1;
1849 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1850 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001851 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1852 "stat_float_times() is deprecated",
1853 1))
1854 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 if (newval == -1)
1856 /* Return old value */
1857 return PyBool_FromLong(_stat_float_times);
1858 _stat_float_times = newval;
1859 Py_INCREF(Py_None);
1860 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001861}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001862
Larry Hastings6fe20b32012-04-19 15:07:49 -07001863static PyObject *billion = NULL;
1864
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001865static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001866fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001867{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001868 PyObject *s = _PyLong_FromTime_t(sec);
1869 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1870 PyObject *s_in_ns = NULL;
1871 PyObject *ns_total = NULL;
1872 PyObject *float_s = NULL;
1873
1874 if (!(s && ns_fractional))
1875 goto exit;
1876
1877 s_in_ns = PyNumber_Multiply(s, billion);
1878 if (!s_in_ns)
1879 goto exit;
1880
1881 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1882 if (!ns_total)
1883 goto exit;
1884
Victor Stinner4195b5c2012-02-08 23:03:19 +01001885 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001886 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1887 if (!float_s)
1888 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001890 else {
1891 float_s = s;
1892 Py_INCREF(float_s);
1893 }
1894
1895 PyStructSequence_SET_ITEM(v, index, s);
1896 PyStructSequence_SET_ITEM(v, index+3, float_s);
1897 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1898 s = NULL;
1899 float_s = NULL;
1900 ns_total = NULL;
1901exit:
1902 Py_XDECREF(s);
1903 Py_XDECREF(ns_fractional);
1904 Py_XDECREF(s_in_ns);
1905 Py_XDECREF(ns_total);
1906 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001907}
1908
Tim Peters5aa91602002-01-30 05:46:57 +00001909/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001910 (used by posix_stat() and posix_fstat()) */
1911static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001912_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001913{
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 unsigned long ansec, mnsec, cnsec;
1915 PyObject *v = PyStructSequence_New(&StatResultType);
1916 if (v == NULL)
1917 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001918
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001920#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001922 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001923#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001925#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001926#ifdef MS_WINDOWS
1927 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001928#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001929 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001930#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001932#if defined(MS_WINDOWS)
1933 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1934 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1935#else
1936 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1937 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1938#endif
Fred Drake699f3522000-06-29 21:12:41 +00001939#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001941 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001942#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001944#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001945
Martin v. Löwis14694662006-02-03 12:54:16 +00001946#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 ansec = st->st_atim.tv_nsec;
1948 mnsec = st->st_mtim.tv_nsec;
1949 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001950#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 ansec = st->st_atimespec.tv_nsec;
1952 mnsec = st->st_mtimespec.tv_nsec;
1953 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001954#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 ansec = st->st_atime_nsec;
1956 mnsec = st->st_mtime_nsec;
1957 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001958#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001960#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001961 fill_time(v, 7, st->st_atime, ansec);
1962 fill_time(v, 8, st->st_mtime, mnsec);
1963 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001965#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1967 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001968#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001969#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1971 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1975 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001976#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001977#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1979 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001980#endif
1981#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001983 PyObject *val;
1984 unsigned long bsec,bnsec;
1985 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001986#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001987 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001988#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001989 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001990#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001991 if (_stat_float_times) {
1992 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1993 } else {
1994 val = PyLong_FromLong((long)bsec);
1995 }
1996 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1997 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001999#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002000#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2002 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002003#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002004#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2005 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2006 PyLong_FromUnsignedLong(st->st_file_attributes));
2007#endif
Fred Drake699f3522000-06-29 21:12:41 +00002008
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 if (PyErr_Occurred()) {
2010 Py_DECREF(v);
2011 return NULL;
2012 }
Fred Drake699f3522000-06-29 21:12:41 +00002013
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002015}
2016
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002017/* POSIX methods */
2018
Guido van Rossum94f6f721999-01-06 18:42:14 +00002019
2020static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002021posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002022 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002023{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002024 STRUCT_STAT st;
2025 int result;
2026
2027#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2028 if (follow_symlinks_specified(function_name, follow_symlinks))
2029 return NULL;
2030#endif
2031
2032 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2033 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2034 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2035 return NULL;
2036
2037 Py_BEGIN_ALLOW_THREADS
2038 if (path->fd != -1)
2039 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002040#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002041 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002042 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002043 else
Steve Dowercc16be82016-09-08 10:35:16 -07002044 result = win32_lstat(path->wide, &st);
2045#else
2046 else
2047#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002048 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2049 result = LSTAT(path->narrow, &st);
2050 else
Steve Dowercc16be82016-09-08 10:35:16 -07002051#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002052#ifdef HAVE_FSTATAT
2053 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2054 result = fstatat(dir_fd, path->narrow, &st,
2055 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2056 else
Steve Dowercc16be82016-09-08 10:35:16 -07002057#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002058 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002059#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002060 Py_END_ALLOW_THREADS
2061
Victor Stinner292c8352012-10-30 02:17:38 +01002062 if (result != 0) {
2063 return path_error(path);
2064 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002065
2066 return _pystat_fromstructstat(&st);
2067}
2068
Larry Hastings2f936352014-08-05 14:04:04 +10002069/*[python input]
2070
2071for s in """
2072
2073FACCESSAT
2074FCHMODAT
2075FCHOWNAT
2076FSTATAT
2077LINKAT
2078MKDIRAT
2079MKFIFOAT
2080MKNODAT
2081OPENAT
2082READLINKAT
2083SYMLINKAT
2084UNLINKAT
2085
2086""".strip().split():
2087 s = s.strip()
2088 print("""
2089#ifdef HAVE_{s}
2090 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002091#else
Larry Hastings2f936352014-08-05 14:04:04 +10002092 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002093#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002094""".rstrip().format(s=s))
2095
2096for s in """
2097
2098FCHDIR
2099FCHMOD
2100FCHOWN
2101FDOPENDIR
2102FEXECVE
2103FPATHCONF
2104FSTATVFS
2105FTRUNCATE
2106
2107""".strip().split():
2108 s = s.strip()
2109 print("""
2110#ifdef HAVE_{s}
2111 #define PATH_HAVE_{s} 1
2112#else
2113 #define PATH_HAVE_{s} 0
2114#endif
2115
2116""".rstrip().format(s=s))
2117[python start generated code]*/
2118
2119#ifdef HAVE_FACCESSAT
2120 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2121#else
2122 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2123#endif
2124
2125#ifdef HAVE_FCHMODAT
2126 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2127#else
2128 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2129#endif
2130
2131#ifdef HAVE_FCHOWNAT
2132 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2133#else
2134 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2135#endif
2136
2137#ifdef HAVE_FSTATAT
2138 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2139#else
2140 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2141#endif
2142
2143#ifdef HAVE_LINKAT
2144 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2145#else
2146 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2147#endif
2148
2149#ifdef HAVE_MKDIRAT
2150 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2151#else
2152 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2153#endif
2154
2155#ifdef HAVE_MKFIFOAT
2156 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2157#else
2158 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2159#endif
2160
2161#ifdef HAVE_MKNODAT
2162 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2163#else
2164 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2165#endif
2166
2167#ifdef HAVE_OPENAT
2168 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2169#else
2170 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2171#endif
2172
2173#ifdef HAVE_READLINKAT
2174 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2175#else
2176 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2177#endif
2178
2179#ifdef HAVE_SYMLINKAT
2180 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2181#else
2182 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2183#endif
2184
2185#ifdef HAVE_UNLINKAT
2186 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2187#else
2188 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2189#endif
2190
2191#ifdef HAVE_FCHDIR
2192 #define PATH_HAVE_FCHDIR 1
2193#else
2194 #define PATH_HAVE_FCHDIR 0
2195#endif
2196
2197#ifdef HAVE_FCHMOD
2198 #define PATH_HAVE_FCHMOD 1
2199#else
2200 #define PATH_HAVE_FCHMOD 0
2201#endif
2202
2203#ifdef HAVE_FCHOWN
2204 #define PATH_HAVE_FCHOWN 1
2205#else
2206 #define PATH_HAVE_FCHOWN 0
2207#endif
2208
2209#ifdef HAVE_FDOPENDIR
2210 #define PATH_HAVE_FDOPENDIR 1
2211#else
2212 #define PATH_HAVE_FDOPENDIR 0
2213#endif
2214
2215#ifdef HAVE_FEXECVE
2216 #define PATH_HAVE_FEXECVE 1
2217#else
2218 #define PATH_HAVE_FEXECVE 0
2219#endif
2220
2221#ifdef HAVE_FPATHCONF
2222 #define PATH_HAVE_FPATHCONF 1
2223#else
2224 #define PATH_HAVE_FPATHCONF 0
2225#endif
2226
2227#ifdef HAVE_FSTATVFS
2228 #define PATH_HAVE_FSTATVFS 1
2229#else
2230 #define PATH_HAVE_FSTATVFS 0
2231#endif
2232
2233#ifdef HAVE_FTRUNCATE
2234 #define PATH_HAVE_FTRUNCATE 1
2235#else
2236 #define PATH_HAVE_FTRUNCATE 0
2237#endif
2238/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002239
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002240#ifdef MS_WINDOWS
2241 #undef PATH_HAVE_FTRUNCATE
2242 #define PATH_HAVE_FTRUNCATE 1
2243#endif
Larry Hastings31826802013-10-19 00:09:25 -07002244
Larry Hastings61272b72014-01-07 12:41:53 -08002245/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002246
2247class path_t_converter(CConverter):
2248
2249 type = "path_t"
2250 impl_by_reference = True
2251 parse_by_reference = True
2252
2253 converter = 'path_converter'
2254
2255 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002256 # right now path_t doesn't support default values.
2257 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002258 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002259 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002260
Larry Hastings2f936352014-08-05 14:04:04 +10002261 if self.c_default not in (None, 'Py_None'):
2262 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002263
2264 self.nullable = nullable
2265 self.allow_fd = allow_fd
2266
Larry Hastings7726ac92014-01-31 22:03:12 -08002267 def pre_render(self):
2268 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002269 if isinstance(value, str):
2270 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002271 return str(int(bool(value)))
2272
2273 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002274 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002275 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002276 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002277 strify(self.nullable),
2278 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002279 )
2280
2281 def cleanup(self):
2282 return "path_cleanup(&" + self.name + ");\n"
2283
2284
2285class dir_fd_converter(CConverter):
2286 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002287
Larry Hastings2f936352014-08-05 14:04:04 +10002288 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002289 if self.default in (unspecified, None):
2290 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002291 if isinstance(requires, str):
2292 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2293 else:
2294 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002295
Larry Hastings2f936352014-08-05 14:04:04 +10002296class fildes_converter(CConverter):
2297 type = 'int'
2298 converter = 'fildes_converter'
2299
2300class uid_t_converter(CConverter):
2301 type = "uid_t"
2302 converter = '_Py_Uid_Converter'
2303
2304class gid_t_converter(CConverter):
2305 type = "gid_t"
2306 converter = '_Py_Gid_Converter'
2307
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002308class dev_t_converter(CConverter):
2309 type = 'dev_t'
2310 converter = '_Py_Dev_Converter'
2311
2312class dev_t_return_converter(unsigned_long_return_converter):
2313 type = 'dev_t'
2314 conversion_fn = '_PyLong_FromDev'
2315 unsigned_cast = '(dev_t)'
2316
Larry Hastings2f936352014-08-05 14:04:04 +10002317class FSConverter_converter(CConverter):
2318 type = 'PyObject *'
2319 converter = 'PyUnicode_FSConverter'
2320 def converter_init(self):
2321 if self.default is not unspecified:
2322 fail("FSConverter_converter does not support default values")
2323 self.c_default = 'NULL'
2324
2325 def cleanup(self):
2326 return "Py_XDECREF(" + self.name + ");\n"
2327
2328class pid_t_converter(CConverter):
2329 type = 'pid_t'
2330 format_unit = '" _Py_PARSE_PID "'
2331
2332class idtype_t_converter(int_converter):
2333 type = 'idtype_t'
2334
2335class id_t_converter(CConverter):
2336 type = 'id_t'
2337 format_unit = '" _Py_PARSE_PID "'
2338
Benjamin Petersonca470632016-09-06 13:47:26 -07002339class intptr_t_converter(CConverter):
2340 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002341 format_unit = '" _Py_PARSE_INTPTR "'
2342
2343class Py_off_t_converter(CConverter):
2344 type = 'Py_off_t'
2345 converter = 'Py_off_t_converter'
2346
2347class Py_off_t_return_converter(long_return_converter):
2348 type = 'Py_off_t'
2349 conversion_fn = 'PyLong_FromPy_off_t'
2350
2351class path_confname_converter(CConverter):
2352 type="int"
2353 converter="conv_path_confname"
2354
2355class confstr_confname_converter(path_confname_converter):
2356 converter='conv_confstr_confname'
2357
2358class sysconf_confname_converter(path_confname_converter):
2359 converter="conv_sysconf_confname"
2360
2361class sched_param_converter(CConverter):
2362 type = 'struct sched_param'
2363 converter = 'convert_sched_param'
2364 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002365
Larry Hastings61272b72014-01-07 12:41:53 -08002366[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002367/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002368
Larry Hastings61272b72014-01-07 12:41:53 -08002369/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002370
Larry Hastings2a727912014-01-16 11:32:01 -08002371os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002372
2373 path : path_t(allow_fd=True)
2374 Path to be examined; can be string, bytes, or open-file-descriptor int.
2375
2376 *
2377
Larry Hastings2f936352014-08-05 14:04:04 +10002378 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002379 If not None, it should be a file descriptor open to a directory,
2380 and path should be a relative string; path will then be relative to
2381 that directory.
2382
2383 follow_symlinks: bool = True
2384 If False, and the last element of the path is a symbolic link,
2385 stat will examine the symbolic link itself instead of the file
2386 the link points to.
2387
2388Perform a stat system call on the given path.
2389
2390dir_fd and follow_symlinks may not be implemented
2391 on your platform. If they are unavailable, using them will raise a
2392 NotImplementedError.
2393
2394It's an error to use dir_fd or follow_symlinks when specifying path as
2395 an open file descriptor.
2396
Larry Hastings61272b72014-01-07 12:41:53 -08002397[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002398
Larry Hastings31826802013-10-19 00:09:25 -07002399static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002400os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2401/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002402{
2403 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2404}
2405
Larry Hastings2f936352014-08-05 14:04:04 +10002406
2407/*[clinic input]
2408os.lstat
2409
2410 path : path_t
2411
2412 *
2413
2414 dir_fd : dir_fd(requires='fstatat') = None
2415
2416Perform a stat system call on the given path, without following symbolic links.
2417
2418Like stat(), but do not follow symbolic links.
2419Equivalent to stat(path, follow_symlinks=False).
2420[clinic start generated code]*/
2421
Larry Hastings2f936352014-08-05 14:04:04 +10002422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002423os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2424/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002425{
2426 int follow_symlinks = 0;
2427 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2428}
Larry Hastings31826802013-10-19 00:09:25 -07002429
Larry Hastings2f936352014-08-05 14:04:04 +10002430
Larry Hastings61272b72014-01-07 12:41:53 -08002431/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002432os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002433
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002434 path: path_t
2435 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002436
2437 mode: int
2438 Operating-system mode bitfield. Can be F_OK to test existence,
2439 or the inclusive-OR of R_OK, W_OK, and X_OK.
2440
2441 *
2442
Larry Hastings2f936352014-08-05 14:04:04 +10002443 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002444 If not None, it should be a file descriptor open to a directory,
2445 and path should be relative; path will then be relative to that
2446 directory.
2447
2448 effective_ids: bool = False
2449 If True, access will use the effective uid/gid instead of
2450 the real uid/gid.
2451
2452 follow_symlinks: bool = True
2453 If False, and the last element of the path is a symbolic link,
2454 access will examine the symbolic link itself instead of the file
2455 the link points to.
2456
2457Use the real uid/gid to test for access to a path.
2458
2459{parameters}
2460dir_fd, effective_ids, and follow_symlinks may not be implemented
2461 on your platform. If they are unavailable, using them will raise a
2462 NotImplementedError.
2463
2464Note that most operations will use the effective uid/gid, therefore this
2465 routine can be used in a suid/sgid environment to test if the invoking user
2466 has the specified access to the path.
2467
Larry Hastings61272b72014-01-07 12:41:53 -08002468[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002469
Larry Hastings2f936352014-08-05 14:04:04 +10002470static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002471os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002472 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002473/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002474{
Larry Hastings2f936352014-08-05 14:04:04 +10002475 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002476
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002477#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002478 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002479#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002480 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002481#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002482
Larry Hastings9cf065c2012-06-22 16:30:09 -07002483#ifndef HAVE_FACCESSAT
2484 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002485 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002486
2487 if (effective_ids) {
2488 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002489 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002490 }
2491#endif
2492
2493#ifdef MS_WINDOWS
2494 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002495 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002496 Py_END_ALLOW_THREADS
2497
2498 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002499 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500 * * we didn't get a -1, and
2501 * * write access wasn't requested,
2502 * * or the file isn't read-only,
2503 * * or it's a directory.
2504 * (Directories cannot be read-only on Windows.)
2505 */
Larry Hastings2f936352014-08-05 14:04:04 +10002506 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002507 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002509 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510#else
2511
2512 Py_BEGIN_ALLOW_THREADS
2513#ifdef HAVE_FACCESSAT
2514 if ((dir_fd != DEFAULT_DIR_FD) ||
2515 effective_ids ||
2516 !follow_symlinks) {
2517 int flags = 0;
2518 if (!follow_symlinks)
2519 flags |= AT_SYMLINK_NOFOLLOW;
2520 if (effective_ids)
2521 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002522 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523 }
2524 else
2525#endif
Larry Hastings31826802013-10-19 00:09:25 -07002526 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002528 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002529#endif
2530
Larry Hastings9cf065c2012-06-22 16:30:09 -07002531 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002532}
2533
Guido van Rossumd371ff11999-01-25 16:12:23 +00002534#ifndef F_OK
2535#define F_OK 0
2536#endif
2537#ifndef R_OK
2538#define R_OK 4
2539#endif
2540#ifndef W_OK
2541#define W_OK 2
2542#endif
2543#ifndef X_OK
2544#define X_OK 1
2545#endif
2546
Larry Hastings31826802013-10-19 00:09:25 -07002547
Guido van Rossumd371ff11999-01-25 16:12:23 +00002548#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002549/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002550os.ttyname -> DecodeFSDefault
2551
2552 fd: int
2553 Integer file descriptor handle.
2554
2555 /
2556
2557Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002558[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559
Larry Hastings31826802013-10-19 00:09:25 -07002560static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002561os_ttyname_impl(PyObject *module, int fd)
2562/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002563{
2564 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002565
Larry Hastings31826802013-10-19 00:09:25 -07002566 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002567 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002568 posix_error();
2569 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002570}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002571#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002572
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002573#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002574/*[clinic input]
2575os.ctermid
2576
2577Return the name of the controlling terminal for this process.
2578[clinic start generated code]*/
2579
Larry Hastings2f936352014-08-05 14:04:04 +10002580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002581os_ctermid_impl(PyObject *module)
2582/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002583{
Victor Stinner8c62be82010-05-06 00:08:46 +00002584 char *ret;
2585 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002586
Greg Wardb48bc172000-03-01 21:51:56 +00002587#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002589#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002590 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002591#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 if (ret == NULL)
2593 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002594 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002595}
Larry Hastings2f936352014-08-05 14:04:04 +10002596#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002597
Larry Hastings2f936352014-08-05 14:04:04 +10002598
2599/*[clinic input]
2600os.chdir
2601
2602 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2603
2604Change the current working directory to the specified path.
2605
2606path may always be specified as a string.
2607On some platforms, path may also be specified as an open file descriptor.
2608 If this functionality is unavailable, using it raises an exception.
2609[clinic start generated code]*/
2610
Larry Hastings2f936352014-08-05 14:04:04 +10002611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002612os_chdir_impl(PyObject *module, path_t *path)
2613/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002614{
2615 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002616
2617 Py_BEGIN_ALLOW_THREADS
2618#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002619 /* on unix, success = 0, on windows, success = !0 */
2620 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621#else
2622#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002623 if (path->fd != -1)
2624 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002625 else
2626#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002627 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628#endif
2629 Py_END_ALLOW_THREADS
2630
2631 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002632 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633 }
2634
Larry Hastings2f936352014-08-05 14:04:04 +10002635 Py_RETURN_NONE;
2636}
2637
2638
2639#ifdef HAVE_FCHDIR
2640/*[clinic input]
2641os.fchdir
2642
2643 fd: fildes
2644
2645Change to the directory of the given file descriptor.
2646
2647fd must be opened on a directory, not a file.
2648Equivalent to os.chdir(fd).
2649
2650[clinic start generated code]*/
2651
Fred Drake4d1e64b2002-04-15 19:40:07 +00002652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002653os_fchdir_impl(PyObject *module, int fd)
2654/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002655{
Larry Hastings2f936352014-08-05 14:04:04 +10002656 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002657}
2658#endif /* HAVE_FCHDIR */
2659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002660
Larry Hastings2f936352014-08-05 14:04:04 +10002661/*[clinic input]
2662os.chmod
2663
2664 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2665 Path to be modified. May always be specified as a str or bytes.
2666 On some platforms, path may also be specified as an open file descriptor.
2667 If this functionality is unavailable, using it raises an exception.
2668
2669 mode: int
2670 Operating-system mode bitfield.
2671
2672 *
2673
2674 dir_fd : dir_fd(requires='fchmodat') = None
2675 If not None, it should be a file descriptor open to a directory,
2676 and path should be relative; path will then be relative to that
2677 directory.
2678
2679 follow_symlinks: bool = True
2680 If False, and the last element of the path is a symbolic link,
2681 chmod will modify the symbolic link itself instead of the file
2682 the link points to.
2683
2684Change the access permissions of a file.
2685
2686It is an error to use dir_fd or follow_symlinks when specifying path as
2687 an open file descriptor.
2688dir_fd and follow_symlinks may not be implemented on your platform.
2689 If they are unavailable, using them will raise a NotImplementedError.
2690
2691[clinic start generated code]*/
2692
Larry Hastings2f936352014-08-05 14:04:04 +10002693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002694os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002695 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002696/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002697{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002698 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002699
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002700#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002701 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002703
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704#ifdef HAVE_FCHMODAT
2705 int fchmodat_nofollow_unsupported = 0;
2706#endif
2707
Larry Hastings9cf065c2012-06-22 16:30:09 -07002708#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2709 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002710 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711#endif
2712
2713#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002714 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002715 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002716 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717 result = 0;
2718 else {
2719 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002720 attr &= ~FILE_ATTRIBUTE_READONLY;
2721 else
2722 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002723 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724 }
2725 Py_END_ALLOW_THREADS
2726
2727 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002728 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 }
2730#else /* MS_WINDOWS */
2731 Py_BEGIN_ALLOW_THREADS
2732#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002733 if (path->fd != -1)
2734 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735 else
2736#endif
2737#ifdef HAVE_LCHMOD
2738 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002739 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740 else
2741#endif
2742#ifdef HAVE_FCHMODAT
2743 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2744 /*
2745 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2746 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002747 * and then says it isn't implemented yet.
2748 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002749 *
2750 * Once it is supported, os.chmod will automatically
2751 * support dir_fd and follow_symlinks=False. (Hopefully.)
2752 * Until then, we need to be careful what exception we raise.
2753 */
Larry Hastings2f936352014-08-05 14:04:04 +10002754 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2756 /*
2757 * But wait! We can't throw the exception without allowing threads,
2758 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2759 */
2760 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002761 result &&
2762 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2763 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002764 }
2765 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002766#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002767 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768 Py_END_ALLOW_THREADS
2769
2770 if (result) {
2771#ifdef HAVE_FCHMODAT
2772 if (fchmodat_nofollow_unsupported) {
2773 if (dir_fd != DEFAULT_DIR_FD)
2774 dir_fd_and_follow_symlinks_invalid("chmod",
2775 dir_fd, follow_symlinks);
2776 else
2777 follow_symlinks_specified("chmod", follow_symlinks);
2778 }
2779 else
2780#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002781 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782 }
2783#endif
2784
Larry Hastings2f936352014-08-05 14:04:04 +10002785 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002786}
2787
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788
Christian Heimes4e30a842007-11-30 22:12:06 +00002789#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002790/*[clinic input]
2791os.fchmod
2792
2793 fd: int
2794 mode: int
2795
2796Change the access permissions of the file given by file descriptor fd.
2797
2798Equivalent to os.chmod(fd, mode).
2799[clinic start generated code]*/
2800
Larry Hastings2f936352014-08-05 14:04:04 +10002801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002802os_fchmod_impl(PyObject *module, int fd, int mode)
2803/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002804{
2805 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002806 int async_err = 0;
2807
2808 do {
2809 Py_BEGIN_ALLOW_THREADS
2810 res = fchmod(fd, mode);
2811 Py_END_ALLOW_THREADS
2812 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2813 if (res != 0)
2814 return (!async_err) ? posix_error() : NULL;
2815
Victor Stinner8c62be82010-05-06 00:08:46 +00002816 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002817}
2818#endif /* HAVE_FCHMOD */
2819
Larry Hastings2f936352014-08-05 14:04:04 +10002820
Christian Heimes4e30a842007-11-30 22:12:06 +00002821#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002822/*[clinic input]
2823os.lchmod
2824
2825 path: path_t
2826 mode: int
2827
2828Change the access permissions of a file, without following symbolic links.
2829
2830If path is a symlink, this affects the link itself rather than the target.
2831Equivalent to chmod(path, mode, follow_symlinks=False)."
2832[clinic start generated code]*/
2833
Larry Hastings2f936352014-08-05 14:04:04 +10002834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002835os_lchmod_impl(PyObject *module, path_t *path, int mode)
2836/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002837{
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002840 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002842 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002843 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002844 return NULL;
2845 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002847}
2848#endif /* HAVE_LCHMOD */
2849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002850
Thomas Wouterscf297e42007-02-23 15:07:44 +00002851#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002852/*[clinic input]
2853os.chflags
2854
2855 path: path_t
2856 flags: unsigned_long(bitwise=True)
2857 follow_symlinks: bool=True
2858
2859Set file flags.
2860
2861If follow_symlinks is False, and the last element of the path is a symbolic
2862 link, chflags will change flags on the symbolic link itself instead of the
2863 file the link points to.
2864follow_symlinks may not be implemented on your platform. If it is
2865unavailable, using it will raise a NotImplementedError.
2866
2867[clinic start generated code]*/
2868
Larry Hastings2f936352014-08-05 14:04:04 +10002869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002870os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002871 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002872/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002873{
2874 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002875
2876#ifndef HAVE_LCHFLAGS
2877 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002878 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879#endif
2880
Victor Stinner8c62be82010-05-06 00:08:46 +00002881 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882#ifdef HAVE_LCHFLAGS
2883 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002884 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885 else
2886#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002887 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002889
Larry Hastings2f936352014-08-05 14:04:04 +10002890 if (result)
2891 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892
Larry Hastings2f936352014-08-05 14:04:04 +10002893 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002894}
2895#endif /* HAVE_CHFLAGS */
2896
Larry Hastings2f936352014-08-05 14:04:04 +10002897
Thomas Wouterscf297e42007-02-23 15:07:44 +00002898#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002899/*[clinic input]
2900os.lchflags
2901
2902 path: path_t
2903 flags: unsigned_long(bitwise=True)
2904
2905Set file flags.
2906
2907This function will not follow symbolic links.
2908Equivalent to chflags(path, flags, follow_symlinks=False).
2909[clinic start generated code]*/
2910
Larry Hastings2f936352014-08-05 14:04:04 +10002911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002912os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2913/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002914{
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002917 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002919 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002920 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002921 }
Victor Stinner292c8352012-10-30 02:17:38 +01002922 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002923}
2924#endif /* HAVE_LCHFLAGS */
2925
Larry Hastings2f936352014-08-05 14:04:04 +10002926
Martin v. Löwis244edc82001-10-04 22:44:26 +00002927#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002928/*[clinic input]
2929os.chroot
2930 path: path_t
2931
2932Change root directory to path.
2933
2934[clinic start generated code]*/
2935
Larry Hastings2f936352014-08-05 14:04:04 +10002936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937os_chroot_impl(PyObject *module, path_t *path)
2938/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002939{
2940 int res;
2941 Py_BEGIN_ALLOW_THREADS
2942 res = chroot(path->narrow);
2943 Py_END_ALLOW_THREADS
2944 if (res < 0)
2945 return path_error(path);
2946 Py_RETURN_NONE;
2947}
2948#endif /* HAVE_CHROOT */
2949
Martin v. Löwis244edc82001-10-04 22:44:26 +00002950
Guido van Rossum21142a01999-01-08 21:05:37 +00002951#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002952/*[clinic input]
2953os.fsync
2954
2955 fd: fildes
2956
2957Force write of fd to disk.
2958[clinic start generated code]*/
2959
Larry Hastings2f936352014-08-05 14:04:04 +10002960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002961os_fsync_impl(PyObject *module, int fd)
2962/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002963{
2964 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002965}
2966#endif /* HAVE_FSYNC */
2967
Larry Hastings2f936352014-08-05 14:04:04 +10002968
Ross Lagerwall7807c352011-03-17 20:20:30 +02002969#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002970/*[clinic input]
2971os.sync
2972
2973Force write of everything to disk.
2974[clinic start generated code]*/
2975
Larry Hastings2f936352014-08-05 14:04:04 +10002976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002977os_sync_impl(PyObject *module)
2978/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002979{
2980 Py_BEGIN_ALLOW_THREADS
2981 sync();
2982 Py_END_ALLOW_THREADS
2983 Py_RETURN_NONE;
2984}
Larry Hastings2f936352014-08-05 14:04:04 +10002985#endif /* HAVE_SYNC */
2986
Ross Lagerwall7807c352011-03-17 20:20:30 +02002987
Guido van Rossum21142a01999-01-08 21:05:37 +00002988#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002989#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002990extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2991#endif
2992
Larry Hastings2f936352014-08-05 14:04:04 +10002993/*[clinic input]
2994os.fdatasync
2995
2996 fd: fildes
2997
2998Force write of fd to disk without forcing update of metadata.
2999[clinic start generated code]*/
3000
Larry Hastings2f936352014-08-05 14:04:04 +10003001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003002os_fdatasync_impl(PyObject *module, int fd)
3003/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003004{
3005 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003006}
3007#endif /* HAVE_FDATASYNC */
3008
3009
Fredrik Lundh10723342000-07-10 16:38:09 +00003010#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003011/*[clinic input]
3012os.chown
3013
3014 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3015 Path to be examined; can be string, bytes, or open-file-descriptor int.
3016
3017 uid: uid_t
3018
3019 gid: gid_t
3020
3021 *
3022
3023 dir_fd : dir_fd(requires='fchownat') = None
3024 If not None, it should be a file descriptor open to a directory,
3025 and path should be relative; path will then be relative to that
3026 directory.
3027
3028 follow_symlinks: bool = True
3029 If False, and the last element of the path is a symbolic link,
3030 stat will examine the symbolic link itself instead of the file
3031 the link points to.
3032
3033Change the owner and group id of path to the numeric uid and gid.\
3034
3035path may always be specified as a string.
3036On some platforms, path may also be specified as an open file descriptor.
3037 If this functionality is unavailable, using it raises an exception.
3038If dir_fd is not None, it should be a file descriptor open to a directory,
3039 and path should be relative; path will then be relative to that directory.
3040If follow_symlinks is False, and the last element of the path is a symbolic
3041 link, chown will modify the symbolic link itself instead of the file the
3042 link points to.
3043It is an error to use dir_fd or follow_symlinks when specifying path as
3044 an open file descriptor.
3045dir_fd and follow_symlinks may not be implemented on your platform.
3046 If they are unavailable, using them will raise a NotImplementedError.
3047
3048[clinic start generated code]*/
3049
Larry Hastings2f936352014-08-05 14:04:04 +10003050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003051os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003052 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003053/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003054{
3055 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056
3057#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3058 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003059 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003061 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3062 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3063 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003064
3065#ifdef __APPLE__
3066 /*
3067 * This is for Mac OS X 10.3, which doesn't have lchown.
3068 * (But we still have an lchown symbol because of weak-linking.)
3069 * It doesn't have fchownat either. So there's no possibility
3070 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003071 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 if ((!follow_symlinks) && (lchown == NULL)) {
3073 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003074 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003075 }
3076#endif
3077
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003079#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003080 if (path->fd != -1)
3081 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003082 else
3083#endif
3084#ifdef HAVE_LCHOWN
3085 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003086 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 else
3088#endif
3089#ifdef HAVE_FCHOWNAT
3090 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003091 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3093 else
3094#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003095 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003096 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097
Larry Hastings2f936352014-08-05 14:04:04 +10003098 if (result)
3099 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003100
Larry Hastings2f936352014-08-05 14:04:04 +10003101 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003102}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003103#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003104
Larry Hastings2f936352014-08-05 14:04:04 +10003105
Christian Heimes4e30a842007-11-30 22:12:06 +00003106#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003107/*[clinic input]
3108os.fchown
3109
3110 fd: int
3111 uid: uid_t
3112 gid: gid_t
3113
3114Change the owner and group id of the file specified by file descriptor.
3115
3116Equivalent to os.chown(fd, uid, gid).
3117
3118[clinic start generated code]*/
3119
Larry Hastings2f936352014-08-05 14:04:04 +10003120static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003121os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3122/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003123{
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003125 int async_err = 0;
3126
3127 do {
3128 Py_BEGIN_ALLOW_THREADS
3129 res = fchown(fd, uid, gid);
3130 Py_END_ALLOW_THREADS
3131 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3132 if (res != 0)
3133 return (!async_err) ? posix_error() : NULL;
3134
Victor Stinner8c62be82010-05-06 00:08:46 +00003135 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003136}
3137#endif /* HAVE_FCHOWN */
3138
Larry Hastings2f936352014-08-05 14:04:04 +10003139
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003140#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003141/*[clinic input]
3142os.lchown
3143
3144 path : path_t
3145 uid: uid_t
3146 gid: gid_t
3147
3148Change the owner and group id of path to the numeric uid and gid.
3149
3150This function will not follow symbolic links.
3151Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3152[clinic start generated code]*/
3153
Larry Hastings2f936352014-08-05 14:04:04 +10003154static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003155os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3156/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003157{
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003160 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003162 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003163 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003164 }
Larry Hastings2f936352014-08-05 14:04:04 +10003165 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003166}
3167#endif /* HAVE_LCHOWN */
3168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003169
Barry Warsaw53699e91996-12-10 23:23:01 +00003170static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003171posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003172{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003173 char *buf, *tmpbuf;
3174 char *cwd;
3175 const size_t chunk = 1024;
3176 size_t buflen = 0;
3177 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003178
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003179#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003181 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 wchar_t *wbuf2 = wbuf;
3183 PyObject *resobj;
3184 DWORD len;
3185 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003186 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 /* If the buffer is large enough, len does not include the
3188 terminating \0. If the buffer is too small, len includes
3189 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003190 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003191 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 if (wbuf2)
3193 len = GetCurrentDirectoryW(len, wbuf2);
3194 }
3195 Py_END_ALLOW_THREADS
3196 if (!wbuf2) {
3197 PyErr_NoMemory();
3198 return NULL;
3199 }
3200 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003201 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003202 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003203 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 }
3205 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003206 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003207 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 return resobj;
3209 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003210
3211 if (win32_warn_bytes_api())
3212 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003213#endif
3214
Victor Stinner4403d7d2015-04-25 00:16:10 +02003215 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003217 do {
3218 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003219#ifdef MS_WINDOWS
3220 if (buflen > INT_MAX) {
3221 PyErr_NoMemory();
3222 break;
3223 }
3224#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003225 tmpbuf = PyMem_RawRealloc(buf, buflen);
3226 if (tmpbuf == NULL)
3227 break;
3228
3229 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003230#ifdef MS_WINDOWS
3231 cwd = getcwd(buf, (int)buflen);
3232#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003233 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003234#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003235 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003237
3238 if (cwd == NULL) {
3239 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003241 }
3242
Victor Stinner8c62be82010-05-06 00:08:46 +00003243 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003244 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3245 else
3246 obj = PyUnicode_DecodeFSDefault(buf);
3247 PyMem_RawFree(buf);
3248
3249 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003250}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003251
Larry Hastings2f936352014-08-05 14:04:04 +10003252
3253/*[clinic input]
3254os.getcwd
3255
3256Return a unicode string representing the current working directory.
3257[clinic start generated code]*/
3258
Larry Hastings2f936352014-08-05 14:04:04 +10003259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003260os_getcwd_impl(PyObject *module)
3261/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003262{
3263 return posix_getcwd(0);
3264}
3265
Larry Hastings2f936352014-08-05 14:04:04 +10003266
3267/*[clinic input]
3268os.getcwdb
3269
3270Return a bytes string representing the current working directory.
3271[clinic start generated code]*/
3272
Larry Hastings2f936352014-08-05 14:04:04 +10003273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003274os_getcwdb_impl(PyObject *module)
3275/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003276{
3277 return posix_getcwd(1);
3278}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003279
Larry Hastings2f936352014-08-05 14:04:04 +10003280
Larry Hastings9cf065c2012-06-22 16:30:09 -07003281#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3282#define HAVE_LINK 1
3283#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Guido van Rossumb6775db1994-08-01 11:34:53 +00003285#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003286/*[clinic input]
3287
3288os.link
3289
3290 src : path_t
3291 dst : path_t
3292 *
3293 src_dir_fd : dir_fd = None
3294 dst_dir_fd : dir_fd = None
3295 follow_symlinks: bool = True
3296
3297Create a hard link to a file.
3298
3299If either src_dir_fd or dst_dir_fd is not None, it should be a file
3300 descriptor open to a directory, and the respective path string (src or dst)
3301 should be relative; the path will then be relative to that directory.
3302If follow_symlinks is False, and the last element of src is a symbolic
3303 link, link will create a link to the symbolic link itself instead of the
3304 file the link points to.
3305src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3306 platform. If they are unavailable, using them will raise a
3307 NotImplementedError.
3308[clinic start generated code]*/
3309
Larry Hastings2f936352014-08-05 14:04:04 +10003310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003311os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003312 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003313/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003314{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003315#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003316 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317#else
3318 int result;
3319#endif
3320
Larry Hastings9cf065c2012-06-22 16:30:09 -07003321#ifndef HAVE_LINKAT
3322 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3323 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003324 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325 }
3326#endif
3327
Steve Dowercc16be82016-09-08 10:35:16 -07003328#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003329 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330 PyErr_SetString(PyExc_NotImplementedError,
3331 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003332 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333 }
Steve Dowercc16be82016-09-08 10:35:16 -07003334#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003335
Brian Curtin1b9df392010-11-24 20:24:31 +00003336#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003338 if (src->wide)
3339 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003341
Larry Hastings2f936352014-08-05 14:04:04 +10003342 if (!result)
3343 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344#else
3345 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003346#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3348 (dst_dir_fd != DEFAULT_DIR_FD) ||
3349 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003350 result = linkat(src_dir_fd, src->narrow,
3351 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3353 else
Steve Dowercc16be82016-09-08 10:35:16 -07003354#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003355 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003357
Larry Hastings2f936352014-08-05 14:04:04 +10003358 if (result)
3359 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003360#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361
Larry Hastings2f936352014-08-05 14:04:04 +10003362 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003363}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364#endif
3365
Brian Curtin1b9df392010-11-24 20:24:31 +00003366
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003367#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003368static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003369_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003370{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371 PyObject *v;
3372 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3373 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003374 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003376 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378
Steve Dowercc16be82016-09-08 10:35:16 -07003379 WIN32_FIND_DATAW wFileData;
3380 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003381
Steve Dowercc16be82016-09-08 10:35:16 -07003382 if (!path->wide) { /* Default arg: "." */
3383 po_wchars = L".";
3384 len = 1;
3385 } else {
3386 po_wchars = path->wide;
3387 len = wcslen(path->wide);
3388 }
3389 /* The +5 is so we can append "\\*.*\0" */
3390 wnamebuf = PyMem_New(wchar_t, len + 5);
3391 if (!wnamebuf) {
3392 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 }
Steve Dowercc16be82016-09-08 10:35:16 -07003395 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003397 wchar_t wch = wnamebuf[len-1];
3398 if (wch != SEP && wch != ALTSEP && wch != L':')
3399 wnamebuf[len++] = SEP;
3400 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003401 }
Steve Dowercc16be82016-09-08 10:35:16 -07003402 if ((list = PyList_New(0)) == NULL) {
3403 goto exit;
3404 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003405 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003406 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003407 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 if (hFindFile == INVALID_HANDLE_VALUE) {
3409 int error = GetLastError();
3410 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 goto exit;
3412 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003413 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
3416 do {
3417 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003418 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3419 wcscmp(wFileData.cFileName, L"..") != 0) {
3420 v = PyUnicode_FromWideChar(wFileData.cFileName,
3421 wcslen(wFileData.cFileName));
3422 if (path->narrow && v) {
3423 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3424 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 Py_DECREF(list);
3427 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 break;
3429 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_DECREF(list);
3433 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 break;
3435 }
3436 Py_DECREF(v);
3437 }
3438 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003439 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 Py_END_ALLOW_THREADS
3441 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3442 it got to the end of the directory. */
3443 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
3448 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003449
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450exit:
3451 if (hFindFile != INVALID_HANDLE_VALUE) {
3452 if (FindClose(hFindFile) == FALSE) {
3453 if (list != NULL) {
3454 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003455 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 }
3457 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003459 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003462} /* end of _listdir_windows_no_opendir */
3463
3464#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3465
3466static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003467_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003468{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003469 PyObject *v;
3470 DIR *dirp = NULL;
3471 struct dirent *ep;
3472 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003473#ifdef HAVE_FDOPENDIR
3474 int fd = -1;
3475#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003476
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003479 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003481 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003482 if (fd == -1)
3483 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484
Larry Hastingsfdaea062012-06-25 04:42:23 -07003485 return_str = 1;
3486
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 Py_BEGIN_ALLOW_THREADS
3488 dirp = fdopendir(fd);
3489 Py_END_ALLOW_THREADS
3490 }
3491 else
3492#endif
3493 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003494 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003495 if (path->narrow) {
3496 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003497 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003498 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003499 }
3500 else {
3501 name = ".";
3502 return_str = 1;
3503 }
3504
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 Py_BEGIN_ALLOW_THREADS
3506 dirp = opendir(name);
3507 Py_END_ALLOW_THREADS
3508 }
3509
3510 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003511 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003512#ifdef HAVE_FDOPENDIR
3513 if (fd != -1) {
3514 Py_BEGIN_ALLOW_THREADS
3515 close(fd);
3516 Py_END_ALLOW_THREADS
3517 }
3518#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 goto exit;
3520 }
3521 if ((list = PyList_New(0)) == NULL) {
3522 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
3524 for (;;) {
3525 errno = 0;
3526 Py_BEGIN_ALLOW_THREADS
3527 ep = readdir(dirp);
3528 Py_END_ALLOW_THREADS
3529 if (ep == NULL) {
3530 if (errno == 0) {
3531 break;
3532 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003534 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 }
3537 }
3538 if (ep->d_name[0] == '.' &&
3539 (NAMLEN(ep) == 1 ||
3540 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3541 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003542 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003543 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3544 else
3545 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 break;
3549 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 break;
3554 }
3555 Py_DECREF(v);
3556 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003557
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558exit:
3559 if (dirp != NULL) {
3560 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003561#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 if (fd > -1)
3563 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003564#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 closedir(dirp);
3566 Py_END_ALLOW_THREADS
3567 }
3568
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003570} /* end of _posix_listdir */
3571#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003572
Larry Hastings2f936352014-08-05 14:04:04 +10003573
3574/*[clinic input]
3575os.listdir
3576
3577 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3578
3579Return a list containing the names of the files in the directory.
3580
3581path can be specified as either str or bytes. If path is bytes,
3582 the filenames returned will also be bytes; in all other circumstances
3583 the filenames returned will be str.
3584If path is None, uses the path='.'.
3585On some platforms, path may also be specified as an open file descriptor;\
3586 the file descriptor must refer to a directory.
3587 If this functionality is unavailable, using it raises NotImplementedError.
3588
3589The list is in arbitrary order. It does not include the special
3590entries '.' and '..' even if they are present in the directory.
3591
3592
3593[clinic start generated code]*/
3594
Larry Hastings2f936352014-08-05 14:04:04 +10003595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003596os_listdir_impl(PyObject *module, path_t *path)
3597/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003598{
3599#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3600 return _listdir_windows_no_opendir(path, NULL);
3601#else
3602 return _posix_listdir(path, NULL);
3603#endif
3604}
3605
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003606#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003607/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003608/*[clinic input]
3609os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003610
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003611 path: path_t
3612 /
3613
3614[clinic start generated code]*/
3615
3616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003617os__getfullpathname_impl(PyObject *module, path_t *path)
3618/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003619{
Steve Dowercc16be82016-09-08 10:35:16 -07003620 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3621 wchar_t *wtemp;
3622 DWORD result;
3623 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003624
Steve Dowercc16be82016-09-08 10:35:16 -07003625 result = GetFullPathNameW(path->wide,
3626 Py_ARRAY_LENGTH(woutbuf),
3627 woutbuf, &wtemp);
3628 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3629 woutbufp = PyMem_New(wchar_t, result);
3630 if (!woutbufp)
3631 return PyErr_NoMemory();
3632 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 }
Steve Dowercc16be82016-09-08 10:35:16 -07003634 if (result) {
3635 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3636 if (path->narrow)
3637 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3638 } else
3639 v = win32_error_object("GetFullPathNameW", path->object);
3640 if (woutbufp != woutbuf)
3641 PyMem_Free(woutbufp);
3642 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003643}
Brian Curtind40e6f72010-07-08 21:39:08 +00003644
Brian Curtind25aef52011-06-13 15:16:04 -05003645
Larry Hastings2f936352014-08-05 14:04:04 +10003646/*[clinic input]
3647os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003648
Larry Hastings2f936352014-08-05 14:04:04 +10003649 path: unicode
3650 /
3651
3652A helper function for samepath on windows.
3653[clinic start generated code]*/
3654
Larry Hastings2f936352014-08-05 14:04:04 +10003655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003656os__getfinalpathname_impl(PyObject *module, PyObject *path)
3657/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003658{
3659 HANDLE hFile;
3660 int buf_size;
3661 wchar_t *target_path;
3662 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003663 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003664 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003665
Larry Hastings2f936352014-08-05 14:04:04 +10003666 path_wchar = PyUnicode_AsUnicode(path);
3667 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003668 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003669
Brian Curtind40e6f72010-07-08 21:39:08 +00003670 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003671 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003672 0, /* desired access */
3673 0, /* share mode */
3674 NULL, /* security attributes */
3675 OPEN_EXISTING,
3676 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3677 FILE_FLAG_BACKUP_SEMANTICS,
3678 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003679
Victor Stinnereb5657a2011-09-30 01:44:27 +02003680 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003681 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003682
3683 /* We have a good handle to the target, use it to determine the
3684 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003685 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003686
3687 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003688 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003689
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003690 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003691 if(!target_path)
3692 return PyErr_NoMemory();
3693
Steve Dower2ea51c92015-03-20 21:49:12 -07003694 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3695 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003696 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003697 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003698
3699 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003700 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003701
3702 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003703 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003704 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003705 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003706}
Brian Curtin62857742010-09-06 17:07:27 +00003707
Brian Curtin95d028f2011-06-09 09:10:38 -05003708PyDoc_STRVAR(posix__isdir__doc__,
3709"Return true if the pathname refers to an existing directory.");
3710
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003711/*[clinic input]
3712os._isdir
3713
3714 path: path_t
3715 /
3716
3717[clinic start generated code]*/
3718
Brian Curtin9c669cc2011-06-08 18:17:18 -05003719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003720os__isdir_impl(PyObject *module, path_t *path)
3721/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003722{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003723 DWORD attributes;
3724
Steve Dowerb22a6772016-07-17 20:49:38 -07003725 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003726 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003727 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003728
Brian Curtin9c669cc2011-06-08 18:17:18 -05003729 if (attributes == INVALID_FILE_ATTRIBUTES)
3730 Py_RETURN_FALSE;
3731
Brian Curtin9c669cc2011-06-08 18:17:18 -05003732 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3733 Py_RETURN_TRUE;
3734 else
3735 Py_RETURN_FALSE;
3736}
Tim Golden6b528062013-08-01 12:44:00 +01003737
Tim Golden6b528062013-08-01 12:44:00 +01003738
Larry Hastings2f936352014-08-05 14:04:04 +10003739/*[clinic input]
3740os._getvolumepathname
3741
3742 path: unicode
3743
3744A helper function for ismount on Win32.
3745[clinic start generated code]*/
3746
Larry Hastings2f936352014-08-05 14:04:04 +10003747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003748os__getvolumepathname_impl(PyObject *module, PyObject *path)
3749/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003750{
3751 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003752 const wchar_t *path_wchar;
3753 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003754 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003755 BOOL ret;
3756
Larry Hastings2f936352014-08-05 14:04:04 +10003757 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3758 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003759 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003760 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003761
3762 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003763 buflen = Py_MAX(buflen, MAX_PATH);
3764
3765 if (buflen > DWORD_MAX) {
3766 PyErr_SetString(PyExc_OverflowError, "path too long");
3767 return NULL;
3768 }
3769
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003770 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003771 if (mountpath == NULL)
3772 return PyErr_NoMemory();
3773
3774 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003775 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003776 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003777 Py_END_ALLOW_THREADS
3778
3779 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003780 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003781 goto exit;
3782 }
3783 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3784
3785exit:
3786 PyMem_Free(mountpath);
3787 return result;
3788}
Tim Golden6b528062013-08-01 12:44:00 +01003789
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003790#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003791
Larry Hastings2f936352014-08-05 14:04:04 +10003792
3793/*[clinic input]
3794os.mkdir
3795
3796 path : path_t
3797
3798 mode: int = 0o777
3799
3800 *
3801
3802 dir_fd : dir_fd(requires='mkdirat') = None
3803
3804# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3805
3806Create a directory.
3807
3808If dir_fd is not None, it should be a file descriptor open to a directory,
3809 and path should be relative; path will then be relative to that directory.
3810dir_fd may not be implemented on your platform.
3811 If it is unavailable, using it will raise a NotImplementedError.
3812
3813The mode argument is ignored on Windows.
3814[clinic start generated code]*/
3815
Larry Hastings2f936352014-08-05 14:04:04 +10003816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003817os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3818/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003819{
3820 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003821
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003822#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003823 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003824 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003825 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003826
Larry Hastings2f936352014-08-05 14:04:04 +10003827 if (!result)
3828 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003830 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831#if HAVE_MKDIRAT
3832 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003833 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003834 else
3835#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003836#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003837 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003838#else
Larry Hastings2f936352014-08-05 14:04:04 +10003839 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003840#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003841 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003842 if (result < 0)
3843 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003844#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003845 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003846}
3847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003848
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003849/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3850#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003851#include <sys/resource.h>
3852#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003853
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003854
3855#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003856/*[clinic input]
3857os.nice
3858
3859 increment: int
3860 /
3861
3862Add increment to the priority of process and return the new priority.
3863[clinic start generated code]*/
3864
Larry Hastings2f936352014-08-05 14:04:04 +10003865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003866os_nice_impl(PyObject *module, int increment)
3867/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003868{
3869 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003870
Victor Stinner8c62be82010-05-06 00:08:46 +00003871 /* There are two flavours of 'nice': one that returns the new
3872 priority (as required by almost all standards out there) and the
3873 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3874 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003875
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 If we are of the nice family that returns the new priority, we
3877 need to clear errno before the call, and check if errno is filled
3878 before calling posix_error() on a returnvalue of -1, because the
3879 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003880
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 errno = 0;
3882 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003883#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 if (value == 0)
3885 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003886#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 if (value == -1 && errno != 0)
3888 /* either nice() or getpriority() returned an error */
3889 return posix_error();
3890 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003891}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003892#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003893
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003894
3895#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003896/*[clinic input]
3897os.getpriority
3898
3899 which: int
3900 who: int
3901
3902Return program scheduling priority.
3903[clinic start generated code]*/
3904
Larry Hastings2f936352014-08-05 14:04:04 +10003905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003906os_getpriority_impl(PyObject *module, int which, int who)
3907/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003908{
3909 int retval;
3910
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003911 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003912 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003913 if (errno != 0)
3914 return posix_error();
3915 return PyLong_FromLong((long)retval);
3916}
3917#endif /* HAVE_GETPRIORITY */
3918
3919
3920#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003921/*[clinic input]
3922os.setpriority
3923
3924 which: int
3925 who: int
3926 priority: int
3927
3928Set program scheduling priority.
3929[clinic start generated code]*/
3930
Larry Hastings2f936352014-08-05 14:04:04 +10003931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003932os_setpriority_impl(PyObject *module, int which, int who, int priority)
3933/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003934{
3935 int retval;
3936
3937 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003938 if (retval == -1)
3939 return posix_error();
3940 Py_RETURN_NONE;
3941}
3942#endif /* HAVE_SETPRIORITY */
3943
3944
Barry Warsaw53699e91996-12-10 23:23:01 +00003945static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003946internal_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 +00003947{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003948 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003949 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003950
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003953 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003954#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003955 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003956#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003957
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3959 (dst_dir_fd != DEFAULT_DIR_FD);
3960#ifndef HAVE_RENAMEAT
3961 if (dir_fd_specified) {
3962 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003963 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003964 }
3965#endif
3966
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967#ifdef MS_WINDOWS
3968 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003969 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970 Py_END_ALLOW_THREADS
3971
Larry Hastings2f936352014-08-05 14:04:04 +10003972 if (!result)
3973 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974
3975#else
Steve Dowercc16be82016-09-08 10:35:16 -07003976 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3977 PyErr_Format(PyExc_ValueError,
3978 "%s: src and dst must be the same type", function_name);
3979 return NULL;
3980 }
3981
Larry Hastings9cf065c2012-06-22 16:30:09 -07003982 Py_BEGIN_ALLOW_THREADS
3983#ifdef HAVE_RENAMEAT
3984 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003985 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986 else
3987#endif
Steve Dowercc16be82016-09-08 10:35:16 -07003988 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989 Py_END_ALLOW_THREADS
3990
Larry Hastings2f936352014-08-05 14:04:04 +10003991 if (result)
3992 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003994 Py_RETURN_NONE;
3995}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996
Larry Hastings2f936352014-08-05 14:04:04 +10003997
3998/*[clinic input]
3999os.rename
4000
4001 src : path_t
4002 dst : path_t
4003 *
4004 src_dir_fd : dir_fd = None
4005 dst_dir_fd : dir_fd = None
4006
4007Rename a file or directory.
4008
4009If either src_dir_fd or dst_dir_fd is not None, it should be a file
4010 descriptor open to a directory, and the respective path string (src or dst)
4011 should be relative; the path will then be relative to that directory.
4012src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4013 If they are unavailable, using them will raise a NotImplementedError.
4014[clinic start generated code]*/
4015
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004017os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004018 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004019/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004020{
Larry Hastings2f936352014-08-05 14:04:04 +10004021 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004022}
4023
Larry Hastings2f936352014-08-05 14:04:04 +10004024
4025/*[clinic input]
4026os.replace = os.rename
4027
4028Rename a file or directory, overwriting the destination.
4029
4030If either src_dir_fd or dst_dir_fd is not None, it should be a file
4031 descriptor open to a directory, and the respective path string (src or dst)
4032 should be relative; the path will then be relative to that directory.
4033src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4034 If they are unavailable, using them will raise a NotImplementedError."
4035[clinic start generated code]*/
4036
Larry Hastings2f936352014-08-05 14:04:04 +10004037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004038os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4039 int dst_dir_fd)
4040/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004041{
4042 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4043}
4044
4045
4046/*[clinic input]
4047os.rmdir
4048
4049 path: path_t
4050 *
4051 dir_fd: dir_fd(requires='unlinkat') = None
4052
4053Remove a directory.
4054
4055If dir_fd is not None, it should be a file descriptor open to a directory,
4056 and path should be relative; path will then be relative to that directory.
4057dir_fd may not be implemented on your platform.
4058 If it is unavailable, using it will raise a NotImplementedError.
4059[clinic start generated code]*/
4060
Larry Hastings2f936352014-08-05 14:04:04 +10004061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004062os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4063/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004064{
4065 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004066
4067 Py_BEGIN_ALLOW_THREADS
4068#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004069 /* Windows, success=1, UNIX, success=0 */
4070 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004071#else
4072#ifdef HAVE_UNLINKAT
4073 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004074 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004075 else
4076#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004077 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004078#endif
4079 Py_END_ALLOW_THREADS
4080
Larry Hastings2f936352014-08-05 14:04:04 +10004081 if (result)
4082 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004083
Larry Hastings2f936352014-08-05 14:04:04 +10004084 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004085}
4086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004087
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004088#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004089#ifdef MS_WINDOWS
4090/*[clinic input]
4091os.system -> long
4092
4093 command: Py_UNICODE
4094
4095Execute the command in a subshell.
4096[clinic start generated code]*/
4097
Larry Hastings2f936352014-08-05 14:04:04 +10004098static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004099os_system_impl(PyObject *module, Py_UNICODE *command)
4100/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004101{
4102 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004103 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004104 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004105 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004106 return result;
4107}
4108#else /* MS_WINDOWS */
4109/*[clinic input]
4110os.system -> long
4111
4112 command: FSConverter
4113
4114Execute the command in a subshell.
4115[clinic start generated code]*/
4116
Larry Hastings2f936352014-08-05 14:04:04 +10004117static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004118os_system_impl(PyObject *module, PyObject *command)
4119/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004120{
4121 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004122 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004123 Py_BEGIN_ALLOW_THREADS
4124 result = system(bytes);
4125 Py_END_ALLOW_THREADS
4126 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004127}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004128#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004129#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004131
Larry Hastings2f936352014-08-05 14:04:04 +10004132/*[clinic input]
4133os.umask
4134
4135 mask: int
4136 /
4137
4138Set the current numeric umask and return the previous umask.
4139[clinic start generated code]*/
4140
Larry Hastings2f936352014-08-05 14:04:04 +10004141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004142os_umask_impl(PyObject *module, int mask)
4143/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004144{
4145 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004146 if (i < 0)
4147 return posix_error();
4148 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004149}
4150
Brian Curtind40e6f72010-07-08 21:39:08 +00004151#ifdef MS_WINDOWS
4152
4153/* override the default DeleteFileW behavior so that directory
4154symlinks can be removed with this function, the same as with
4155Unix symlinks */
4156BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4157{
4158 WIN32_FILE_ATTRIBUTE_DATA info;
4159 WIN32_FIND_DATAW find_data;
4160 HANDLE find_data_handle;
4161 int is_directory = 0;
4162 int is_link = 0;
4163
4164 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4165 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004166
Brian Curtind40e6f72010-07-08 21:39:08 +00004167 /* Get WIN32_FIND_DATA structure for the path to determine if
4168 it is a symlink */
4169 if(is_directory &&
4170 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4171 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4172
4173 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004174 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4175 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4176 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4177 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004178 FindClose(find_data_handle);
4179 }
4180 }
4181 }
4182
4183 if (is_directory && is_link)
4184 return RemoveDirectoryW(lpFileName);
4185
4186 return DeleteFileW(lpFileName);
4187}
4188#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004190
Larry Hastings2f936352014-08-05 14:04:04 +10004191/*[clinic input]
4192os.unlink
4193
4194 path: path_t
4195 *
4196 dir_fd: dir_fd(requires='unlinkat')=None
4197
4198Remove a file (same as remove()).
4199
4200If dir_fd is not None, it should be a file descriptor open to a directory,
4201 and path should be relative; path will then be relative to that directory.
4202dir_fd may not be implemented on your platform.
4203 If it is unavailable, using it will raise a NotImplementedError.
4204
4205[clinic start generated code]*/
4206
Larry Hastings2f936352014-08-05 14:04:04 +10004207static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004208os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4209/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004210{
4211 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004212
4213 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004214 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004215#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004216 /* Windows, success=1, UNIX, success=0 */
4217 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004218#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004219#ifdef HAVE_UNLINKAT
4220 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004221 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004222 else
4223#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004224 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004225#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004226 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227 Py_END_ALLOW_THREADS
4228
Larry Hastings2f936352014-08-05 14:04:04 +10004229 if (result)
4230 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231
Larry Hastings2f936352014-08-05 14:04:04 +10004232 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004233}
4234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004235
Larry Hastings2f936352014-08-05 14:04:04 +10004236/*[clinic input]
4237os.remove = os.unlink
4238
4239Remove a file (same as unlink()).
4240
4241If dir_fd is not None, it should be a file descriptor open to a directory,
4242 and path should be relative; path will then be relative to that directory.
4243dir_fd may not be implemented on your platform.
4244 If it is unavailable, using it will raise a NotImplementedError.
4245[clinic start generated code]*/
4246
Larry Hastings2f936352014-08-05 14:04:04 +10004247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004248os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4249/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004250{
4251 return os_unlink_impl(module, path, dir_fd);
4252}
4253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004254
Larry Hastings605a62d2012-06-24 04:33:36 -07004255static PyStructSequence_Field uname_result_fields[] = {
4256 {"sysname", "operating system name"},
4257 {"nodename", "name of machine on network (implementation-defined)"},
4258 {"release", "operating system release"},
4259 {"version", "operating system version"},
4260 {"machine", "hardware identifier"},
4261 {NULL}
4262};
4263
4264PyDoc_STRVAR(uname_result__doc__,
4265"uname_result: Result from os.uname().\n\n\
4266This object may be accessed either as a tuple of\n\
4267 (sysname, nodename, release, version, machine),\n\
4268or via the attributes sysname, nodename, release, version, and machine.\n\
4269\n\
4270See os.uname for more information.");
4271
4272static PyStructSequence_Desc uname_result_desc = {
4273 "uname_result", /* name */
4274 uname_result__doc__, /* doc */
4275 uname_result_fields,
4276 5
4277};
4278
4279static PyTypeObject UnameResultType;
4280
4281
4282#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004283/*[clinic input]
4284os.uname
4285
4286Return an object identifying the current operating system.
4287
4288The object behaves like a named tuple with the following fields:
4289 (sysname, nodename, release, version, machine)
4290
4291[clinic start generated code]*/
4292
Larry Hastings2f936352014-08-05 14:04:04 +10004293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004294os_uname_impl(PyObject *module)
4295/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004296{
Victor Stinner8c62be82010-05-06 00:08:46 +00004297 struct utsname u;
4298 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004299 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004300
Victor Stinner8c62be82010-05-06 00:08:46 +00004301 Py_BEGIN_ALLOW_THREADS
4302 res = uname(&u);
4303 Py_END_ALLOW_THREADS
4304 if (res < 0)
4305 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004306
4307 value = PyStructSequence_New(&UnameResultType);
4308 if (value == NULL)
4309 return NULL;
4310
4311#define SET(i, field) \
4312 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004313 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004314 if (!o) { \
4315 Py_DECREF(value); \
4316 return NULL; \
4317 } \
4318 PyStructSequence_SET_ITEM(value, i, o); \
4319 } \
4320
4321 SET(0, u.sysname);
4322 SET(1, u.nodename);
4323 SET(2, u.release);
4324 SET(3, u.version);
4325 SET(4, u.machine);
4326
4327#undef SET
4328
4329 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004330}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004331#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004332
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004333
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334
4335typedef struct {
4336 int now;
4337 time_t atime_s;
4338 long atime_ns;
4339 time_t mtime_s;
4340 long mtime_ns;
4341} utime_t;
4342
4343/*
Victor Stinner484df002014-10-09 13:52:31 +02004344 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345 * they also intentionally leak the declaration of a pointer named "time"
4346 */
4347#define UTIME_TO_TIMESPEC \
4348 struct timespec ts[2]; \
4349 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004350 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004351 time = NULL; \
4352 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004353 ts[0].tv_sec = ut->atime_s; \
4354 ts[0].tv_nsec = ut->atime_ns; \
4355 ts[1].tv_sec = ut->mtime_s; \
4356 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357 time = ts; \
4358 } \
4359
4360#define UTIME_TO_TIMEVAL \
4361 struct timeval tv[2]; \
4362 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004363 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364 time = NULL; \
4365 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004366 tv[0].tv_sec = ut->atime_s; \
4367 tv[0].tv_usec = ut->atime_ns / 1000; \
4368 tv[1].tv_sec = ut->mtime_s; \
4369 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004370 time = tv; \
4371 } \
4372
4373#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004374 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004376 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 time = NULL; \
4378 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004379 u.actime = ut->atime_s; \
4380 u.modtime = ut->mtime_s; \
4381 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 }
4383
4384#define UTIME_TO_TIME_T \
4385 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004386 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004387 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388 time = NULL; \
4389 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004390 timet[0] = ut->atime_s; \
4391 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004392 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393 } \
4394
4395
Victor Stinner528a9ab2015-09-03 21:30:26 +02004396#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397
4398static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004399utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400{
4401#ifdef HAVE_UTIMENSAT
4402 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4403 UTIME_TO_TIMESPEC;
4404 return utimensat(dir_fd, path, time, flags);
4405#elif defined(HAVE_FUTIMESAT)
4406 UTIME_TO_TIMEVAL;
4407 /*
4408 * follow_symlinks will never be false here;
4409 * we only allow !follow_symlinks and dir_fd together
4410 * if we have utimensat()
4411 */
4412 assert(follow_symlinks);
4413 return futimesat(dir_fd, path, time);
4414#endif
4415}
4416
Larry Hastings2f936352014-08-05 14:04:04 +10004417 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4418#else
4419 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420#endif
4421
Victor Stinner528a9ab2015-09-03 21:30:26 +02004422#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004423
4424static int
Victor Stinner484df002014-10-09 13:52:31 +02004425utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004426{
4427#ifdef HAVE_FUTIMENS
4428 UTIME_TO_TIMESPEC;
4429 return futimens(fd, time);
4430#else
4431 UTIME_TO_TIMEVAL;
4432 return futimes(fd, time);
4433#endif
4434}
4435
Larry Hastings2f936352014-08-05 14:04:04 +10004436 #define PATH_UTIME_HAVE_FD 1
4437#else
4438 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439#endif
4440
Victor Stinner5ebae872015-09-22 01:29:33 +02004441#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4442# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4443#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444
Victor Stinner4552ced2015-09-21 22:37:15 +02004445#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004446
4447static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004448utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004449{
4450#ifdef HAVE_UTIMENSAT
4451 UTIME_TO_TIMESPEC;
4452 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4453#else
4454 UTIME_TO_TIMEVAL;
4455 return lutimes(path, time);
4456#endif
4457}
4458
4459#endif
4460
4461#ifndef MS_WINDOWS
4462
4463static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004464utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004465{
4466#ifdef HAVE_UTIMENSAT
4467 UTIME_TO_TIMESPEC;
4468 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4469#elif defined(HAVE_UTIMES)
4470 UTIME_TO_TIMEVAL;
4471 return utimes(path, time);
4472#elif defined(HAVE_UTIME_H)
4473 UTIME_TO_UTIMBUF;
4474 return utime(path, time);
4475#else
4476 UTIME_TO_TIME_T;
4477 return utime(path, time);
4478#endif
4479}
4480
4481#endif
4482
Larry Hastings76ad59b2012-05-03 00:30:07 -07004483static int
4484split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4485{
4486 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004487 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004488 divmod = PyNumber_Divmod(py_long, billion);
4489 if (!divmod)
4490 goto exit;
4491 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4492 if ((*s == -1) && PyErr_Occurred())
4493 goto exit;
4494 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004495 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004496 goto exit;
4497
4498 result = 1;
4499exit:
4500 Py_XDECREF(divmod);
4501 return result;
4502}
4503
Larry Hastings2f936352014-08-05 14:04:04 +10004504
4505/*[clinic input]
4506os.utime
4507
4508 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4509 times: object = NULL
4510 *
4511 ns: object = NULL
4512 dir_fd: dir_fd(requires='futimensat') = None
4513 follow_symlinks: bool=True
4514
Martin Panter0ff89092015-09-09 01:56:53 +00004515# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004516
4517Set the access and modified time of path.
4518
4519path may always be specified as a string.
4520On some platforms, path may also be specified as an open file descriptor.
4521 If this functionality is unavailable, using it raises an exception.
4522
4523If times is not None, it must be a tuple (atime, mtime);
4524 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004525If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004526 atime_ns and mtime_ns should be expressed as integer nanoseconds
4527 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004528If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004529Specifying tuples for both times and ns is an error.
4530
4531If dir_fd is not None, it should be a file descriptor open to a directory,
4532 and path should be relative; path will then be relative to that directory.
4533If follow_symlinks is False, and the last element of the path is a symbolic
4534 link, utime will modify the symbolic link itself instead of the file the
4535 link points to.
4536It is an error to use dir_fd or follow_symlinks when specifying path
4537 as an open file descriptor.
4538dir_fd and follow_symlinks may not be available on your platform.
4539 If they are unavailable, using them will raise a NotImplementedError.
4540
4541[clinic start generated code]*/
4542
Larry Hastings2f936352014-08-05 14:04:04 +10004543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004544os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4545 int dir_fd, int follow_symlinks)
4546/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004547{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548#ifdef MS_WINDOWS
4549 HANDLE hFile;
4550 FILETIME atime, mtime;
4551#else
4552 int result;
4553#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004554
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004556 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004557
Christian Heimesb3c87242013-08-01 00:08:16 +02004558 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004559
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 if (times && (times != Py_None) && ns) {
4561 PyErr_SetString(PyExc_ValueError,
4562 "utime: you may specify either 'times'"
4563 " or 'ns' but not both");
4564 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565 }
4566
4567 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004568 time_t a_sec, m_sec;
4569 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004571 PyErr_SetString(PyExc_TypeError,
4572 "utime: 'times' must be either"
4573 " a tuple of two ints or None");
4574 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004576 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004577 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004578 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004579 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004580 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004582 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004583 utime.atime_s = a_sec;
4584 utime.atime_ns = a_nsec;
4585 utime.mtime_s = m_sec;
4586 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 PyErr_SetString(PyExc_TypeError,
4591 "utime: 'ns' must be a tuple of two ints");
4592 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004593 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004595 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004597 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 &utime.mtime_s, &utime.mtime_ns)) {
4599 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004600 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601 }
4602 else {
4603 /* times and ns are both None/unspecified. use "now". */
4604 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004605 }
4606
Victor Stinner4552ced2015-09-21 22:37:15 +02004607#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 if (follow_symlinks_specified("utime", follow_symlinks))
4609 goto exit;
4610#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004611
Larry Hastings2f936352014-08-05 14:04:04 +10004612 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4613 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4614 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004616
Larry Hastings9cf065c2012-06-22 16:30:09 -07004617#if !defined(HAVE_UTIMENSAT)
4618 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004619 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 "utime: cannot use dir_fd and follow_symlinks "
4621 "together on this platform");
4622 goto exit;
4623 }
4624#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004625
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004626#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004628 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4629 NULL, OPEN_EXISTING,
4630 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 Py_END_ALLOW_THREADS
4632 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004633 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004635 }
4636
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004638 GetSystemTimeAsFileTime(&mtime);
4639 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004640 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004641 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004642 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4643 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004644 }
4645 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4646 /* Avoid putting the file name into the error here,
4647 as that may confuse the user into believing that
4648 something is wrong with the file, when it also
4649 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004650 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004653#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004655
Victor Stinner4552ced2015-09-21 22:37:15 +02004656#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004658 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004660#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661
Victor Stinner528a9ab2015-09-03 21:30:26 +02004662#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004664 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 else
4666#endif
4667
Victor Stinner528a9ab2015-09-03 21:30:26 +02004668#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004669 if (path->fd != -1)
4670 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 else
4672#endif
4673
Larry Hastings2f936352014-08-05 14:04:04 +10004674 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675
4676 Py_END_ALLOW_THREADS
4677
4678 if (result < 0) {
4679 /* see previous comment about not putting filename in error here */
4680 return_value = posix_error();
4681 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004682 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004683
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004684#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685
4686 Py_INCREF(Py_None);
4687 return_value = Py_None;
4688
4689exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690#ifdef MS_WINDOWS
4691 if (hFile != INVALID_HANDLE_VALUE)
4692 CloseHandle(hFile);
4693#endif
4694 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004695}
4696
Guido van Rossum3b066191991-06-04 19:40:25 +00004697/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004698
Larry Hastings2f936352014-08-05 14:04:04 +10004699
4700/*[clinic input]
4701os._exit
4702
4703 status: int
4704
4705Exit to the system with specified status, without normal exit processing.
4706[clinic start generated code]*/
4707
Larry Hastings2f936352014-08-05 14:04:04 +10004708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004709os__exit_impl(PyObject *module, int status)
4710/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004711{
4712 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004713 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004714}
4715
Steve Dowercc16be82016-09-08 10:35:16 -07004716#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4717#define EXECV_CHAR wchar_t
4718#else
4719#define EXECV_CHAR char
4720#endif
4721
Martin v. Löwis114619e2002-10-07 06:44:21 +00004722#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4723static void
Steve Dowercc16be82016-09-08 10:35:16 -07004724free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004725{
Victor Stinner8c62be82010-05-06 00:08:46 +00004726 Py_ssize_t i;
4727 for (i = 0; i < count; i++)
4728 PyMem_Free(array[i]);
4729 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004730}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004731
Antoine Pitrou69f71142009-05-24 21:25:49 +00004732static
Steve Dowercc16be82016-09-08 10:35:16 -07004733int fsconvert_strdup(PyObject *o, EXECV_CHAR**out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004734{
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 Py_ssize_t size;
Steve Dowercc16be82016-09-08 10:35:16 -07004736#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4737 *out = PyUnicode_AsWideCharString(o, &size);
4738 if (!*out)
4739 return 0;
4740#else
4741 PyObject *bytes;
Victor Stinner8c62be82010-05-06 00:08:46 +00004742 if (!PyUnicode_FSConverter(o, &bytes))
4743 return 0;
4744 size = PyBytes_GET_SIZE(bytes);
4745 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004746 if (!*out) {
4747 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004748 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004749 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004750 memcpy(*out, PyBytes_AsString(bytes), size+1);
4751 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07004752#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004753 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004754}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004755#endif
4756
Ross Lagerwall7807c352011-03-17 20:20:30 +02004757#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004758static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004759parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4760{
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 Py_ssize_t i, pos, envc;
4762 PyObject *keys=NULL, *vals=NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004763 PyObject *key, *val, *keyval;
4764 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004765
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 i = PyMapping_Size(env);
4767 if (i < 0)
4768 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004769 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004770 if (envlist == NULL) {
4771 PyErr_NoMemory();
4772 return NULL;
4773 }
4774 envc = 0;
4775 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004776 if (!keys)
4777 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004779 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 goto error;
4781 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4782 PyErr_Format(PyExc_TypeError,
4783 "env.keys() or env.values() is not a list");
4784 goto error;
4785 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004786
Victor Stinner8c62be82010-05-06 00:08:46 +00004787 for (pos = 0; pos < i; pos++) {
4788 key = PyList_GetItem(keys, pos);
4789 val = PyList_GetItem(vals, pos);
4790 if (!key || !val)
4791 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004792
Steve Dowercc16be82016-09-08 10:35:16 -07004793 keyval = PyUnicode_FromFormat("%U=%U", key, val);
4794 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004796
4797 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4798 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 goto error;
4800 }
Steve Dowercc16be82016-09-08 10:35:16 -07004801
4802 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004803 }
4804 Py_DECREF(vals);
4805 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004806
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 envlist[envc] = 0;
4808 *envc_ptr = envc;
4809 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004810
4811error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 Py_XDECREF(keys);
4813 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004814 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004816}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004817
Steve Dowercc16be82016-09-08 10:35:16 -07004818static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004819parse_arglist(PyObject* argv, Py_ssize_t *argc)
4820{
4821 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004822 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004823 if (argvlist == NULL) {
4824 PyErr_NoMemory();
4825 return NULL;
4826 }
4827 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004828 PyObject* item = PySequence_ITEM(argv, i);
4829 if (item == NULL)
4830 goto fail;
4831 if (!fsconvert_strdup(item, &argvlist[i])) {
4832 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004833 goto fail;
4834 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004835 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004836 }
4837 argvlist[*argc] = NULL;
4838 return argvlist;
4839fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004840 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004841 free_string_array(argvlist, *argc);
4842 return NULL;
4843}
Steve Dowercc16be82016-09-08 10:35:16 -07004844
Ross Lagerwall7807c352011-03-17 20:20:30 +02004845#endif
4846
Larry Hastings2f936352014-08-05 14:04:04 +10004847
Ross Lagerwall7807c352011-03-17 20:20:30 +02004848#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004849/*[clinic input]
4850os.execv
4851
Steve Dowercc16be82016-09-08 10:35:16 -07004852 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004853 Path of executable file.
4854 argv: object
4855 Tuple or list of strings.
4856 /
4857
4858Execute an executable path with arguments, replacing current process.
4859[clinic start generated code]*/
4860
Larry Hastings2f936352014-08-05 14:04:04 +10004861static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004862os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4863/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004864{
Steve Dowercc16be82016-09-08 10:35:16 -07004865 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004866 Py_ssize_t argc;
4867
4868 /* execv has two arguments: (path, argv), where
4869 argv is a list or tuple of strings. */
4870
Ross Lagerwall7807c352011-03-17 20:20:30 +02004871 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4872 PyErr_SetString(PyExc_TypeError,
4873 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004874 return NULL;
4875 }
4876 argc = PySequence_Size(argv);
4877 if (argc < 1) {
4878 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004879 return NULL;
4880 }
4881
4882 argvlist = parse_arglist(argv, &argc);
4883 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004884 return NULL;
4885 }
4886
Steve Dowercc16be82016-09-08 10:35:16 -07004887#ifdef HAVE_WEXECV
4888 _wexecv(path->wide, argvlist);
4889#else
4890 execv(path->narrow, argvlist);
4891#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004892
4893 /* If we get here it's definitely an error */
4894
4895 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004896 return posix_error();
4897}
4898
Larry Hastings2f936352014-08-05 14:04:04 +10004899
4900/*[clinic input]
4901os.execve
4902
4903 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4904 Path of executable file.
4905 argv: object
4906 Tuple or list of strings.
4907 env: object
4908 Dictionary of strings mapping to strings.
4909
4910Execute an executable path with arguments, replacing current process.
4911[clinic start generated code]*/
4912
Larry Hastings2f936352014-08-05 14:04:04 +10004913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004914os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4915/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004916{
Steve Dowercc16be82016-09-08 10:35:16 -07004917 EXECV_CHAR **argvlist = NULL;
4918 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004919 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004920
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 /* execve has three arguments: (path, argv, env), where
4922 argv is a list or tuple of strings and env is a dictionary
4923 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004924
Ross Lagerwall7807c352011-03-17 20:20:30 +02004925 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 "execve: argv must be a tuple or list");
4928 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004930 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 if (!PyMapping_Check(env)) {
4932 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004933 "execve: environment must be a mapping object");
4934 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004936
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004939 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004941
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 envlist = parse_envlist(env, &envc);
4943 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004944 goto fail;
4945
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10004947 if (path->fd > -1)
4948 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 else
4950#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004951#ifdef HAVE_WEXECV
4952 _wexecve(path->wide, argvlist, envlist);
4953#else
Larry Hastings2f936352014-08-05 14:04:04 +10004954 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07004955#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956
4957 /* If we get here it's definitely an error */
4958
Larry Hastings2f936352014-08-05 14:04:04 +10004959 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004960
Steve Dowercc16be82016-09-08 10:35:16 -07004961 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963 if (argvlist)
4964 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004965 return NULL;
4966}
Steve Dowercc16be82016-09-08 10:35:16 -07004967
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968#endif /* HAVE_EXECV */
4969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Steve Dowercc16be82016-09-08 10:35:16 -07004971#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10004972/*[clinic input]
4973os.spawnv
4974
4975 mode: int
4976 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07004977 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004978 Path of executable file.
4979 argv: object
4980 Tuple or list of strings.
4981 /
4982
4983Execute the program specified by path in a new process.
4984[clinic start generated code]*/
4985
Larry Hastings2f936352014-08-05 14:04:04 +10004986static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004987os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
4988/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004989{
Steve Dowercc16be82016-09-08 10:35:16 -07004990 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10004991 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07004993 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 /* spawnv has three arguments: (mode, path, argv), where
4997 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004998
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 if (PyList_Check(argv)) {
5000 argc = PyList_Size(argv);
5001 getitem = PyList_GetItem;
5002 }
5003 else if (PyTuple_Check(argv)) {
5004 argc = PyTuple_Size(argv);
5005 getitem = PyTuple_GetItem;
5006 }
5007 else {
5008 PyErr_SetString(PyExc_TypeError,
5009 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005010 return NULL;
5011 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005012
Steve Dowercc16be82016-09-08 10:35:16 -07005013 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 return PyErr_NoMemory();
5016 }
5017 for (i = 0; i < argc; i++) {
5018 if (!fsconvert_strdup((*getitem)(argv, i),
5019 &argvlist[i])) {
5020 free_string_array(argvlist, i);
5021 PyErr_SetString(
5022 PyExc_TypeError,
5023 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 return NULL;
5025 }
5026 }
5027 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005028
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 if (mode == _OLD_P_OVERLAY)
5030 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005033#ifdef HAVE_WSPAWNV
5034 spawnval = _wspawnv(mode, path->wide, argvlist);
5035#else
5036 spawnval = _spawnv(mode, path->narrow, argvlist);
5037#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005038 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005039
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005041
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 if (spawnval == -1)
5043 return posix_error();
5044 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005045 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005046}
5047
5048
Larry Hastings2f936352014-08-05 14:04:04 +10005049/*[clinic input]
5050os.spawnve
5051
5052 mode: int
5053 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005054 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005055 Path of executable file.
5056 argv: object
5057 Tuple or list of strings.
5058 env: object
5059 Dictionary of strings mapping to strings.
5060 /
5061
5062Execute the program specified by path in a new process.
5063[clinic start generated code]*/
5064
Larry Hastings2f936352014-08-05 14:04:04 +10005065static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005066os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005067 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005068/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005069{
Steve Dowercc16be82016-09-08 10:35:16 -07005070 EXECV_CHAR **argvlist;
5071 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005073 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005074 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005075 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5076 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005077
Victor Stinner8c62be82010-05-06 00:08:46 +00005078 /* spawnve has four arguments: (mode, path, argv, env), where
5079 argv is a list or tuple of strings and env is a dictionary
5080 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005081
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 if (PyList_Check(argv)) {
5083 argc = PyList_Size(argv);
5084 getitem = PyList_GetItem;
5085 }
5086 else if (PyTuple_Check(argv)) {
5087 argc = PyTuple_Size(argv);
5088 getitem = PyTuple_GetItem;
5089 }
5090 else {
5091 PyErr_SetString(PyExc_TypeError,
5092 "spawnve() arg 2 must be a tuple or list");
5093 goto fail_0;
5094 }
5095 if (!PyMapping_Check(env)) {
5096 PyErr_SetString(PyExc_TypeError,
5097 "spawnve() arg 3 must be a mapping object");
5098 goto fail_0;
5099 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005100
Steve Dowercc16be82016-09-08 10:35:16 -07005101 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005102 if (argvlist == NULL) {
5103 PyErr_NoMemory();
5104 goto fail_0;
5105 }
5106 for (i = 0; i < argc; i++) {
5107 if (!fsconvert_strdup((*getitem)(argv, i),
5108 &argvlist[i]))
5109 {
5110 lastarg = i;
5111 goto fail_1;
5112 }
5113 }
5114 lastarg = argc;
5115 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005116
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 envlist = parse_envlist(env, &envc);
5118 if (envlist == NULL)
5119 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005120
Victor Stinner8c62be82010-05-06 00:08:46 +00005121 if (mode == _OLD_P_OVERLAY)
5122 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005123
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005125#ifdef HAVE_WSPAWNV
5126 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5127#else
5128 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5129#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005130 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005131
Victor Stinner8c62be82010-05-06 00:08:46 +00005132 if (spawnval == -1)
5133 (void) posix_error();
5134 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005135 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005136
Victor Stinner8c62be82010-05-06 00:08:46 +00005137 while (--envc >= 0)
5138 PyMem_DEL(envlist[envc]);
5139 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005140 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005142 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005143 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005144}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005145
Guido van Rossuma1065681999-01-25 23:20:23 +00005146#endif /* HAVE_SPAWNV */
5147
5148
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005149#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005150/*[clinic input]
5151os.fork1
5152
5153Fork a child process with a single multiplexed (i.e., not bound) thread.
5154
5155Return 0 to child process and PID of child to parent process.
5156[clinic start generated code]*/
5157
Larry Hastings2f936352014-08-05 14:04:04 +10005158static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005159os_fork1_impl(PyObject *module)
5160/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005161{
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 pid_t pid;
5163 int result = 0;
5164 _PyImport_AcquireLock();
5165 pid = fork1();
5166 if (pid == 0) {
5167 /* child: this clobbers and resets the import lock. */
5168 PyOS_AfterFork();
5169 } else {
5170 /* parent: release the import lock. */
5171 result = _PyImport_ReleaseLock();
5172 }
5173 if (pid == -1)
5174 return posix_error();
5175 if (result < 0) {
5176 /* Don't clobber the OSError if the fork failed. */
5177 PyErr_SetString(PyExc_RuntimeError,
5178 "not holding the import lock");
5179 return NULL;
5180 }
5181 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005182}
Larry Hastings2f936352014-08-05 14:04:04 +10005183#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005184
5185
Guido van Rossumad0ee831995-03-01 10:34:45 +00005186#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005187/*[clinic input]
5188os.fork
5189
5190Fork a child process.
5191
5192Return 0 to child process and PID of child to parent process.
5193[clinic start generated code]*/
5194
Larry Hastings2f936352014-08-05 14:04:04 +10005195static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005196os_fork_impl(PyObject *module)
5197/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005198{
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 pid_t pid;
5200 int result = 0;
5201 _PyImport_AcquireLock();
5202 pid = fork();
5203 if (pid == 0) {
5204 /* child: this clobbers and resets the import lock. */
5205 PyOS_AfterFork();
5206 } else {
5207 /* parent: release the import lock. */
5208 result = _PyImport_ReleaseLock();
5209 }
5210 if (pid == -1)
5211 return posix_error();
5212 if (result < 0) {
5213 /* Don't clobber the OSError if the fork failed. */
5214 PyErr_SetString(PyExc_RuntimeError,
5215 "not holding the import lock");
5216 return NULL;
5217 }
5218 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005219}
Larry Hastings2f936352014-08-05 14:04:04 +10005220#endif /* HAVE_FORK */
5221
Guido van Rossum85e3b011991-06-03 12:42:10 +00005222
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005223#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005224#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005225/*[clinic input]
5226os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005227
Larry Hastings2f936352014-08-05 14:04:04 +10005228 policy: int
5229
5230Get the maximum scheduling priority for policy.
5231[clinic start generated code]*/
5232
Larry Hastings2f936352014-08-05 14:04:04 +10005233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005234os_sched_get_priority_max_impl(PyObject *module, int policy)
5235/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005236{
5237 int max;
5238
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005239 max = sched_get_priority_max(policy);
5240 if (max < 0)
5241 return posix_error();
5242 return PyLong_FromLong(max);
5243}
5244
Larry Hastings2f936352014-08-05 14:04:04 +10005245
5246/*[clinic input]
5247os.sched_get_priority_min
5248
5249 policy: int
5250
5251Get the minimum scheduling priority for policy.
5252[clinic start generated code]*/
5253
Larry Hastings2f936352014-08-05 14:04:04 +10005254static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005255os_sched_get_priority_min_impl(PyObject *module, int policy)
5256/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005257{
5258 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005259 if (min < 0)
5260 return posix_error();
5261 return PyLong_FromLong(min);
5262}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005263#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5264
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005265
Larry Hastings2f936352014-08-05 14:04:04 +10005266#ifdef HAVE_SCHED_SETSCHEDULER
5267/*[clinic input]
5268os.sched_getscheduler
5269 pid: pid_t
5270 /
5271
5272Get the scheduling policy for the process identifiedy by pid.
5273
5274Passing 0 for pid returns the scheduling policy for the calling process.
5275[clinic start generated code]*/
5276
Larry Hastings2f936352014-08-05 14:04:04 +10005277static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005278os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5279/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005280{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005281 int policy;
5282
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005283 policy = sched_getscheduler(pid);
5284 if (policy < 0)
5285 return posix_error();
5286 return PyLong_FromLong(policy);
5287}
Larry Hastings2f936352014-08-05 14:04:04 +10005288#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005289
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005290
5291#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005292/*[clinic input]
5293class os.sched_param "PyObject *" "&SchedParamType"
5294
5295@classmethod
5296os.sched_param.__new__
5297
5298 sched_priority: object
5299 A scheduling parameter.
5300
5301Current has only one field: sched_priority");
5302[clinic start generated code]*/
5303
Larry Hastings2f936352014-08-05 14:04:04 +10005304static PyObject *
5305os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005306/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005307{
5308 PyObject *res;
5309
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005310 res = PyStructSequence_New(type);
5311 if (!res)
5312 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005313 Py_INCREF(sched_priority);
5314 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005315 return res;
5316}
5317
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005318
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005319PyDoc_VAR(os_sched_param__doc__);
5320
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005321static PyStructSequence_Field sched_param_fields[] = {
5322 {"sched_priority", "the scheduling priority"},
5323 {0}
5324};
5325
5326static PyStructSequence_Desc sched_param_desc = {
5327 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005328 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005329 sched_param_fields,
5330 1
5331};
5332
5333static int
5334convert_sched_param(PyObject *param, struct sched_param *res)
5335{
5336 long priority;
5337
5338 if (Py_TYPE(param) != &SchedParamType) {
5339 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5340 return 0;
5341 }
5342 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5343 if (priority == -1 && PyErr_Occurred())
5344 return 0;
5345 if (priority > INT_MAX || priority < INT_MIN) {
5346 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5347 return 0;
5348 }
5349 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5350 return 1;
5351}
Larry Hastings2f936352014-08-05 14:04:04 +10005352#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005353
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005354
5355#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005356/*[clinic input]
5357os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005358
Larry Hastings2f936352014-08-05 14:04:04 +10005359 pid: pid_t
5360 policy: int
5361 param: sched_param
5362 /
5363
5364Set the scheduling policy for the process identified by pid.
5365
5366If pid is 0, the calling process is changed.
5367param is an instance of sched_param.
5368[clinic start generated code]*/
5369
Larry Hastings2f936352014-08-05 14:04:04 +10005370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005371os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005372 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005373/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005374{
Jesus Cea9c822272011-09-10 01:40:52 +02005375 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005376 ** sched_setscheduler() returns 0 in Linux, but the previous
5377 ** scheduling policy under Solaris/Illumos, and others.
5378 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005379 */
Larry Hastings2f936352014-08-05 14:04:04 +10005380 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005381 return posix_error();
5382 Py_RETURN_NONE;
5383}
Larry Hastings2f936352014-08-05 14:04:04 +10005384#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005385
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005386
5387#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005388/*[clinic input]
5389os.sched_getparam
5390 pid: pid_t
5391 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005392
Larry Hastings2f936352014-08-05 14:04:04 +10005393Returns scheduling parameters for the process identified by pid.
5394
5395If pid is 0, returns parameters for the calling process.
5396Return value is an instance of sched_param.
5397[clinic start generated code]*/
5398
Larry Hastings2f936352014-08-05 14:04:04 +10005399static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005400os_sched_getparam_impl(PyObject *module, pid_t pid)
5401/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005402{
5403 struct sched_param param;
5404 PyObject *result;
5405 PyObject *priority;
5406
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005407 if (sched_getparam(pid, &param))
5408 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005409 result = PyStructSequence_New(&SchedParamType);
5410 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005411 return NULL;
5412 priority = PyLong_FromLong(param.sched_priority);
5413 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005414 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005415 return NULL;
5416 }
Larry Hastings2f936352014-08-05 14:04:04 +10005417 PyStructSequence_SET_ITEM(result, 0, priority);
5418 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005419}
5420
Larry Hastings2f936352014-08-05 14:04:04 +10005421
5422/*[clinic input]
5423os.sched_setparam
5424 pid: pid_t
5425 param: sched_param
5426 /
5427
5428Set scheduling parameters for the process identified by pid.
5429
5430If pid is 0, sets parameters for the calling process.
5431param should be an instance of sched_param.
5432[clinic start generated code]*/
5433
Larry Hastings2f936352014-08-05 14:04:04 +10005434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005435os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005436 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005437/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005438{
5439 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005440 return posix_error();
5441 Py_RETURN_NONE;
5442}
Larry Hastings2f936352014-08-05 14:04:04 +10005443#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005444
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005445
5446#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005447/*[clinic input]
5448os.sched_rr_get_interval -> double
5449 pid: pid_t
5450 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005451
Larry Hastings2f936352014-08-05 14:04:04 +10005452Return the round-robin quantum for the process identified by pid, in seconds.
5453
5454Value returned is a float.
5455[clinic start generated code]*/
5456
Larry Hastings2f936352014-08-05 14:04:04 +10005457static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005458os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5459/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005460{
5461 struct timespec interval;
5462 if (sched_rr_get_interval(pid, &interval)) {
5463 posix_error();
5464 return -1.0;
5465 }
5466 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5467}
5468#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005469
Larry Hastings2f936352014-08-05 14:04:04 +10005470
5471/*[clinic input]
5472os.sched_yield
5473
5474Voluntarily relinquish the CPU.
5475[clinic start generated code]*/
5476
Larry Hastings2f936352014-08-05 14:04:04 +10005477static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005478os_sched_yield_impl(PyObject *module)
5479/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005480{
5481 if (sched_yield())
5482 return posix_error();
5483 Py_RETURN_NONE;
5484}
5485
Benjamin Peterson2740af82011-08-02 17:41:34 -05005486#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005487/* The minimum number of CPUs allocated in a cpu_set_t */
5488static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005489
Larry Hastings2f936352014-08-05 14:04:04 +10005490/*[clinic input]
5491os.sched_setaffinity
5492 pid: pid_t
5493 mask : object
5494 /
5495
5496Set the CPU affinity of the process identified by pid to mask.
5497
5498mask should be an iterable of integers identifying CPUs.
5499[clinic start generated code]*/
5500
Larry Hastings2f936352014-08-05 14:04:04 +10005501static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005502os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5503/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005504{
Antoine Pitrou84869872012-08-04 16:16:35 +02005505 int ncpus;
5506 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005507 cpu_set_t *cpu_set = NULL;
5508 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005509
Larry Hastings2f936352014-08-05 14:04:04 +10005510 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005511 if (iterator == NULL)
5512 return NULL;
5513
5514 ncpus = NCPUS_START;
5515 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005516 cpu_set = CPU_ALLOC(ncpus);
5517 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005518 PyErr_NoMemory();
5519 goto error;
5520 }
Larry Hastings2f936352014-08-05 14:04:04 +10005521 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005522
5523 while ((item = PyIter_Next(iterator))) {
5524 long cpu;
5525 if (!PyLong_Check(item)) {
5526 PyErr_Format(PyExc_TypeError,
5527 "expected an iterator of ints, "
5528 "but iterator yielded %R",
5529 Py_TYPE(item));
5530 Py_DECREF(item);
5531 goto error;
5532 }
5533 cpu = PyLong_AsLong(item);
5534 Py_DECREF(item);
5535 if (cpu < 0) {
5536 if (!PyErr_Occurred())
5537 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5538 goto error;
5539 }
5540 if (cpu > INT_MAX - 1) {
5541 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5542 goto error;
5543 }
5544 if (cpu >= ncpus) {
5545 /* Grow CPU mask to fit the CPU number */
5546 int newncpus = ncpus;
5547 cpu_set_t *newmask;
5548 size_t newsetsize;
5549 while (newncpus <= cpu) {
5550 if (newncpus > INT_MAX / 2)
5551 newncpus = cpu + 1;
5552 else
5553 newncpus = newncpus * 2;
5554 }
5555 newmask = CPU_ALLOC(newncpus);
5556 if (newmask == NULL) {
5557 PyErr_NoMemory();
5558 goto error;
5559 }
5560 newsetsize = CPU_ALLOC_SIZE(newncpus);
5561 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005562 memcpy(newmask, cpu_set, setsize);
5563 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005564 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005565 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005566 ncpus = newncpus;
5567 }
Larry Hastings2f936352014-08-05 14:04:04 +10005568 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005569 }
5570 Py_CLEAR(iterator);
5571
Larry Hastings2f936352014-08-05 14:04:04 +10005572 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005573 posix_error();
5574 goto error;
5575 }
Larry Hastings2f936352014-08-05 14:04:04 +10005576 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005577 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005578
5579error:
Larry Hastings2f936352014-08-05 14:04:04 +10005580 if (cpu_set)
5581 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005582 Py_XDECREF(iterator);
5583 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005584}
5585
Larry Hastings2f936352014-08-05 14:04:04 +10005586
5587/*[clinic input]
5588os.sched_getaffinity
5589 pid: pid_t
5590 /
5591
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005592Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005593
5594The affinity is returned as a set of CPU identifiers.
5595[clinic start generated code]*/
5596
Larry Hastings2f936352014-08-05 14:04:04 +10005597static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005598os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005599/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005600{
Antoine Pitrou84869872012-08-04 16:16:35 +02005601 int cpu, ncpus, count;
5602 size_t setsize;
5603 cpu_set_t *mask = NULL;
5604 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005605
Antoine Pitrou84869872012-08-04 16:16:35 +02005606 ncpus = NCPUS_START;
5607 while (1) {
5608 setsize = CPU_ALLOC_SIZE(ncpus);
5609 mask = CPU_ALLOC(ncpus);
5610 if (mask == NULL)
5611 return PyErr_NoMemory();
5612 if (sched_getaffinity(pid, setsize, mask) == 0)
5613 break;
5614 CPU_FREE(mask);
5615 if (errno != EINVAL)
5616 return posix_error();
5617 if (ncpus > INT_MAX / 2) {
5618 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5619 "a large enough CPU set");
5620 return NULL;
5621 }
5622 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005623 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005624
5625 res = PySet_New(NULL);
5626 if (res == NULL)
5627 goto error;
5628 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5629 if (CPU_ISSET_S(cpu, setsize, mask)) {
5630 PyObject *cpu_num = PyLong_FromLong(cpu);
5631 --count;
5632 if (cpu_num == NULL)
5633 goto error;
5634 if (PySet_Add(res, cpu_num)) {
5635 Py_DECREF(cpu_num);
5636 goto error;
5637 }
5638 Py_DECREF(cpu_num);
5639 }
5640 }
5641 CPU_FREE(mask);
5642 return res;
5643
5644error:
5645 if (mask)
5646 CPU_FREE(mask);
5647 Py_XDECREF(res);
5648 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005649}
5650
Benjamin Peterson2740af82011-08-02 17:41:34 -05005651#endif /* HAVE_SCHED_SETAFFINITY */
5652
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005653#endif /* HAVE_SCHED_H */
5654
Larry Hastings2f936352014-08-05 14:04:04 +10005655
Neal Norwitzb59798b2003-03-21 01:43:31 +00005656/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005657/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5658#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005659#define DEV_PTY_FILE "/dev/ptc"
5660#define HAVE_DEV_PTMX
5661#else
5662#define DEV_PTY_FILE "/dev/ptmx"
5663#endif
5664
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005665#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005666#ifdef HAVE_PTY_H
5667#include <pty.h>
5668#else
5669#ifdef HAVE_LIBUTIL_H
5670#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005671#else
5672#ifdef HAVE_UTIL_H
5673#include <util.h>
5674#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005675#endif /* HAVE_LIBUTIL_H */
5676#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005677#ifdef HAVE_STROPTS_H
5678#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005679#endif
5680#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005681
Larry Hastings2f936352014-08-05 14:04:04 +10005682
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005683#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005684/*[clinic input]
5685os.openpty
5686
5687Open a pseudo-terminal.
5688
5689Return a tuple of (master_fd, slave_fd) containing open file descriptors
5690for both the master and slave ends.
5691[clinic start generated code]*/
5692
Larry Hastings2f936352014-08-05 14:04:04 +10005693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005694os_openpty_impl(PyObject *module)
5695/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005696{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005697 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005698#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005699 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005700#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005701#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005702 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005703#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005704 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005705#endif
5706#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005707
Thomas Wouters70c21a12000-07-14 14:28:33 +00005708#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005709 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005710 goto posix_error;
5711
5712 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5713 goto error;
5714 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5715 goto error;
5716
Neal Norwitzb59798b2003-03-21 01:43:31 +00005717#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005718 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5719 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005720 goto posix_error;
5721 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5722 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005723
Victor Stinnerdaf45552013-08-28 00:53:59 +02005724 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005725 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005726 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005727
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005728#else
Victor Stinner000de532013-11-25 23:19:58 +01005729 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005731 goto posix_error;
5732
Victor Stinner8c62be82010-05-06 00:08:46 +00005733 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005734
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 /* change permission of slave */
5736 if (grantpt(master_fd) < 0) {
5737 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005738 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005740
Victor Stinner8c62be82010-05-06 00:08:46 +00005741 /* unlock slave */
5742 if (unlockpt(master_fd) < 0) {
5743 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005744 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005746
Victor Stinner8c62be82010-05-06 00:08:46 +00005747 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005748
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 slave_name = ptsname(master_fd); /* get name of slave */
5750 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005751 goto posix_error;
5752
5753 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005754 if (slave_fd == -1)
5755 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005756
5757 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5758 goto posix_error;
5759
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005760#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005761 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5762 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005763#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005765#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005766#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005767#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005768
Victor Stinner8c62be82010-05-06 00:08:46 +00005769 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005770
Victor Stinnerdaf45552013-08-28 00:53:59 +02005771posix_error:
5772 posix_error();
5773error:
5774 if (master_fd != -1)
5775 close(master_fd);
5776 if (slave_fd != -1)
5777 close(slave_fd);
5778 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005779}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005780#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005781
Larry Hastings2f936352014-08-05 14:04:04 +10005782
Fred Drake8cef4cf2000-06-28 16:40:38 +00005783#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005784/*[clinic input]
5785os.forkpty
5786
5787Fork a new process with a new pseudo-terminal as controlling tty.
5788
5789Returns a tuple of (pid, master_fd).
5790Like fork(), return pid of 0 to the child process,
5791and pid of child to the parent process.
5792To both, return fd of newly opened pseudo-terminal.
5793[clinic start generated code]*/
5794
Larry Hastings2f936352014-08-05 14:04:04 +10005795static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005796os_forkpty_impl(PyObject *module)
5797/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005798{
Victor Stinner8c62be82010-05-06 00:08:46 +00005799 int master_fd = -1, result = 0;
5800 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005801
Victor Stinner8c62be82010-05-06 00:08:46 +00005802 _PyImport_AcquireLock();
5803 pid = forkpty(&master_fd, NULL, NULL, NULL);
5804 if (pid == 0) {
5805 /* child: this clobbers and resets the import lock. */
5806 PyOS_AfterFork();
5807 } else {
5808 /* parent: release the import lock. */
5809 result = _PyImport_ReleaseLock();
5810 }
5811 if (pid == -1)
5812 return posix_error();
5813 if (result < 0) {
5814 /* Don't clobber the OSError if the fork failed. */
5815 PyErr_SetString(PyExc_RuntimeError,
5816 "not holding the import lock");
5817 return NULL;
5818 }
5819 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005820}
Larry Hastings2f936352014-08-05 14:04:04 +10005821#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005822
Ross Lagerwall7807c352011-03-17 20:20:30 +02005823
Guido van Rossumad0ee831995-03-01 10:34:45 +00005824#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005825/*[clinic input]
5826os.getegid
5827
5828Return the current process's effective group id.
5829[clinic start generated code]*/
5830
Larry Hastings2f936352014-08-05 14:04:04 +10005831static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005832os_getegid_impl(PyObject *module)
5833/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005834{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005835 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005836}
Larry Hastings2f936352014-08-05 14:04:04 +10005837#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005839
Guido van Rossumad0ee831995-03-01 10:34:45 +00005840#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005841/*[clinic input]
5842os.geteuid
5843
5844Return the current process's effective user id.
5845[clinic start generated code]*/
5846
Larry Hastings2f936352014-08-05 14:04:04 +10005847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005848os_geteuid_impl(PyObject *module)
5849/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005850{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005851 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005852}
Larry Hastings2f936352014-08-05 14:04:04 +10005853#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005854
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005855
Guido van Rossumad0ee831995-03-01 10:34:45 +00005856#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005857/*[clinic input]
5858os.getgid
5859
5860Return the current process's group id.
5861[clinic start generated code]*/
5862
Larry Hastings2f936352014-08-05 14:04:04 +10005863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005864os_getgid_impl(PyObject *module)
5865/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005866{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005867 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005868}
Larry Hastings2f936352014-08-05 14:04:04 +10005869#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005870
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005871
Larry Hastings2f936352014-08-05 14:04:04 +10005872/*[clinic input]
5873os.getpid
5874
5875Return the current process id.
5876[clinic start generated code]*/
5877
Larry Hastings2f936352014-08-05 14:04:04 +10005878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005879os_getpid_impl(PyObject *module)
5880/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005881{
Victor Stinner8c62be82010-05-06 00:08:46 +00005882 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005883}
5884
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005885#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005886
5887/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005888PyDoc_STRVAR(posix_getgrouplist__doc__,
5889"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5890Returns a list of groups to which a user belongs.\n\n\
5891 user: username to lookup\n\
5892 group: base group id of the user");
5893
5894static PyObject *
5895posix_getgrouplist(PyObject *self, PyObject *args)
5896{
5897#ifdef NGROUPS_MAX
5898#define MAX_GROUPS NGROUPS_MAX
5899#else
5900 /* defined to be 16 on Solaris7, so this should be a small number */
5901#define MAX_GROUPS 64
5902#endif
5903
5904 const char *user;
5905 int i, ngroups;
5906 PyObject *list;
5907#ifdef __APPLE__
5908 int *groups, basegid;
5909#else
5910 gid_t *groups, basegid;
5911#endif
5912 ngroups = MAX_GROUPS;
5913
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005914#ifdef __APPLE__
5915 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005916 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005917#else
5918 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5919 _Py_Gid_Converter, &basegid))
5920 return NULL;
5921#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005922
5923#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005924 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005925#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005926 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005927#endif
5928 if (groups == NULL)
5929 return PyErr_NoMemory();
5930
5931 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5932 PyMem_Del(groups);
5933 return posix_error();
5934 }
5935
5936 list = PyList_New(ngroups);
5937 if (list == NULL) {
5938 PyMem_Del(groups);
5939 return NULL;
5940 }
5941
5942 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005943#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005944 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005945#else
5946 PyObject *o = _PyLong_FromGid(groups[i]);
5947#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005948 if (o == NULL) {
5949 Py_DECREF(list);
5950 PyMem_Del(groups);
5951 return NULL;
5952 }
5953 PyList_SET_ITEM(list, i, o);
5954 }
5955
5956 PyMem_Del(groups);
5957
5958 return list;
5959}
Larry Hastings2f936352014-08-05 14:04:04 +10005960#endif /* HAVE_GETGROUPLIST */
5961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005962
Fred Drakec9680921999-12-13 16:37:25 +00005963#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10005964/*[clinic input]
5965os.getgroups
5966
5967Return list of supplemental group IDs for the process.
5968[clinic start generated code]*/
5969
Larry Hastings2f936352014-08-05 14:04:04 +10005970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005971os_getgroups_impl(PyObject *module)
5972/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00005973{
5974 PyObject *result = NULL;
5975
Fred Drakec9680921999-12-13 16:37:25 +00005976#ifdef NGROUPS_MAX
5977#define MAX_GROUPS NGROUPS_MAX
5978#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005979 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005980#define MAX_GROUPS 64
5981#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005983
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005984 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005985 * This is a helper variable to store the intermediate result when
5986 * that happens.
5987 *
5988 * To keep the code readable the OSX behaviour is unconditional,
5989 * according to the POSIX spec this should be safe on all unix-y
5990 * systems.
5991 */
5992 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005994
Ned Deilyb5dd6d22013-08-01 21:21:15 -07005995#ifdef __APPLE__
5996 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
5997 * there are more groups than can fit in grouplist. Therefore, on OS X
5998 * always first call getgroups with length 0 to get the actual number
5999 * of groups.
6000 */
6001 n = getgroups(0, NULL);
6002 if (n < 0) {
6003 return posix_error();
6004 } else if (n <= MAX_GROUPS) {
6005 /* groups will fit in existing array */
6006 alt_grouplist = grouplist;
6007 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006008 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006009 if (alt_grouplist == NULL) {
6010 errno = EINVAL;
6011 return posix_error();
6012 }
6013 }
6014
6015 n = getgroups(n, alt_grouplist);
6016 if (n == -1) {
6017 if (alt_grouplist != grouplist) {
6018 PyMem_Free(alt_grouplist);
6019 }
6020 return posix_error();
6021 }
6022#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006023 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006024 if (n < 0) {
6025 if (errno == EINVAL) {
6026 n = getgroups(0, NULL);
6027 if (n == -1) {
6028 return posix_error();
6029 }
6030 if (n == 0) {
6031 /* Avoid malloc(0) */
6032 alt_grouplist = grouplist;
6033 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006034 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006035 if (alt_grouplist == NULL) {
6036 errno = EINVAL;
6037 return posix_error();
6038 }
6039 n = getgroups(n, alt_grouplist);
6040 if (n == -1) {
6041 PyMem_Free(alt_grouplist);
6042 return posix_error();
6043 }
6044 }
6045 } else {
6046 return posix_error();
6047 }
6048 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006049#endif
6050
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006051 result = PyList_New(n);
6052 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 int i;
6054 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006055 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006057 Py_DECREF(result);
6058 result = NULL;
6059 break;
Fred Drakec9680921999-12-13 16:37:25 +00006060 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006061 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006062 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006063 }
6064
6065 if (alt_grouplist != grouplist) {
6066 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006067 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006068
Fred Drakec9680921999-12-13 16:37:25 +00006069 return result;
6070}
Larry Hastings2f936352014-08-05 14:04:04 +10006071#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006072
Antoine Pitroub7572f02009-12-02 20:46:48 +00006073#ifdef HAVE_INITGROUPS
6074PyDoc_STRVAR(posix_initgroups__doc__,
6075"initgroups(username, gid) -> None\n\n\
6076Call the system initgroups() to initialize the group access list with all of\n\
6077the groups of which the specified username is a member, plus the specified\n\
6078group id.");
6079
Larry Hastings2f936352014-08-05 14:04:04 +10006080/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006081static PyObject *
6082posix_initgroups(PyObject *self, PyObject *args)
6083{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006084 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006085 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006086 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006087#ifdef __APPLE__
6088 int gid;
6089#else
6090 gid_t gid;
6091#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006092
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006093#ifdef __APPLE__
6094 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6095 PyUnicode_FSConverter, &oname,
6096 &gid))
6097#else
6098 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6099 PyUnicode_FSConverter, &oname,
6100 _Py_Gid_Converter, &gid))
6101#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006102 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006103 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006104
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006105 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006106 Py_DECREF(oname);
6107 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006108 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006109
Victor Stinner8c62be82010-05-06 00:08:46 +00006110 Py_INCREF(Py_None);
6111 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006112}
Larry Hastings2f936352014-08-05 14:04:04 +10006113#endif /* HAVE_INITGROUPS */
6114
Antoine Pitroub7572f02009-12-02 20:46:48 +00006115
Martin v. Löwis606edc12002-06-13 21:09:11 +00006116#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006117/*[clinic input]
6118os.getpgid
6119
6120 pid: pid_t
6121
6122Call the system call getpgid(), and return the result.
6123[clinic start generated code]*/
6124
Larry Hastings2f936352014-08-05 14:04:04 +10006125static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006126os_getpgid_impl(PyObject *module, pid_t pid)
6127/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006128{
6129 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 if (pgid < 0)
6131 return posix_error();
6132 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006133}
6134#endif /* HAVE_GETPGID */
6135
6136
Guido van Rossumb6775db1994-08-01 11:34:53 +00006137#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006138/*[clinic input]
6139os.getpgrp
6140
6141Return the current process group id.
6142[clinic start generated code]*/
6143
Larry Hastings2f936352014-08-05 14:04:04 +10006144static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006145os_getpgrp_impl(PyObject *module)
6146/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006147{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006148#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006150#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006152#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006153}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006154#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006156
Guido van Rossumb6775db1994-08-01 11:34:53 +00006157#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006158/*[clinic input]
6159os.setpgrp
6160
6161Make the current process the leader of its process group.
6162[clinic start generated code]*/
6163
Larry Hastings2f936352014-08-05 14:04:04 +10006164static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006165os_setpgrp_impl(PyObject *module)
6166/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006167{
Guido van Rossum64933891994-10-20 21:56:42 +00006168#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006169 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006170#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006171 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006172#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006173 return posix_error();
6174 Py_INCREF(Py_None);
6175 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006176}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006177#endif /* HAVE_SETPGRP */
6178
Guido van Rossumad0ee831995-03-01 10:34:45 +00006179#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006180
6181#ifdef MS_WINDOWS
6182#include <tlhelp32.h>
6183
6184static PyObject*
6185win32_getppid()
6186{
6187 HANDLE snapshot;
6188 pid_t mypid;
6189 PyObject* result = NULL;
6190 BOOL have_record;
6191 PROCESSENTRY32 pe;
6192
6193 mypid = getpid(); /* This function never fails */
6194
6195 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6196 if (snapshot == INVALID_HANDLE_VALUE)
6197 return PyErr_SetFromWindowsErr(GetLastError());
6198
6199 pe.dwSize = sizeof(pe);
6200 have_record = Process32First(snapshot, &pe);
6201 while (have_record) {
6202 if (mypid == (pid_t)pe.th32ProcessID) {
6203 /* We could cache the ulong value in a static variable. */
6204 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6205 break;
6206 }
6207
6208 have_record = Process32Next(snapshot, &pe);
6209 }
6210
6211 /* If our loop exits and our pid was not found (result will be NULL)
6212 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6213 * error anyway, so let's raise it. */
6214 if (!result)
6215 result = PyErr_SetFromWindowsErr(GetLastError());
6216
6217 CloseHandle(snapshot);
6218
6219 return result;
6220}
6221#endif /*MS_WINDOWS*/
6222
Larry Hastings2f936352014-08-05 14:04:04 +10006223
6224/*[clinic input]
6225os.getppid
6226
6227Return the parent's process id.
6228
6229If the parent process has already exited, Windows machines will still
6230return its id; others systems will return the id of the 'init' process (1).
6231[clinic start generated code]*/
6232
Larry Hastings2f936352014-08-05 14:04:04 +10006233static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006234os_getppid_impl(PyObject *module)
6235/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006236{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006237#ifdef MS_WINDOWS
6238 return win32_getppid();
6239#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006241#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006242}
6243#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006244
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006245
Fred Drake12c6e2d1999-12-14 21:25:03 +00006246#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006247/*[clinic input]
6248os.getlogin
6249
6250Return the actual login name.
6251[clinic start generated code]*/
6252
Larry Hastings2f936352014-08-05 14:04:04 +10006253static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006254os_getlogin_impl(PyObject *module)
6255/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006256{
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006258#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006259 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006260 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006261
6262 if (GetUserNameW(user_name, &num_chars)) {
6263 /* num_chars is the number of unicode chars plus null terminator */
6264 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006265 }
6266 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006267 result = PyErr_SetFromWindowsErr(GetLastError());
6268#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 char *name;
6270 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006271
Victor Stinner8c62be82010-05-06 00:08:46 +00006272 errno = 0;
6273 name = getlogin();
6274 if (name == NULL) {
6275 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006276 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006277 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006278 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 }
6280 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006281 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006283#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006284 return result;
6285}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006286#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006287
Larry Hastings2f936352014-08-05 14:04:04 +10006288
Guido van Rossumad0ee831995-03-01 10:34:45 +00006289#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006290/*[clinic input]
6291os.getuid
6292
6293Return the current process's user id.
6294[clinic start generated code]*/
6295
Larry Hastings2f936352014-08-05 14:04:04 +10006296static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006297os_getuid_impl(PyObject *module)
6298/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006299{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006300 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006301}
Larry Hastings2f936352014-08-05 14:04:04 +10006302#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006303
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006304
Brian Curtineb24d742010-04-12 17:16:38 +00006305#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006306#define HAVE_KILL
6307#endif /* MS_WINDOWS */
6308
6309#ifdef HAVE_KILL
6310/*[clinic input]
6311os.kill
6312
6313 pid: pid_t
6314 signal: Py_ssize_t
6315 /
6316
6317Kill a process with a signal.
6318[clinic start generated code]*/
6319
Larry Hastings2f936352014-08-05 14:04:04 +10006320static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006321os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6322/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006323#ifndef MS_WINDOWS
6324{
6325 if (kill(pid, (int)signal) == -1)
6326 return posix_error();
6327 Py_RETURN_NONE;
6328}
6329#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006330{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006331 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006332 DWORD sig = (DWORD)signal;
6333 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006334 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006335
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 /* Console processes which share a common console can be sent CTRL+C or
6337 CTRL+BREAK events, provided they handle said events. */
6338 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006339 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 err = GetLastError();
6341 PyErr_SetFromWindowsErr(err);
6342 }
6343 else
6344 Py_RETURN_NONE;
6345 }
Brian Curtineb24d742010-04-12 17:16:38 +00006346
Victor Stinner8c62be82010-05-06 00:08:46 +00006347 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6348 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006349 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006350 if (handle == NULL) {
6351 err = GetLastError();
6352 return PyErr_SetFromWindowsErr(err);
6353 }
Brian Curtineb24d742010-04-12 17:16:38 +00006354
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 if (TerminateProcess(handle, sig) == 0) {
6356 err = GetLastError();
6357 result = PyErr_SetFromWindowsErr(err);
6358 } else {
6359 Py_INCREF(Py_None);
6360 result = Py_None;
6361 }
Brian Curtineb24d742010-04-12 17:16:38 +00006362
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 CloseHandle(handle);
6364 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006365}
Larry Hastings2f936352014-08-05 14:04:04 +10006366#endif /* !MS_WINDOWS */
6367#endif /* HAVE_KILL */
6368
6369
6370#ifdef HAVE_KILLPG
6371/*[clinic input]
6372os.killpg
6373
6374 pgid: pid_t
6375 signal: int
6376 /
6377
6378Kill a process group with a signal.
6379[clinic start generated code]*/
6380
Larry Hastings2f936352014-08-05 14:04:04 +10006381static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006382os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6383/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006384{
6385 /* XXX some man pages make the `pgid` parameter an int, others
6386 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6387 take the same type. Moreover, pid_t is always at least as wide as
6388 int (else compilation of this module fails), which is safe. */
6389 if (killpg(pgid, signal) == -1)
6390 return posix_error();
6391 Py_RETURN_NONE;
6392}
6393#endif /* HAVE_KILLPG */
6394
Brian Curtineb24d742010-04-12 17:16:38 +00006395
Guido van Rossumc0125471996-06-28 18:55:32 +00006396#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006397#ifdef HAVE_SYS_LOCK_H
6398#include <sys/lock.h>
6399#endif
6400
Larry Hastings2f936352014-08-05 14:04:04 +10006401/*[clinic input]
6402os.plock
6403 op: int
6404 /
6405
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006406Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006407[clinic start generated code]*/
6408
Larry Hastings2f936352014-08-05 14:04:04 +10006409static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006410os_plock_impl(PyObject *module, int op)
6411/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006412{
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 if (plock(op) == -1)
6414 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006415 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006416}
Larry Hastings2f936352014-08-05 14:04:04 +10006417#endif /* HAVE_PLOCK */
6418
Guido van Rossumc0125471996-06-28 18:55:32 +00006419
Guido van Rossumb6775db1994-08-01 11:34:53 +00006420#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006421/*[clinic input]
6422os.setuid
6423
6424 uid: uid_t
6425 /
6426
6427Set the current process's user id.
6428[clinic start generated code]*/
6429
Larry Hastings2f936352014-08-05 14:04:04 +10006430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006431os_setuid_impl(PyObject *module, uid_t uid)
6432/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006433{
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 if (setuid(uid) < 0)
6435 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006436 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006437}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006438#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006440
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006441#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006442/*[clinic input]
6443os.seteuid
6444
6445 euid: uid_t
6446 /
6447
6448Set the current process's effective user id.
6449[clinic start generated code]*/
6450
Larry Hastings2f936352014-08-05 14:04:04 +10006451static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006452os_seteuid_impl(PyObject *module, uid_t euid)
6453/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006454{
6455 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006457 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006458}
6459#endif /* HAVE_SETEUID */
6460
Larry Hastings2f936352014-08-05 14:04:04 +10006461
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006462#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006463/*[clinic input]
6464os.setegid
6465
6466 egid: gid_t
6467 /
6468
6469Set the current process's effective group id.
6470[clinic start generated code]*/
6471
Larry Hastings2f936352014-08-05 14:04:04 +10006472static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006473os_setegid_impl(PyObject *module, gid_t egid)
6474/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006475{
6476 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006477 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006478 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006479}
6480#endif /* HAVE_SETEGID */
6481
Larry Hastings2f936352014-08-05 14:04:04 +10006482
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006483#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006484/*[clinic input]
6485os.setreuid
6486
6487 ruid: uid_t
6488 euid: uid_t
6489 /
6490
6491Set the current process's real and effective user ids.
6492[clinic start generated code]*/
6493
Larry Hastings2f936352014-08-05 14:04:04 +10006494static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006495os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6496/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006497{
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 if (setreuid(ruid, euid) < 0) {
6499 return posix_error();
6500 } else {
6501 Py_INCREF(Py_None);
6502 return Py_None;
6503 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006504}
6505#endif /* HAVE_SETREUID */
6506
Larry Hastings2f936352014-08-05 14:04:04 +10006507
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006508#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006509/*[clinic input]
6510os.setregid
6511
6512 rgid: gid_t
6513 egid: gid_t
6514 /
6515
6516Set the current process's real and effective group ids.
6517[clinic start generated code]*/
6518
Larry Hastings2f936352014-08-05 14:04:04 +10006519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006520os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6521/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006522{
6523 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006525 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006526}
6527#endif /* HAVE_SETREGID */
6528
Larry Hastings2f936352014-08-05 14:04:04 +10006529
Guido van Rossumb6775db1994-08-01 11:34:53 +00006530#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006531/*[clinic input]
6532os.setgid
6533 gid: gid_t
6534 /
6535
6536Set the current process's group id.
6537[clinic start generated code]*/
6538
Larry Hastings2f936352014-08-05 14:04:04 +10006539static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006540os_setgid_impl(PyObject *module, gid_t gid)
6541/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006542{
Victor Stinner8c62be82010-05-06 00:08:46 +00006543 if (setgid(gid) < 0)
6544 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006545 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006546}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006547#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006548
Larry Hastings2f936352014-08-05 14:04:04 +10006549
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006550#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006551/*[clinic input]
6552os.setgroups
6553
6554 groups: object
6555 /
6556
6557Set the groups of the current process to list.
6558[clinic start generated code]*/
6559
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006561os_setgroups(PyObject *module, PyObject *groups)
6562/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006563{
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 int i, len;
6565 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006566
Victor Stinner8c62be82010-05-06 00:08:46 +00006567 if (!PySequence_Check(groups)) {
6568 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6569 return NULL;
6570 }
6571 len = PySequence_Size(groups);
6572 if (len > MAX_GROUPS) {
6573 PyErr_SetString(PyExc_ValueError, "too many groups");
6574 return NULL;
6575 }
6576 for(i = 0; i < len; i++) {
6577 PyObject *elem;
6578 elem = PySequence_GetItem(groups, i);
6579 if (!elem)
6580 return NULL;
6581 if (!PyLong_Check(elem)) {
6582 PyErr_SetString(PyExc_TypeError,
6583 "groups must be integers");
6584 Py_DECREF(elem);
6585 return NULL;
6586 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006587 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006588 Py_DECREF(elem);
6589 return NULL;
6590 }
6591 }
6592 Py_DECREF(elem);
6593 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006594
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 if (setgroups(len, grouplist) < 0)
6596 return posix_error();
6597 Py_INCREF(Py_None);
6598 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006599}
6600#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006601
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006602#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6603static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006604wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006605{
Victor Stinner8c62be82010-05-06 00:08:46 +00006606 PyObject *result;
6607 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006608 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006609
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 if (pid == -1)
6611 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006612
Victor Stinner8c62be82010-05-06 00:08:46 +00006613 if (struct_rusage == NULL) {
6614 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6615 if (m == NULL)
6616 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006617 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006618 Py_DECREF(m);
6619 if (struct_rusage == NULL)
6620 return NULL;
6621 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006622
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6624 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6625 if (!result)
6626 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006627
6628#ifndef doubletime
6629#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6630#endif
6631
Victor Stinner8c62be82010-05-06 00:08:46 +00006632 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006633 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006634 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006635 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006636#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6638 SET_INT(result, 2, ru->ru_maxrss);
6639 SET_INT(result, 3, ru->ru_ixrss);
6640 SET_INT(result, 4, ru->ru_idrss);
6641 SET_INT(result, 5, ru->ru_isrss);
6642 SET_INT(result, 6, ru->ru_minflt);
6643 SET_INT(result, 7, ru->ru_majflt);
6644 SET_INT(result, 8, ru->ru_nswap);
6645 SET_INT(result, 9, ru->ru_inblock);
6646 SET_INT(result, 10, ru->ru_oublock);
6647 SET_INT(result, 11, ru->ru_msgsnd);
6648 SET_INT(result, 12, ru->ru_msgrcv);
6649 SET_INT(result, 13, ru->ru_nsignals);
6650 SET_INT(result, 14, ru->ru_nvcsw);
6651 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006652#undef SET_INT
6653
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 if (PyErr_Occurred()) {
6655 Py_DECREF(result);
6656 return NULL;
6657 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006658
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006660}
6661#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6662
Larry Hastings2f936352014-08-05 14:04:04 +10006663
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006664#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006665/*[clinic input]
6666os.wait3
6667
6668 options: int
6669Wait for completion of a child process.
6670
6671Returns a tuple of information about the child process:
6672 (pid, status, rusage)
6673[clinic start generated code]*/
6674
Larry Hastings2f936352014-08-05 14:04:04 +10006675static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006676os_wait3_impl(PyObject *module, int options)
6677/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006678{
Victor Stinner8c62be82010-05-06 00:08:46 +00006679 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006681 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 WAIT_TYPE status;
6683 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006685 do {
6686 Py_BEGIN_ALLOW_THREADS
6687 pid = wait3(&status, options, &ru);
6688 Py_END_ALLOW_THREADS
6689 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6690 if (pid < 0)
6691 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006692
Victor Stinner4195b5c2012-02-08 23:03:19 +01006693 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006694}
6695#endif /* HAVE_WAIT3 */
6696
Larry Hastings2f936352014-08-05 14:04:04 +10006697
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006698#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006699/*[clinic input]
6700
6701os.wait4
6702
6703 pid: pid_t
6704 options: int
6705
6706Wait for completion of a specific child process.
6707
6708Returns a tuple of information about the child process:
6709 (pid, status, rusage)
6710[clinic start generated code]*/
6711
Larry Hastings2f936352014-08-05 14:04:04 +10006712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006713os_wait4_impl(PyObject *module, pid_t pid, int options)
6714/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006715{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006716 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006717 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006718 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006719 WAIT_TYPE status;
6720 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006721
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006722 do {
6723 Py_BEGIN_ALLOW_THREADS
6724 res = wait4(pid, &status, options, &ru);
6725 Py_END_ALLOW_THREADS
6726 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6727 if (res < 0)
6728 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006729
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006730 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006731}
6732#endif /* HAVE_WAIT4 */
6733
Larry Hastings2f936352014-08-05 14:04:04 +10006734
Ross Lagerwall7807c352011-03-17 20:20:30 +02006735#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006736/*[clinic input]
6737os.waitid
6738
6739 idtype: idtype_t
6740 Must be one of be P_PID, P_PGID or P_ALL.
6741 id: id_t
6742 The id to wait on.
6743 options: int
6744 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6745 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6746 /
6747
6748Returns the result of waiting for a process or processes.
6749
6750Returns either waitid_result or None if WNOHANG is specified and there are
6751no children in a waitable state.
6752[clinic start generated code]*/
6753
Larry Hastings2f936352014-08-05 14:04:04 +10006754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006755os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6756/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006757{
6758 PyObject *result;
6759 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006760 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006761 siginfo_t si;
6762 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006763
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006764 do {
6765 Py_BEGIN_ALLOW_THREADS
6766 res = waitid(idtype, id, &si, options);
6767 Py_END_ALLOW_THREADS
6768 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6769 if (res < 0)
6770 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006771
6772 if (si.si_pid == 0)
6773 Py_RETURN_NONE;
6774
6775 result = PyStructSequence_New(&WaitidResultType);
6776 if (!result)
6777 return NULL;
6778
6779 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006780 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006781 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6782 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6783 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6784 if (PyErr_Occurred()) {
6785 Py_DECREF(result);
6786 return NULL;
6787 }
6788
6789 return result;
6790}
Larry Hastings2f936352014-08-05 14:04:04 +10006791#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006792
Larry Hastings2f936352014-08-05 14:04:04 +10006793
6794#if defined(HAVE_WAITPID)
6795/*[clinic input]
6796os.waitpid
6797 pid: pid_t
6798 options: int
6799 /
6800
6801Wait for completion of a given child process.
6802
6803Returns a tuple of information regarding the child process:
6804 (pid, status)
6805
6806The options argument is ignored on Windows.
6807[clinic start generated code]*/
6808
Larry Hastings2f936352014-08-05 14:04:04 +10006809static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006810os_waitpid_impl(PyObject *module, pid_t pid, int options)
6811/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006812{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006813 pid_t res;
6814 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006815 WAIT_TYPE status;
6816 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006817
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006818 do {
6819 Py_BEGIN_ALLOW_THREADS
6820 res = waitpid(pid, &status, options);
6821 Py_END_ALLOW_THREADS
6822 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6823 if (res < 0)
6824 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006826 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006827}
Tim Petersab034fa2002-02-01 11:27:43 +00006828#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006829/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006830/*[clinic input]
6831os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006832 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006833 options: int
6834 /
6835
6836Wait for completion of a given process.
6837
6838Returns a tuple of information regarding the process:
6839 (pid, status << 8)
6840
6841The options argument is ignored on Windows.
6842[clinic start generated code]*/
6843
Larry Hastings2f936352014-08-05 14:04:04 +10006844static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006845os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006846/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006847{
6848 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006849 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006850 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006851
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006852 do {
6853 Py_BEGIN_ALLOW_THREADS
6854 res = _cwait(&status, pid, options);
6855 Py_END_ALLOW_THREADS
6856 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006857 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006858 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006859
Victor Stinner8c62be82010-05-06 00:08:46 +00006860 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006861 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006862}
Larry Hastings2f936352014-08-05 14:04:04 +10006863#endif
6864
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006865
Guido van Rossumad0ee831995-03-01 10:34:45 +00006866#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006867/*[clinic input]
6868os.wait
6869
6870Wait for completion of a child process.
6871
6872Returns a tuple of information about the child process:
6873 (pid, status)
6874[clinic start generated code]*/
6875
Larry Hastings2f936352014-08-05 14:04:04 +10006876static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006877os_wait_impl(PyObject *module)
6878/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006879{
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006881 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 WAIT_TYPE status;
6883 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006884
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006885 do {
6886 Py_BEGIN_ALLOW_THREADS
6887 pid = wait(&status);
6888 Py_END_ALLOW_THREADS
6889 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6890 if (pid < 0)
6891 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006894}
Larry Hastings2f936352014-08-05 14:04:04 +10006895#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006896
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006897
Larry Hastings9cf065c2012-06-22 16:30:09 -07006898#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6899PyDoc_STRVAR(readlink__doc__,
6900"readlink(path, *, dir_fd=None) -> path\n\n\
6901Return a string representing the path to which the symbolic link points.\n\
6902\n\
6903If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6904 and path should be relative; path will then be relative to that directory.\n\
6905dir_fd may not be implemented on your platform.\n\
6906 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006907#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006908
Guido van Rossumb6775db1994-08-01 11:34:53 +00006909#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006910
Larry Hastings2f936352014-08-05 14:04:04 +10006911/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006912static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006913posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006914{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006915 path_t path;
6916 int dir_fd = DEFAULT_DIR_FD;
6917 char buffer[MAXPATHLEN];
6918 ssize_t length;
6919 PyObject *return_value = NULL;
6920 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006921
Larry Hastings9cf065c2012-06-22 16:30:09 -07006922 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006923 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006924 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6925 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10006926 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00006927 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006928
Victor Stinner8c62be82010-05-06 00:08:46 +00006929 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006930#ifdef HAVE_READLINKAT
6931 if (dir_fd != DEFAULT_DIR_FD)
6932 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006933 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006934#endif
6935 length = readlink(path.narrow, buffer, sizeof(buffer));
6936 Py_END_ALLOW_THREADS
6937
6938 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006939 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006940 goto exit;
6941 }
6942
6943 if (PyUnicode_Check(path.object))
6944 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6945 else
6946 return_value = PyBytes_FromStringAndSize(buffer, length);
6947exit:
6948 path_cleanup(&path);
6949 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006950}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006951
Guido van Rossumb6775db1994-08-01 11:34:53 +00006952#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006953
Larry Hastings2f936352014-08-05 14:04:04 +10006954#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6955
6956static PyObject *
6957win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
6958{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006959 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10006960 DWORD n_bytes_returned;
6961 DWORD io_result;
6962 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006963 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10006964 HANDLE reparse_point_handle;
6965
Martin Panter70214ad2016-08-04 02:38:59 +00006966 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6967 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006968 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10006969
6970 static char *keywords[] = {"path", "dir_fd", NULL};
6971
6972 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6973 &po,
6974 dir_fd_unavailable, &dir_fd
6975 ))
6976 return NULL;
6977
6978 path = PyUnicode_AsUnicode(po);
6979 if (path == NULL)
6980 return NULL;
6981
6982 /* First get a handle to the reparse point */
6983 Py_BEGIN_ALLOW_THREADS
6984 reparse_point_handle = CreateFileW(
6985 path,
6986 0,
6987 0,
6988 0,
6989 OPEN_EXISTING,
6990 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6991 0);
6992 Py_END_ALLOW_THREADS
6993
6994 if (reparse_point_handle==INVALID_HANDLE_VALUE)
6995 return win32_error_object("readlink", po);
6996
6997 Py_BEGIN_ALLOW_THREADS
6998 /* New call DeviceIoControl to read the reparse point */
6999 io_result = DeviceIoControl(
7000 reparse_point_handle,
7001 FSCTL_GET_REPARSE_POINT,
7002 0, 0, /* in buffer */
7003 target_buffer, sizeof(target_buffer),
7004 &n_bytes_returned,
7005 0 /* we're not using OVERLAPPED_IO */
7006 );
7007 CloseHandle(reparse_point_handle);
7008 Py_END_ALLOW_THREADS
7009
7010 if (io_result==0)
7011 return win32_error_object("readlink", po);
7012
7013 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7014 {
7015 PyErr_SetString(PyExc_ValueError,
7016 "not a symbolic link");
7017 return NULL;
7018 }
7019 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7020 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7021
7022 result = PyUnicode_FromWideChar(print_name,
7023 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7024 return result;
7025}
7026
7027#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7028
7029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007030
Larry Hastings9cf065c2012-06-22 16:30:09 -07007031#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007032
7033#if defined(MS_WINDOWS)
7034
7035/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007036static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007037
Larry Hastings9cf065c2012-06-22 16:30:09 -07007038static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007039check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007040{
7041 HINSTANCE hKernel32;
7042 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007043 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007044 return 1;
7045 hKernel32 = GetModuleHandleW(L"KERNEL32");
7046 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7047 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007048 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007049}
7050
Victor Stinner31b3b922013-06-05 01:49:17 +02007051/* Remove the last portion of the path */
7052static void
7053_dirnameW(WCHAR *path)
7054{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007055 WCHAR *ptr;
7056
7057 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007058 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007059 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007060 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007061 }
7062 *ptr = 0;
7063}
7064
Victor Stinner31b3b922013-06-05 01:49:17 +02007065/* Is this path absolute? */
7066static int
7067_is_absW(const WCHAR *path)
7068{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007069 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7070
7071}
7072
Victor Stinner31b3b922013-06-05 01:49:17 +02007073/* join root and rest with a backslash */
7074static void
7075_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7076{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007077 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007078
Victor Stinner31b3b922013-06-05 01:49:17 +02007079 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007080 wcscpy(dest_path, rest);
7081 return;
7082 }
7083
7084 root_len = wcslen(root);
7085
7086 wcscpy(dest_path, root);
7087 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007088 dest_path[root_len] = L'\\';
7089 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007090 }
7091 wcscpy(dest_path+root_len, rest);
7092}
7093
Victor Stinner31b3b922013-06-05 01:49:17 +02007094/* Return True if the path at src relative to dest is a directory */
7095static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007096_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007097{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007098 WIN32_FILE_ATTRIBUTE_DATA src_info;
7099 WCHAR dest_parent[MAX_PATH];
7100 WCHAR src_resolved[MAX_PATH] = L"";
7101
7102 /* dest_parent = os.path.dirname(dest) */
7103 wcscpy(dest_parent, dest);
7104 _dirnameW(dest_parent);
7105 /* src_resolved = os.path.join(dest_parent, src) */
7106 _joinW(src_resolved, dest_parent, src);
7107 return (
7108 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7109 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7110 );
7111}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007112#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007113
Larry Hastings2f936352014-08-05 14:04:04 +10007114
7115/*[clinic input]
7116os.symlink
7117 src: path_t
7118 dst: path_t
7119 target_is_directory: bool = False
7120 *
7121 dir_fd: dir_fd(requires='symlinkat')=None
7122
7123# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7124
7125Create a symbolic link pointing to src named dst.
7126
7127target_is_directory is required on Windows if the target is to be
7128 interpreted as a directory. (On Windows, symlink requires
7129 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7130 target_is_directory is ignored on non-Windows platforms.
7131
7132If dir_fd is not None, it should be a file descriptor open to a directory,
7133 and path should be relative; path will then be relative to that directory.
7134dir_fd may not be implemented on your platform.
7135 If it is unavailable, using it will raise a NotImplementedError.
7136
7137[clinic start generated code]*/
7138
Larry Hastings2f936352014-08-05 14:04:04 +10007139static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007140os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007141 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007142/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007143{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007144#ifdef MS_WINDOWS
7145 DWORD result;
7146#else
7147 int result;
7148#endif
7149
Larry Hastings9cf065c2012-06-22 16:30:09 -07007150#ifdef MS_WINDOWS
7151 if (!check_CreateSymbolicLink()) {
7152 PyErr_SetString(PyExc_NotImplementedError,
7153 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007154 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007155 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007156 if (!win32_can_symlink) {
7157 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007158 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007159 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160#endif
7161
Larry Hastings2f936352014-08-05 14:04:04 +10007162 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007163 PyErr_SetString(PyExc_ValueError,
7164 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007165 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007166 }
7167
7168#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007169
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007171 /* if src is a directory, ensure target_is_directory==1 */
7172 target_is_directory |= _check_dirW(src->wide, dst->wide);
7173 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7174 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007175 Py_END_ALLOW_THREADS
7176
Larry Hastings2f936352014-08-05 14:04:04 +10007177 if (!result)
7178 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007179
7180#else
7181
7182 Py_BEGIN_ALLOW_THREADS
7183#if HAVE_SYMLINKAT
7184 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007185 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007186 else
7187#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007188 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007189 Py_END_ALLOW_THREADS
7190
Larry Hastings2f936352014-08-05 14:04:04 +10007191 if (result)
7192 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007193#endif
7194
Larry Hastings2f936352014-08-05 14:04:04 +10007195 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007196}
7197#endif /* HAVE_SYMLINK */
7198
Larry Hastings9cf065c2012-06-22 16:30:09 -07007199
Brian Curtind40e6f72010-07-08 21:39:08 +00007200
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007201
Larry Hastings605a62d2012-06-24 04:33:36 -07007202static PyStructSequence_Field times_result_fields[] = {
7203 {"user", "user time"},
7204 {"system", "system time"},
7205 {"children_user", "user time of children"},
7206 {"children_system", "system time of children"},
7207 {"elapsed", "elapsed time since an arbitrary point in the past"},
7208 {NULL}
7209};
7210
7211PyDoc_STRVAR(times_result__doc__,
7212"times_result: Result from os.times().\n\n\
7213This object may be accessed either as a tuple of\n\
7214 (user, system, children_user, children_system, elapsed),\n\
7215or via the attributes user, system, children_user, children_system,\n\
7216and elapsed.\n\
7217\n\
7218See os.times for more information.");
7219
7220static PyStructSequence_Desc times_result_desc = {
7221 "times_result", /* name */
7222 times_result__doc__, /* doc */
7223 times_result_fields,
7224 5
7225};
7226
7227static PyTypeObject TimesResultType;
7228
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007229#ifdef MS_WINDOWS
7230#define HAVE_TIMES /* mandatory, for the method table */
7231#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007232
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007233#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007234
7235static PyObject *
7236build_times_result(double user, double system,
7237 double children_user, double children_system,
7238 double elapsed)
7239{
7240 PyObject *value = PyStructSequence_New(&TimesResultType);
7241 if (value == NULL)
7242 return NULL;
7243
7244#define SET(i, field) \
7245 { \
7246 PyObject *o = PyFloat_FromDouble(field); \
7247 if (!o) { \
7248 Py_DECREF(value); \
7249 return NULL; \
7250 } \
7251 PyStructSequence_SET_ITEM(value, i, o); \
7252 } \
7253
7254 SET(0, user);
7255 SET(1, system);
7256 SET(2, children_user);
7257 SET(3, children_system);
7258 SET(4, elapsed);
7259
7260#undef SET
7261
7262 return value;
7263}
7264
Larry Hastings605a62d2012-06-24 04:33:36 -07007265
Larry Hastings2f936352014-08-05 14:04:04 +10007266#ifndef MS_WINDOWS
7267#define NEED_TICKS_PER_SECOND
7268static long ticks_per_second = -1;
7269#endif /* MS_WINDOWS */
7270
7271/*[clinic input]
7272os.times
7273
7274Return a collection containing process timing information.
7275
7276The object returned behaves like a named tuple with these fields:
7277 (utime, stime, cutime, cstime, elapsed_time)
7278All fields are floating point numbers.
7279[clinic start generated code]*/
7280
Larry Hastings2f936352014-08-05 14:04:04 +10007281static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007282os_times_impl(PyObject *module)
7283/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007284#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007285{
Victor Stinner8c62be82010-05-06 00:08:46 +00007286 FILETIME create, exit, kernel, user;
7287 HANDLE hProc;
7288 hProc = GetCurrentProcess();
7289 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7290 /* The fields of a FILETIME structure are the hi and lo part
7291 of a 64-bit value expressed in 100 nanosecond units.
7292 1e7 is one second in such units; 1e-7 the inverse.
7293 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7294 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007295 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007296 (double)(user.dwHighDateTime*429.4967296 +
7297 user.dwLowDateTime*1e-7),
7298 (double)(kernel.dwHighDateTime*429.4967296 +
7299 kernel.dwLowDateTime*1e-7),
7300 (double)0,
7301 (double)0,
7302 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007303}
Larry Hastings2f936352014-08-05 14:04:04 +10007304#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007305{
Larry Hastings2f936352014-08-05 14:04:04 +10007306
7307
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007308 struct tms t;
7309 clock_t c;
7310 errno = 0;
7311 c = times(&t);
7312 if (c == (clock_t) -1)
7313 return posix_error();
7314 return build_times_result(
7315 (double)t.tms_utime / ticks_per_second,
7316 (double)t.tms_stime / ticks_per_second,
7317 (double)t.tms_cutime / ticks_per_second,
7318 (double)t.tms_cstime / ticks_per_second,
7319 (double)c / ticks_per_second);
7320}
Larry Hastings2f936352014-08-05 14:04:04 +10007321#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007322#endif /* HAVE_TIMES */
7323
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007324
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007325#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007326/*[clinic input]
7327os.getsid
7328
7329 pid: pid_t
7330 /
7331
7332Call the system call getsid(pid) and return the result.
7333[clinic start generated code]*/
7334
Larry Hastings2f936352014-08-05 14:04:04 +10007335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007336os_getsid_impl(PyObject *module, pid_t pid)
7337/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007338{
Victor Stinner8c62be82010-05-06 00:08:46 +00007339 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007340 sid = getsid(pid);
7341 if (sid < 0)
7342 return posix_error();
7343 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007344}
7345#endif /* HAVE_GETSID */
7346
7347
Guido van Rossumb6775db1994-08-01 11:34:53 +00007348#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007349/*[clinic input]
7350os.setsid
7351
7352Call the system call setsid().
7353[clinic start generated code]*/
7354
Larry Hastings2f936352014-08-05 14:04:04 +10007355static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007356os_setsid_impl(PyObject *module)
7357/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007358{
Victor Stinner8c62be82010-05-06 00:08:46 +00007359 if (setsid() < 0)
7360 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007361 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007362}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007363#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007364
Larry Hastings2f936352014-08-05 14:04:04 +10007365
Guido van Rossumb6775db1994-08-01 11:34:53 +00007366#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007367/*[clinic input]
7368os.setpgid
7369
7370 pid: pid_t
7371 pgrp: pid_t
7372 /
7373
7374Call the system call setpgid(pid, pgrp).
7375[clinic start generated code]*/
7376
Larry Hastings2f936352014-08-05 14:04:04 +10007377static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007378os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7379/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007380{
Victor Stinner8c62be82010-05-06 00:08:46 +00007381 if (setpgid(pid, pgrp) < 0)
7382 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007383 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007384}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007385#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007387
Guido van Rossumb6775db1994-08-01 11:34:53 +00007388#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007389/*[clinic input]
7390os.tcgetpgrp
7391
7392 fd: int
7393 /
7394
7395Return the process group associated with the terminal specified by fd.
7396[clinic start generated code]*/
7397
Larry Hastings2f936352014-08-05 14:04:04 +10007398static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007399os_tcgetpgrp_impl(PyObject *module, int fd)
7400/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007401{
7402 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007403 if (pgid < 0)
7404 return posix_error();
7405 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007406}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007407#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007409
Guido van Rossumb6775db1994-08-01 11:34:53 +00007410#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007411/*[clinic input]
7412os.tcsetpgrp
7413
7414 fd: int
7415 pgid: pid_t
7416 /
7417
7418Set the process group associated with the terminal specified by fd.
7419[clinic start generated code]*/
7420
Larry Hastings2f936352014-08-05 14:04:04 +10007421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007422os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7423/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007424{
Victor Stinner8c62be82010-05-06 00:08:46 +00007425 if (tcsetpgrp(fd, pgid) < 0)
7426 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007427 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007428}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007429#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007430
Guido van Rossum687dd131993-05-17 08:34:16 +00007431/* Functions acting on file descriptors */
7432
Victor Stinnerdaf45552013-08-28 00:53:59 +02007433#ifdef O_CLOEXEC
7434extern int _Py_open_cloexec_works;
7435#endif
7436
Larry Hastings2f936352014-08-05 14:04:04 +10007437
7438/*[clinic input]
7439os.open -> int
7440 path: path_t
7441 flags: int
7442 mode: int = 0o777
7443 *
7444 dir_fd: dir_fd(requires='openat') = None
7445
7446# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7447
7448Open a file for low level IO. Returns a file descriptor (integer).
7449
7450If dir_fd is not None, it should be a file descriptor open to a directory,
7451 and path should be relative; path will then be relative to that directory.
7452dir_fd may not be implemented on your platform.
7453 If it is unavailable, using it will raise a NotImplementedError.
7454[clinic start generated code]*/
7455
Larry Hastings2f936352014-08-05 14:04:04 +10007456static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007457os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7458/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007459{
7460 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007461 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007462
Victor Stinnerdaf45552013-08-28 00:53:59 +02007463#ifdef O_CLOEXEC
7464 int *atomic_flag_works = &_Py_open_cloexec_works;
7465#elif !defined(MS_WINDOWS)
7466 int *atomic_flag_works = NULL;
7467#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007468
Victor Stinnerdaf45552013-08-28 00:53:59 +02007469#ifdef MS_WINDOWS
7470 flags |= O_NOINHERIT;
7471#elif defined(O_CLOEXEC)
7472 flags |= O_CLOEXEC;
7473#endif
7474
Steve Dower8fc89802015-04-12 00:26:27 -04007475 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007476 do {
7477 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007478#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007479 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007480#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007481#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007482 if (dir_fd != DEFAULT_DIR_FD)
7483 fd = openat(dir_fd, path->narrow, flags, mode);
7484 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007485#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007486 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007487#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007488 Py_END_ALLOW_THREADS
7489 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007490 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007491
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007492 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007493 if (!async_err)
7494 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007495 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007496 }
7497
Victor Stinnerdaf45552013-08-28 00:53:59 +02007498#ifndef MS_WINDOWS
7499 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7500 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007501 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007502 }
7503#endif
7504
Larry Hastings2f936352014-08-05 14:04:04 +10007505 return fd;
7506}
7507
7508
7509/*[clinic input]
7510os.close
7511
7512 fd: int
7513
7514Close a file descriptor.
7515[clinic start generated code]*/
7516
Barry Warsaw53699e91996-12-10 23:23:01 +00007517static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007518os_close_impl(PyObject *module, int fd)
7519/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007520{
Larry Hastings2f936352014-08-05 14:04:04 +10007521 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007522 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7523 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7524 * for more details.
7525 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007527 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007528 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007529 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 Py_END_ALLOW_THREADS
7531 if (res < 0)
7532 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007533 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007534}
7535
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007536
Larry Hastings2f936352014-08-05 14:04:04 +10007537/*[clinic input]
7538os.closerange
7539
7540 fd_low: int
7541 fd_high: int
7542 /
7543
7544Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7545[clinic start generated code]*/
7546
Larry Hastings2f936352014-08-05 14:04:04 +10007547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007548os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7549/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007550{
7551 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007553 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007554 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007555 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007556 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007557 Py_END_ALLOW_THREADS
7558 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007559}
7560
7561
Larry Hastings2f936352014-08-05 14:04:04 +10007562/*[clinic input]
7563os.dup -> int
7564
7565 fd: int
7566 /
7567
7568Return a duplicate of a file descriptor.
7569[clinic start generated code]*/
7570
Larry Hastings2f936352014-08-05 14:04:04 +10007571static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007572os_dup_impl(PyObject *module, int fd)
7573/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007574{
7575 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007576}
7577
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007578
Larry Hastings2f936352014-08-05 14:04:04 +10007579/*[clinic input]
7580os.dup2
7581 fd: int
7582 fd2: int
7583 inheritable: bool=True
7584
7585Duplicate file descriptor.
7586[clinic start generated code]*/
7587
Larry Hastings2f936352014-08-05 14:04:04 +10007588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007589os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7590/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007591{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007592 int res;
7593#if defined(HAVE_DUP3) && \
7594 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7595 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7596 int dup3_works = -1;
7597#endif
7598
Steve Dower940f33a2016-09-08 11:21:54 -07007599 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007600 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007601
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007602 /* dup2() can fail with EINTR if the target FD is already open, because it
7603 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7604 * upon close(), and therefore below.
7605 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007606#ifdef MS_WINDOWS
7607 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007608 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007610 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007611 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007612 if (res < 0)
7613 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007614
7615 /* Character files like console cannot be make non-inheritable */
7616 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7617 close(fd2);
7618 return NULL;
7619 }
7620
7621#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7622 Py_BEGIN_ALLOW_THREADS
7623 if (!inheritable)
7624 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7625 else
7626 res = dup2(fd, fd2);
7627 Py_END_ALLOW_THREADS
7628 if (res < 0)
7629 return posix_error();
7630
7631#else
7632
7633#ifdef HAVE_DUP3
7634 if (!inheritable && dup3_works != 0) {
7635 Py_BEGIN_ALLOW_THREADS
7636 res = dup3(fd, fd2, O_CLOEXEC);
7637 Py_END_ALLOW_THREADS
7638 if (res < 0) {
7639 if (dup3_works == -1)
7640 dup3_works = (errno != ENOSYS);
7641 if (dup3_works)
7642 return posix_error();
7643 }
7644 }
7645
7646 if (inheritable || dup3_works == 0)
7647 {
7648#endif
7649 Py_BEGIN_ALLOW_THREADS
7650 res = dup2(fd, fd2);
7651 Py_END_ALLOW_THREADS
7652 if (res < 0)
7653 return posix_error();
7654
7655 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7656 close(fd2);
7657 return NULL;
7658 }
7659#ifdef HAVE_DUP3
7660 }
7661#endif
7662
7663#endif
7664
Larry Hastings2f936352014-08-05 14:04:04 +10007665 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007666}
7667
Larry Hastings2f936352014-08-05 14:04:04 +10007668
Ross Lagerwall7807c352011-03-17 20:20:30 +02007669#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007670/*[clinic input]
7671os.lockf
7672
7673 fd: int
7674 An open file descriptor.
7675 command: int
7676 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7677 length: Py_off_t
7678 The number of bytes to lock, starting at the current position.
7679 /
7680
7681Apply, test or remove a POSIX lock on an open file descriptor.
7682
7683[clinic start generated code]*/
7684
Larry Hastings2f936352014-08-05 14:04:04 +10007685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007686os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7687/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007688{
7689 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007690
7691 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007692 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007693 Py_END_ALLOW_THREADS
7694
7695 if (res < 0)
7696 return posix_error();
7697
7698 Py_RETURN_NONE;
7699}
Larry Hastings2f936352014-08-05 14:04:04 +10007700#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007701
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007702
Larry Hastings2f936352014-08-05 14:04:04 +10007703/*[clinic input]
7704os.lseek -> Py_off_t
7705
7706 fd: int
7707 position: Py_off_t
7708 how: int
7709 /
7710
7711Set the position of a file descriptor. Return the new position.
7712
7713Return the new cursor position in number of bytes
7714relative to the beginning of the file.
7715[clinic start generated code]*/
7716
Larry Hastings2f936352014-08-05 14:04:04 +10007717static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007718os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7719/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007720{
7721 Py_off_t result;
7722
Guido van Rossum687dd131993-05-17 08:34:16 +00007723#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007724 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7725 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007726 case 0: how = SEEK_SET; break;
7727 case 1: how = SEEK_CUR; break;
7728 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007729 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007730#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007731
Victor Stinner8c62be82010-05-06 00:08:46 +00007732 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007733 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007734
Victor Stinner8c62be82010-05-06 00:08:46 +00007735 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007736 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007737#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007738 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007739#else
Larry Hastings2f936352014-08-05 14:04:04 +10007740 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007741#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007742 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007743 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007744 if (result < 0)
7745 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007746
Larry Hastings2f936352014-08-05 14:04:04 +10007747 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007748}
7749
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007750
Larry Hastings2f936352014-08-05 14:04:04 +10007751/*[clinic input]
7752os.read
7753 fd: int
7754 length: Py_ssize_t
7755 /
7756
7757Read from a file descriptor. Returns a bytes object.
7758[clinic start generated code]*/
7759
Larry Hastings2f936352014-08-05 14:04:04 +10007760static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007761os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7762/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007763{
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 Py_ssize_t n;
7765 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007766
7767 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 errno = EINVAL;
7769 return posix_error();
7770 }
Larry Hastings2f936352014-08-05 14:04:04 +10007771
7772#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007773 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007774 if (length > INT_MAX)
7775 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007776#endif
7777
7778 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 if (buffer == NULL)
7780 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007781
Victor Stinner66aab0c2015-03-19 22:53:20 +01007782 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7783 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007785 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 }
Larry Hastings2f936352014-08-05 14:04:04 +10007787
7788 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007790
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007792}
7793
Ross Lagerwall7807c352011-03-17 20:20:30 +02007794#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7795 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007796static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007797iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7798{
7799 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007800 Py_ssize_t blen, total = 0;
7801
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007802 *iov = PyMem_New(struct iovec, cnt);
7803 if (*iov == NULL) {
7804 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007805 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007806 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007807
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007808 *buf = PyMem_New(Py_buffer, cnt);
7809 if (*buf == NULL) {
7810 PyMem_Del(*iov);
7811 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007812 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007813 }
7814
7815 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007816 PyObject *item = PySequence_GetItem(seq, i);
7817 if (item == NULL)
7818 goto fail;
7819 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7820 Py_DECREF(item);
7821 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007822 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007823 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007824 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007825 blen = (*buf)[i].len;
7826 (*iov)[i].iov_len = blen;
7827 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007828 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007829 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007830
7831fail:
7832 PyMem_Del(*iov);
7833 for (j = 0; j < i; j++) {
7834 PyBuffer_Release(&(*buf)[j]);
7835 }
7836 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007837 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007838}
7839
7840static void
7841iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7842{
7843 int i;
7844 PyMem_Del(iov);
7845 for (i = 0; i < cnt; i++) {
7846 PyBuffer_Release(&buf[i]);
7847 }
7848 PyMem_Del(buf);
7849}
7850#endif
7851
Larry Hastings2f936352014-08-05 14:04:04 +10007852
Ross Lagerwall7807c352011-03-17 20:20:30 +02007853#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007854/*[clinic input]
7855os.readv -> Py_ssize_t
7856
7857 fd: int
7858 buffers: object
7859 /
7860
7861Read from a file descriptor fd into an iterable of buffers.
7862
7863The buffers should be mutable buffers accepting bytes.
7864readv will transfer data into each buffer until it is full
7865and then move on to the next buffer in the sequence to hold
7866the rest of the data.
7867
7868readv returns the total number of bytes read,
7869which may be less than the total capacity of all the buffers.
7870[clinic start generated code]*/
7871
Larry Hastings2f936352014-08-05 14:04:04 +10007872static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007873os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7874/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007875{
7876 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007877 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007878 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007879 struct iovec *iov;
7880 Py_buffer *buf;
7881
Larry Hastings2f936352014-08-05 14:04:04 +10007882 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007883 PyErr_SetString(PyExc_TypeError,
7884 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007885 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007886 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007887
Larry Hastings2f936352014-08-05 14:04:04 +10007888 cnt = PySequence_Size(buffers);
7889
7890 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7891 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007892
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007893 do {
7894 Py_BEGIN_ALLOW_THREADS
7895 n = readv(fd, iov, cnt);
7896 Py_END_ALLOW_THREADS
7897 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007898
7899 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007900 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007901 if (!async_err)
7902 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007903 return -1;
7904 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007905
Larry Hastings2f936352014-08-05 14:04:04 +10007906 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007907}
Larry Hastings2f936352014-08-05 14:04:04 +10007908#endif /* HAVE_READV */
7909
Ross Lagerwall7807c352011-03-17 20:20:30 +02007910
7911#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007912/*[clinic input]
7913# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7914os.pread
7915
7916 fd: int
7917 length: int
7918 offset: Py_off_t
7919 /
7920
7921Read a number of bytes from a file descriptor starting at a particular offset.
7922
7923Read length bytes from file descriptor fd, starting at offset bytes from
7924the beginning of the file. The file offset remains unchanged.
7925[clinic start generated code]*/
7926
Larry Hastings2f936352014-08-05 14:04:04 +10007927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007928os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
7929/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007930{
Ross Lagerwall7807c352011-03-17 20:20:30 +02007931 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007932 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007934
Larry Hastings2f936352014-08-05 14:04:04 +10007935 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007936 errno = EINVAL;
7937 return posix_error();
7938 }
Larry Hastings2f936352014-08-05 14:04:04 +10007939 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940 if (buffer == NULL)
7941 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007942
7943 do {
7944 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007945 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007946 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04007947 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007948 Py_END_ALLOW_THREADS
7949 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7950
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951 if (n < 0) {
7952 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007953 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007954 }
Larry Hastings2f936352014-08-05 14:04:04 +10007955 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007956 _PyBytes_Resize(&buffer, n);
7957 return buffer;
7958}
Larry Hastings2f936352014-08-05 14:04:04 +10007959#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007960
Larry Hastings2f936352014-08-05 14:04:04 +10007961
7962/*[clinic input]
7963os.write -> Py_ssize_t
7964
7965 fd: int
7966 data: Py_buffer
7967 /
7968
7969Write a bytes object to a file descriptor.
7970[clinic start generated code]*/
7971
Larry Hastings2f936352014-08-05 14:04:04 +10007972static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007973os_write_impl(PyObject *module, int fd, Py_buffer *data)
7974/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007975{
Victor Stinner66aab0c2015-03-19 22:53:20 +01007976 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007977}
7978
7979#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007980PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00007981"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00007982sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007983 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00007984Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007985
Larry Hastings2f936352014-08-05 14:04:04 +10007986/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007987static PyObject *
7988posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7989{
7990 int in, out;
7991 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007992 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007993 off_t offset;
7994
7995#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
7996#ifndef __APPLE__
7997 Py_ssize_t len;
7998#endif
7999 PyObject *headers = NULL, *trailers = NULL;
8000 Py_buffer *hbuf, *tbuf;
8001 off_t sbytes;
8002 struct sf_hdtr sf;
8003 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008004 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008005 static char *keywords[] = {"out", "in",
8006 "offset", "count",
8007 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008008
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008009 sf.headers = NULL;
8010 sf.trailers = NULL;
8011
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012#ifdef __APPLE__
8013 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008014 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008015#else
8016 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008017 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008018#endif
8019 &headers, &trailers, &flags))
8020 return NULL;
8021 if (headers != NULL) {
8022 if (!PySequence_Check(headers)) {
8023 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008024 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025 return NULL;
8026 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008027 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008028 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008029 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008030 (i = iov_setup(&(sf.headers), &hbuf,
8031 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008033#ifdef __APPLE__
8034 sbytes += i;
8035#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008036 }
8037 }
8038 if (trailers != NULL) {
8039 if (!PySequence_Check(trailers)) {
8040 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008041 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008042 return NULL;
8043 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008044 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008045 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008046 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008047 (i = iov_setup(&(sf.trailers), &tbuf,
8048 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008049 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008050#ifdef __APPLE__
8051 sbytes += i;
8052#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053 }
8054 }
8055
Steve Dower8fc89802015-04-12 00:26:27 -04008056 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008057 do {
8058 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008060 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008062 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008064 Py_END_ALLOW_THREADS
8065 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008066 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008067
8068 if (sf.headers != NULL)
8069 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8070 if (sf.trailers != NULL)
8071 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8072
8073 if (ret < 0) {
8074 if ((errno == EAGAIN) || (errno == EBUSY)) {
8075 if (sbytes != 0) {
8076 // some data has been sent
8077 goto done;
8078 }
8079 else {
8080 // no data has been sent; upper application is supposed
8081 // to retry on EAGAIN or EBUSY
8082 return posix_error();
8083 }
8084 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008085 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 }
8087 goto done;
8088
8089done:
8090 #if !defined(HAVE_LARGEFILE_SUPPORT)
8091 return Py_BuildValue("l", sbytes);
8092 #else
8093 return Py_BuildValue("L", sbytes);
8094 #endif
8095
8096#else
8097 Py_ssize_t count;
8098 PyObject *offobj;
8099 static char *keywords[] = {"out", "in",
8100 "offset", "count", NULL};
8101 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8102 keywords, &out, &in, &offobj, &count))
8103 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008104#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008105 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008106 do {
8107 Py_BEGIN_ALLOW_THREADS
8108 ret = sendfile(out, in, NULL, count);
8109 Py_END_ALLOW_THREADS
8110 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008111 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008112 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008113 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008114 }
8115#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008116 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008117 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008118
8119 do {
8120 Py_BEGIN_ALLOW_THREADS
8121 ret = sendfile(out, in, &offset, count);
8122 Py_END_ALLOW_THREADS
8123 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008124 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008125 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008126 return Py_BuildValue("n", ret);
8127#endif
8128}
Larry Hastings2f936352014-08-05 14:04:04 +10008129#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008130
Larry Hastings2f936352014-08-05 14:04:04 +10008131
8132/*[clinic input]
8133os.fstat
8134
8135 fd : int
8136
8137Perform a stat system call on the given file descriptor.
8138
8139Like stat(), but for an open file descriptor.
8140Equivalent to os.stat(fd).
8141[clinic start generated code]*/
8142
Larry Hastings2f936352014-08-05 14:04:04 +10008143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008144os_fstat_impl(PyObject *module, int fd)
8145/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008146{
Victor Stinner8c62be82010-05-06 00:08:46 +00008147 STRUCT_STAT st;
8148 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008150
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008151 do {
8152 Py_BEGIN_ALLOW_THREADS
8153 res = FSTAT(fd, &st);
8154 Py_END_ALLOW_THREADS
8155 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008156 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008157#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008158 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008159#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008160 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008161#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008162 }
Tim Peters5aa91602002-01-30 05:46:57 +00008163
Victor Stinner4195b5c2012-02-08 23:03:19 +01008164 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008165}
8166
Larry Hastings2f936352014-08-05 14:04:04 +10008167
8168/*[clinic input]
8169os.isatty -> bool
8170 fd: int
8171 /
8172
8173Return True if the fd is connected to a terminal.
8174
8175Return True if the file descriptor is an open file descriptor
8176connected to the slave end of a terminal.
8177[clinic start generated code]*/
8178
Larry Hastings2f936352014-08-05 14:04:04 +10008179static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008180os_isatty_impl(PyObject *module, int fd)
8181/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008182{
Steve Dower8fc89802015-04-12 00:26:27 -04008183 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008184 _Py_BEGIN_SUPPRESS_IPH
8185 return_value = isatty(fd);
8186 _Py_END_SUPPRESS_IPH
8187 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008188}
8189
8190
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008191#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008192/*[clinic input]
8193os.pipe
8194
8195Create a pipe.
8196
8197Returns a tuple of two file descriptors:
8198 (read_fd, write_fd)
8199[clinic start generated code]*/
8200
Larry Hastings2f936352014-08-05 14:04:04 +10008201static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008202os_pipe_impl(PyObject *module)
8203/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008204{
Victor Stinner8c62be82010-05-06 00:08:46 +00008205 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008206#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008208 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008210#else
8211 int res;
8212#endif
8213
8214#ifdef MS_WINDOWS
8215 attr.nLength = sizeof(attr);
8216 attr.lpSecurityDescriptor = NULL;
8217 attr.bInheritHandle = FALSE;
8218
8219 Py_BEGIN_ALLOW_THREADS
8220 ok = CreatePipe(&read, &write, &attr, 0);
8221 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008222 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8223 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008224 if (fds[0] == -1 || fds[1] == -1) {
8225 CloseHandle(read);
8226 CloseHandle(write);
8227 ok = 0;
8228 }
8229 }
8230 Py_END_ALLOW_THREADS
8231
Victor Stinner8c62be82010-05-06 00:08:46 +00008232 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008233 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008234#else
8235
8236#ifdef HAVE_PIPE2
8237 Py_BEGIN_ALLOW_THREADS
8238 res = pipe2(fds, O_CLOEXEC);
8239 Py_END_ALLOW_THREADS
8240
8241 if (res != 0 && errno == ENOSYS)
8242 {
8243#endif
8244 Py_BEGIN_ALLOW_THREADS
8245 res = pipe(fds);
8246 Py_END_ALLOW_THREADS
8247
8248 if (res == 0) {
8249 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8250 close(fds[0]);
8251 close(fds[1]);
8252 return NULL;
8253 }
8254 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8255 close(fds[0]);
8256 close(fds[1]);
8257 return NULL;
8258 }
8259 }
8260#ifdef HAVE_PIPE2
8261 }
8262#endif
8263
8264 if (res != 0)
8265 return PyErr_SetFromErrno(PyExc_OSError);
8266#endif /* !MS_WINDOWS */
8267 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008268}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008269#endif /* HAVE_PIPE */
8270
Larry Hastings2f936352014-08-05 14:04:04 +10008271
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008272#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008273/*[clinic input]
8274os.pipe2
8275
8276 flags: int
8277 /
8278
8279Create a pipe with flags set atomically.
8280
8281Returns a tuple of two file descriptors:
8282 (read_fd, write_fd)
8283
8284flags can be constructed by ORing together one or more of these values:
8285O_NONBLOCK, O_CLOEXEC.
8286[clinic start generated code]*/
8287
Larry Hastings2f936352014-08-05 14:04:04 +10008288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008289os_pipe2_impl(PyObject *module, int flags)
8290/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008291{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008292 int fds[2];
8293 int res;
8294
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008295 res = pipe2(fds, flags);
8296 if (res != 0)
8297 return posix_error();
8298 return Py_BuildValue("(ii)", fds[0], fds[1]);
8299}
8300#endif /* HAVE_PIPE2 */
8301
Larry Hastings2f936352014-08-05 14:04:04 +10008302
Ross Lagerwall7807c352011-03-17 20:20:30 +02008303#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008304/*[clinic input]
8305os.writev -> Py_ssize_t
8306 fd: int
8307 buffers: object
8308 /
8309
8310Iterate over buffers, and write the contents of each to a file descriptor.
8311
8312Returns the total number of bytes written.
8313buffers must be a sequence of bytes-like objects.
8314[clinic start generated code]*/
8315
Larry Hastings2f936352014-08-05 14:04:04 +10008316static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008317os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8318/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008319{
8320 int cnt;
8321 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008323 struct iovec *iov;
8324 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008325
8326 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008327 PyErr_SetString(PyExc_TypeError,
8328 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008329 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008330 }
Larry Hastings2f936352014-08-05 14:04:04 +10008331 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008332
Larry Hastings2f936352014-08-05 14:04:04 +10008333 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8334 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008335 }
8336
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008337 do {
8338 Py_BEGIN_ALLOW_THREADS
8339 result = writev(fd, iov, cnt);
8340 Py_END_ALLOW_THREADS
8341 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008342
8343 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008344 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008345 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008346
Georg Brandl306336b2012-06-24 12:55:33 +02008347 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008348}
Larry Hastings2f936352014-08-05 14:04:04 +10008349#endif /* HAVE_WRITEV */
8350
8351
8352#ifdef HAVE_PWRITE
8353/*[clinic input]
8354os.pwrite -> Py_ssize_t
8355
8356 fd: int
8357 buffer: Py_buffer
8358 offset: Py_off_t
8359 /
8360
8361Write bytes to a file descriptor starting at a particular offset.
8362
8363Write buffer to fd, starting at offset bytes from the beginning of
8364the file. Returns the number of bytes writte. Does not change the
8365current file offset.
8366[clinic start generated code]*/
8367
Larry Hastings2f936352014-08-05 14:04:04 +10008368static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008369os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8370/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008371{
8372 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008373 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008374
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008375 do {
8376 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008377 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008378 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008379 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008380 Py_END_ALLOW_THREADS
8381 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008382
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008383 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008384 posix_error();
8385 return size;
8386}
8387#endif /* HAVE_PWRITE */
8388
8389
8390#ifdef HAVE_MKFIFO
8391/*[clinic input]
8392os.mkfifo
8393
8394 path: path_t
8395 mode: int=0o666
8396 *
8397 dir_fd: dir_fd(requires='mkfifoat')=None
8398
8399Create a "fifo" (a POSIX named pipe).
8400
8401If dir_fd is not None, it should be a file descriptor open to a directory,
8402 and path should be relative; path will then be relative to that directory.
8403dir_fd may not be implemented on your platform.
8404 If it is unavailable, using it will raise a NotImplementedError.
8405[clinic start generated code]*/
8406
Larry Hastings2f936352014-08-05 14:04:04 +10008407static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008408os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8409/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008410{
8411 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008412 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008413
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008414 do {
8415 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008416#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008417 if (dir_fd != DEFAULT_DIR_FD)
8418 result = mkfifoat(dir_fd, path->narrow, mode);
8419 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008420#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008421 result = mkfifo(path->narrow, mode);
8422 Py_END_ALLOW_THREADS
8423 } while (result != 0 && errno == EINTR &&
8424 !(async_err = PyErr_CheckSignals()));
8425 if (result != 0)
8426 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008427
8428 Py_RETURN_NONE;
8429}
8430#endif /* HAVE_MKFIFO */
8431
8432
8433#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8434/*[clinic input]
8435os.mknod
8436
8437 path: path_t
8438 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008439 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008440 *
8441 dir_fd: dir_fd(requires='mknodat')=None
8442
8443Create a node in the file system.
8444
8445Create a node in the file system (file, device special file or named pipe)
8446at path. mode specifies both the permissions to use and the
8447type of node to be created, being combined (bitwise OR) with one of
8448S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8449device defines the newly created device special file (probably using
8450os.makedev()). Otherwise device is ignored.
8451
8452If dir_fd is not None, it should be a file descriptor open to a directory,
8453 and path should be relative; path will then be relative to that directory.
8454dir_fd may not be implemented on your platform.
8455 If it is unavailable, using it will raise a NotImplementedError.
8456[clinic start generated code]*/
8457
Larry Hastings2f936352014-08-05 14:04:04 +10008458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008459os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008460 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008461/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008462{
8463 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008464 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008465
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008466 do {
8467 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008468#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008469 if (dir_fd != DEFAULT_DIR_FD)
8470 result = mknodat(dir_fd, path->narrow, mode, device);
8471 else
Larry Hastings2f936352014-08-05 14:04:04 +10008472#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008473 result = mknod(path->narrow, mode, device);
8474 Py_END_ALLOW_THREADS
8475 } while (result != 0 && errno == EINTR &&
8476 !(async_err = PyErr_CheckSignals()));
8477 if (result != 0)
8478 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008479
8480 Py_RETURN_NONE;
8481}
8482#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8483
8484
8485#ifdef HAVE_DEVICE_MACROS
8486/*[clinic input]
8487os.major -> unsigned_int
8488
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008489 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008490 /
8491
8492Extracts a device major number from a raw device number.
8493[clinic start generated code]*/
8494
Larry Hastings2f936352014-08-05 14:04:04 +10008495static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008496os_major_impl(PyObject *module, dev_t device)
8497/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008498{
8499 return major(device);
8500}
8501
8502
8503/*[clinic input]
8504os.minor -> unsigned_int
8505
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008506 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008507 /
8508
8509Extracts a device minor number from a raw device number.
8510[clinic start generated code]*/
8511
Larry Hastings2f936352014-08-05 14:04:04 +10008512static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008513os_minor_impl(PyObject *module, dev_t device)
8514/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008515{
8516 return minor(device);
8517}
8518
8519
8520/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008521os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008522
8523 major: int
8524 minor: int
8525 /
8526
8527Composes a raw device number from the major and minor device numbers.
8528[clinic start generated code]*/
8529
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008530static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008531os_makedev_impl(PyObject *module, int major, int minor)
8532/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008533{
8534 return makedev(major, minor);
8535}
8536#endif /* HAVE_DEVICE_MACROS */
8537
8538
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008539#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008540/*[clinic input]
8541os.ftruncate
8542
8543 fd: int
8544 length: Py_off_t
8545 /
8546
8547Truncate a file, specified by file descriptor, to a specific length.
8548[clinic start generated code]*/
8549
Larry Hastings2f936352014-08-05 14:04:04 +10008550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008551os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8552/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008553{
8554 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008555 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008556
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008557 do {
8558 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008559 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008560#ifdef MS_WINDOWS
8561 result = _chsize_s(fd, length);
8562#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008563 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008564#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008565 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008566 Py_END_ALLOW_THREADS
8567 } while (result != 0 && errno == EINTR &&
8568 !(async_err = PyErr_CheckSignals()));
8569 if (result != 0)
8570 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008571 Py_RETURN_NONE;
8572}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008573#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008574
8575
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008576#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008577/*[clinic input]
8578os.truncate
8579 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8580 length: Py_off_t
8581
8582Truncate a file, specified by path, to a specific length.
8583
8584On some platforms, path may also be specified as an open file descriptor.
8585 If this functionality is unavailable, using it raises an exception.
8586[clinic start generated code]*/
8587
Larry Hastings2f936352014-08-05 14:04:04 +10008588static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008589os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8590/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008591{
8592 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008593#ifdef MS_WINDOWS
8594 int fd;
8595#endif
8596
8597 if (path->fd != -1)
8598 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008599
8600 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008601 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008602#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008603 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008604 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008605 result = -1;
8606 else {
8607 result = _chsize_s(fd, length);
8608 close(fd);
8609 if (result < 0)
8610 errno = result;
8611 }
8612#else
8613 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008614#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008615 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008616 Py_END_ALLOW_THREADS
8617 if (result < 0)
8618 return path_error(path);
8619
8620 Py_RETURN_NONE;
8621}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008622#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008623
Ross Lagerwall7807c352011-03-17 20:20:30 +02008624
Victor Stinnerd6b17692014-09-30 12:20:05 +02008625/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8626 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8627 defined, which is the case in Python on AIX. AIX bug report:
8628 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8629#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8630# define POSIX_FADVISE_AIX_BUG
8631#endif
8632
Victor Stinnerec39e262014-09-30 12:35:58 +02008633
Victor Stinnerd6b17692014-09-30 12:20:05 +02008634#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008635/*[clinic input]
8636os.posix_fallocate
8637
8638 fd: int
8639 offset: Py_off_t
8640 length: Py_off_t
8641 /
8642
8643Ensure a file has allocated at least a particular number of bytes on disk.
8644
8645Ensure that the file specified by fd encompasses a range of bytes
8646starting at offset bytes from the beginning and continuing for length bytes.
8647[clinic start generated code]*/
8648
Larry Hastings2f936352014-08-05 14:04:04 +10008649static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008650os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008651 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008652/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008653{
8654 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008655 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008656
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008657 do {
8658 Py_BEGIN_ALLOW_THREADS
8659 result = posix_fallocate(fd, offset, length);
8660 Py_END_ALLOW_THREADS
8661 } while (result != 0 && errno == EINTR &&
8662 !(async_err = PyErr_CheckSignals()));
8663 if (result != 0)
8664 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008665 Py_RETURN_NONE;
8666}
Victor Stinnerec39e262014-09-30 12:35:58 +02008667#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008668
Ross Lagerwall7807c352011-03-17 20:20:30 +02008669
Victor Stinnerd6b17692014-09-30 12:20:05 +02008670#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008671/*[clinic input]
8672os.posix_fadvise
8673
8674 fd: int
8675 offset: Py_off_t
8676 length: Py_off_t
8677 advice: int
8678 /
8679
8680Announce an intention to access data in a specific pattern.
8681
8682Announce an intention to access data in a specific pattern, thus allowing
8683the kernel to make optimizations.
8684The advice applies to the region of the file specified by fd starting at
8685offset and continuing for length bytes.
8686advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8687POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8688POSIX_FADV_DONTNEED.
8689[clinic start generated code]*/
8690
Larry Hastings2f936352014-08-05 14:04:04 +10008691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008692os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008693 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008694/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008695{
8696 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008697 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008698
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008699 do {
8700 Py_BEGIN_ALLOW_THREADS
8701 result = posix_fadvise(fd, offset, length, advice);
8702 Py_END_ALLOW_THREADS
8703 } while (result != 0 && errno == EINTR &&
8704 !(async_err = PyErr_CheckSignals()));
8705 if (result != 0)
8706 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008707 Py_RETURN_NONE;
8708}
Victor Stinnerec39e262014-09-30 12:35:58 +02008709#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008710
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008711#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008712
Fred Drake762e2061999-08-26 17:23:54 +00008713/* Save putenv() parameters as values here, so we can collect them when they
8714 * get re-set with another call for the same key. */
8715static PyObject *posix_putenv_garbage;
8716
Larry Hastings2f936352014-08-05 14:04:04 +10008717static void
8718posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008719{
Larry Hastings2f936352014-08-05 14:04:04 +10008720 /* Install the first arg and newstr in posix_putenv_garbage;
8721 * this will cause previous value to be collected. This has to
8722 * happen after the real putenv() call because the old value
8723 * was still accessible until then. */
8724 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8725 /* really not much we can do; just leak */
8726 PyErr_Clear();
8727 else
8728 Py_DECREF(value);
8729}
8730
8731
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008732#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008733/*[clinic input]
8734os.putenv
8735
8736 name: unicode
8737 value: unicode
8738 /
8739
8740Change or add an environment variable.
8741[clinic start generated code]*/
8742
Larry Hastings2f936352014-08-05 14:04:04 +10008743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008744os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8745/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008746{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008747 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008748
8749 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8750 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008751 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008752 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008753 }
Larry Hastings2f936352014-08-05 14:04:04 +10008754 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008755 PyErr_Format(PyExc_ValueError,
8756 "the environment variable is longer than %u characters",
8757 _MAX_ENV);
8758 goto error;
8759 }
8760
Larry Hastings2f936352014-08-05 14:04:04 +10008761 env = PyUnicode_AsUnicode(unicode);
8762 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008763 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008764 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008765 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008766 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008767 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008768
Larry Hastings2f936352014-08-05 14:04:04 +10008769 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008770 Py_RETURN_NONE;
8771
8772error:
Larry Hastings2f936352014-08-05 14:04:04 +10008773 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008774 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008775}
Larry Hastings2f936352014-08-05 14:04:04 +10008776#else /* MS_WINDOWS */
8777/*[clinic input]
8778os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008779
Larry Hastings2f936352014-08-05 14:04:04 +10008780 name: FSConverter
8781 value: FSConverter
8782 /
8783
8784Change or add an environment variable.
8785[clinic start generated code]*/
8786
Larry Hastings2f936352014-08-05 14:04:04 +10008787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008788os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8789/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008790{
8791 PyObject *bytes = NULL;
8792 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008793 const char *name_string = PyBytes_AsString(name);
8794 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008795
8796 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8797 if (bytes == NULL) {
8798 PyErr_NoMemory();
8799 return NULL;
8800 }
8801
8802 env = PyBytes_AS_STRING(bytes);
8803 if (putenv(env)) {
8804 Py_DECREF(bytes);
8805 return posix_error();
8806 }
8807
8808 posix_putenv_garbage_setitem(name, bytes);
8809 Py_RETURN_NONE;
8810}
8811#endif /* MS_WINDOWS */
8812#endif /* HAVE_PUTENV */
8813
8814
8815#ifdef HAVE_UNSETENV
8816/*[clinic input]
8817os.unsetenv
8818 name: FSConverter
8819 /
8820
8821Delete an environment variable.
8822[clinic start generated code]*/
8823
Larry Hastings2f936352014-08-05 14:04:04 +10008824static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008825os_unsetenv_impl(PyObject *module, PyObject *name)
8826/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008827{
Victor Stinner984890f2011-11-24 13:53:38 +01008828#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008829 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008830#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008831
Victor Stinner984890f2011-11-24 13:53:38 +01008832#ifdef HAVE_BROKEN_UNSETENV
8833 unsetenv(PyBytes_AS_STRING(name));
8834#else
Victor Stinner65170952011-11-22 22:16:17 +01008835 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008836 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008837 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008838#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008839
Victor Stinner8c62be82010-05-06 00:08:46 +00008840 /* Remove the key from posix_putenv_garbage;
8841 * this will cause it to be collected. This has to
8842 * happen after the real unsetenv() call because the
8843 * old value was still accessible until then.
8844 */
Victor Stinner65170952011-11-22 22:16:17 +01008845 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008846 /* really not much we can do; just leak */
8847 PyErr_Clear();
8848 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008849 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008850}
Larry Hastings2f936352014-08-05 14:04:04 +10008851#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008852
Larry Hastings2f936352014-08-05 14:04:04 +10008853
8854/*[clinic input]
8855os.strerror
8856
8857 code: int
8858 /
8859
8860Translate an error code to a message string.
8861[clinic start generated code]*/
8862
Larry Hastings2f936352014-08-05 14:04:04 +10008863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008864os_strerror_impl(PyObject *module, int code)
8865/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008866{
8867 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008868 if (message == NULL) {
8869 PyErr_SetString(PyExc_ValueError,
8870 "strerror() argument out of range");
8871 return NULL;
8872 }
Victor Stinner1b579672011-12-17 05:47:23 +01008873 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008874}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008875
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008876
Guido van Rossumc9641791998-08-04 15:26:23 +00008877#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008878#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008879/*[clinic input]
8880os.WCOREDUMP -> bool
8881
8882 status: int
8883 /
8884
8885Return True if the process returning status was dumped to a core file.
8886[clinic start generated code]*/
8887
Larry Hastings2f936352014-08-05 14:04:04 +10008888static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008889os_WCOREDUMP_impl(PyObject *module, int status)
8890/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008891{
8892 WAIT_TYPE wait_status;
8893 WAIT_STATUS_INT(wait_status) = status;
8894 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008895}
8896#endif /* WCOREDUMP */
8897
Larry Hastings2f936352014-08-05 14:04:04 +10008898
Fred Drake106c1a02002-04-23 15:58:02 +00008899#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008900/*[clinic input]
8901os.WIFCONTINUED -> bool
8902
8903 status: int
8904
8905Return True if a particular process was continued from a job control stop.
8906
8907Return True if the process returning status was continued from a
8908job control stop.
8909[clinic start generated code]*/
8910
Larry Hastings2f936352014-08-05 14:04:04 +10008911static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008912os_WIFCONTINUED_impl(PyObject *module, int status)
8913/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008914{
8915 WAIT_TYPE wait_status;
8916 WAIT_STATUS_INT(wait_status) = status;
8917 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008918}
8919#endif /* WIFCONTINUED */
8920
Larry Hastings2f936352014-08-05 14:04:04 +10008921
Guido van Rossumc9641791998-08-04 15:26:23 +00008922#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10008923/*[clinic input]
8924os.WIFSTOPPED -> bool
8925
8926 status: int
8927
8928Return True if the process returning status was stopped.
8929[clinic start generated code]*/
8930
Larry Hastings2f936352014-08-05 14:04:04 +10008931static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008932os_WIFSTOPPED_impl(PyObject *module, int status)
8933/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008934{
8935 WAIT_TYPE wait_status;
8936 WAIT_STATUS_INT(wait_status) = status;
8937 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008938}
8939#endif /* WIFSTOPPED */
8940
Larry Hastings2f936352014-08-05 14:04:04 +10008941
Guido van Rossumc9641791998-08-04 15:26:23 +00008942#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10008943/*[clinic input]
8944os.WIFSIGNALED -> bool
8945
8946 status: int
8947
8948Return True if the process returning status was terminated by a signal.
8949[clinic start generated code]*/
8950
Larry Hastings2f936352014-08-05 14:04:04 +10008951static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008952os_WIFSIGNALED_impl(PyObject *module, int status)
8953/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008954{
8955 WAIT_TYPE wait_status;
8956 WAIT_STATUS_INT(wait_status) = status;
8957 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008958}
8959#endif /* WIFSIGNALED */
8960
Larry Hastings2f936352014-08-05 14:04:04 +10008961
Guido van Rossumc9641791998-08-04 15:26:23 +00008962#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10008963/*[clinic input]
8964os.WIFEXITED -> bool
8965
8966 status: int
8967
8968Return True if the process returning status exited via the exit() system call.
8969[clinic start generated code]*/
8970
Larry Hastings2f936352014-08-05 14:04:04 +10008971static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008972os_WIFEXITED_impl(PyObject *module, int status)
8973/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008974{
8975 WAIT_TYPE wait_status;
8976 WAIT_STATUS_INT(wait_status) = status;
8977 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008978}
8979#endif /* WIFEXITED */
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008982#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10008983/*[clinic input]
8984os.WEXITSTATUS -> int
8985
8986 status: int
8987
8988Return the process return code from status.
8989[clinic start generated code]*/
8990
Larry Hastings2f936352014-08-05 14:04:04 +10008991static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008992os_WEXITSTATUS_impl(PyObject *module, int status)
8993/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008994{
8995 WAIT_TYPE wait_status;
8996 WAIT_STATUS_INT(wait_status) = status;
8997 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008998}
8999#endif /* WEXITSTATUS */
9000
Larry Hastings2f936352014-08-05 14:04:04 +10009001
Guido van Rossumc9641791998-08-04 15:26:23 +00009002#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009003/*[clinic input]
9004os.WTERMSIG -> int
9005
9006 status: int
9007
9008Return the signal that terminated the process that provided the status value.
9009[clinic start generated code]*/
9010
Larry Hastings2f936352014-08-05 14:04:04 +10009011static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009012os_WTERMSIG_impl(PyObject *module, int status)
9013/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009014{
9015 WAIT_TYPE wait_status;
9016 WAIT_STATUS_INT(wait_status) = status;
9017 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009018}
9019#endif /* WTERMSIG */
9020
Larry Hastings2f936352014-08-05 14:04:04 +10009021
Guido van Rossumc9641791998-08-04 15:26:23 +00009022#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009023/*[clinic input]
9024os.WSTOPSIG -> int
9025
9026 status: int
9027
9028Return the signal that stopped the process that provided the status value.
9029[clinic start generated code]*/
9030
Larry Hastings2f936352014-08-05 14:04:04 +10009031static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009032os_WSTOPSIG_impl(PyObject *module, int status)
9033/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009034{
9035 WAIT_TYPE wait_status;
9036 WAIT_STATUS_INT(wait_status) = status;
9037 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009038}
9039#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009040#endif /* HAVE_SYS_WAIT_H */
9041
9042
Thomas Wouters477c8d52006-05-27 19:21:47 +00009043#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009044#ifdef _SCO_DS
9045/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9046 needed definitions in sys/statvfs.h */
9047#define _SVID3
9048#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009049#include <sys/statvfs.h>
9050
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009051static PyObject*
9052_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9054 if (v == NULL)
9055 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009056
9057#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009058 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9059 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9060 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9061 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9062 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9063 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9064 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9065 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9066 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9067 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009068#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009069 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9070 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9071 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009072 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009074 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009075 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009076 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009078 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009080 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009082 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9084 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009085#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009086 if (PyErr_Occurred()) {
9087 Py_DECREF(v);
9088 return NULL;
9089 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009090
Victor Stinner8c62be82010-05-06 00:08:46 +00009091 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009092}
9093
Larry Hastings2f936352014-08-05 14:04:04 +10009094
9095/*[clinic input]
9096os.fstatvfs
9097 fd: int
9098 /
9099
9100Perform an fstatvfs system call on the given fd.
9101
9102Equivalent to statvfs(fd).
9103[clinic start generated code]*/
9104
Larry Hastings2f936352014-08-05 14:04:04 +10009105static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009106os_fstatvfs_impl(PyObject *module, int fd)
9107/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009108{
9109 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009110 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009112
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009113 do {
9114 Py_BEGIN_ALLOW_THREADS
9115 result = fstatvfs(fd, &st);
9116 Py_END_ALLOW_THREADS
9117 } while (result != 0 && errno == EINTR &&
9118 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009119 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009120 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009121
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009123}
Larry Hastings2f936352014-08-05 14:04:04 +10009124#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009125
9126
Thomas Wouters477c8d52006-05-27 19:21:47 +00009127#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009128#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009129/*[clinic input]
9130os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009131
Larry Hastings2f936352014-08-05 14:04:04 +10009132 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9133
9134Perform a statvfs system call on the given path.
9135
9136path may always be specified as a string.
9137On some platforms, path may also be specified as an open file descriptor.
9138 If this functionality is unavailable, using it raises an exception.
9139[clinic start generated code]*/
9140
Larry Hastings2f936352014-08-05 14:04:04 +10009141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009142os_statvfs_impl(PyObject *module, path_t *path)
9143/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009144{
9145 int result;
9146 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009147
9148 Py_BEGIN_ALLOW_THREADS
9149#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009150 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009151#ifdef __APPLE__
9152 /* handle weak-linking on Mac OS X 10.3 */
9153 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009154 fd_specified("statvfs", path->fd);
9155 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009156 }
9157#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009158 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009159 }
9160 else
9161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009162 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009163 Py_END_ALLOW_THREADS
9164
9165 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009166 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009167 }
9168
Larry Hastings2f936352014-08-05 14:04:04 +10009169 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009170}
Larry Hastings2f936352014-08-05 14:04:04 +10009171#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9172
Guido van Rossum94f6f721999-01-06 18:42:14 +00009173
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009174#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009175/*[clinic input]
9176os._getdiskusage
9177
9178 path: Py_UNICODE
9179
9180Return disk usage statistics about the given path as a (total, free) tuple.
9181[clinic start generated code]*/
9182
Larry Hastings2f936352014-08-05 14:04:04 +10009183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009184os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9185/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009186{
9187 BOOL retval;
9188 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009189
9190 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009191 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009192 Py_END_ALLOW_THREADS
9193 if (retval == 0)
9194 return PyErr_SetFromWindowsErr(0);
9195
9196 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9197}
Larry Hastings2f936352014-08-05 14:04:04 +10009198#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009199
9200
Fred Drakec9680921999-12-13 16:37:25 +00009201/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9202 * It maps strings representing configuration variable names to
9203 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009204 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009205 * rarely-used constants. There are three separate tables that use
9206 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009207 *
9208 * This code is always included, even if none of the interfaces that
9209 * need it are included. The #if hackery needed to avoid it would be
9210 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009211 */
9212struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009213 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009214 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009215};
9216
Fred Drake12c6e2d1999-12-14 21:25:03 +00009217static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009218conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009219 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009220{
Christian Heimes217cfd12007-12-02 14:31:20 +00009221 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009222 int value = _PyLong_AsInt(arg);
9223 if (value == -1 && PyErr_Occurred())
9224 return 0;
9225 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009226 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009227 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009228 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009229 /* look up the value in the table using a binary search */
9230 size_t lo = 0;
9231 size_t mid;
9232 size_t hi = tablesize;
9233 int cmp;
9234 const char *confname;
9235 if (!PyUnicode_Check(arg)) {
9236 PyErr_SetString(PyExc_TypeError,
9237 "configuration names must be strings or integers");
9238 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009239 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009240 confname = _PyUnicode_AsString(arg);
9241 if (confname == NULL)
9242 return 0;
9243 while (lo < hi) {
9244 mid = (lo + hi) / 2;
9245 cmp = strcmp(confname, table[mid].name);
9246 if (cmp < 0)
9247 hi = mid;
9248 else if (cmp > 0)
9249 lo = mid + 1;
9250 else {
9251 *valuep = table[mid].value;
9252 return 1;
9253 }
9254 }
9255 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9256 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009257 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009258}
9259
9260
9261#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9262static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009263#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009264 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009265#endif
9266#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009267 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009268#endif
Fred Drakec9680921999-12-13 16:37:25 +00009269#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009270 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009271#endif
9272#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009273 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009274#endif
9275#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009276 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009277#endif
9278#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009279 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009280#endif
9281#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009282 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009283#endif
9284#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009285 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009286#endif
9287#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009288 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009289#endif
9290#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009291 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009292#endif
9293#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009295#endif
9296#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009297 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009298#endif
9299#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009300 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009301#endif
9302#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009303 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009304#endif
9305#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009307#endif
9308#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009309 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009310#endif
9311#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009313#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009314#ifdef _PC_ACL_ENABLED
9315 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9316#endif
9317#ifdef _PC_MIN_HOLE_SIZE
9318 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9319#endif
9320#ifdef _PC_ALLOC_SIZE_MIN
9321 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9322#endif
9323#ifdef _PC_REC_INCR_XFER_SIZE
9324 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9325#endif
9326#ifdef _PC_REC_MAX_XFER_SIZE
9327 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9328#endif
9329#ifdef _PC_REC_MIN_XFER_SIZE
9330 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9331#endif
9332#ifdef _PC_REC_XFER_ALIGN
9333 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9334#endif
9335#ifdef _PC_SYMLINK_MAX
9336 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9337#endif
9338#ifdef _PC_XATTR_ENABLED
9339 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9340#endif
9341#ifdef _PC_XATTR_EXISTS
9342 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9343#endif
9344#ifdef _PC_TIMESTAMP_RESOLUTION
9345 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9346#endif
Fred Drakec9680921999-12-13 16:37:25 +00009347};
9348
Fred Drakec9680921999-12-13 16:37:25 +00009349static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009350conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009351{
9352 return conv_confname(arg, valuep, posix_constants_pathconf,
9353 sizeof(posix_constants_pathconf)
9354 / sizeof(struct constdef));
9355}
9356#endif
9357
Larry Hastings2f936352014-08-05 14:04:04 +10009358
Fred Drakec9680921999-12-13 16:37:25 +00009359#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009360/*[clinic input]
9361os.fpathconf -> long
9362
9363 fd: int
9364 name: path_confname
9365 /
9366
9367Return the configuration limit name for the file descriptor fd.
9368
9369If there is no limit, return -1.
9370[clinic start generated code]*/
9371
Larry Hastings2f936352014-08-05 14:04:04 +10009372static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009373os_fpathconf_impl(PyObject *module, int fd, int name)
9374/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009375{
9376 long limit;
9377
9378 errno = 0;
9379 limit = fpathconf(fd, name);
9380 if (limit == -1 && errno != 0)
9381 posix_error();
9382
9383 return limit;
9384}
9385#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009386
9387
9388#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009389/*[clinic input]
9390os.pathconf -> long
9391 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9392 name: path_confname
9393
9394Return the configuration limit name for the file or directory path.
9395
9396If there is no limit, return -1.
9397On some platforms, path may also be specified as an open file descriptor.
9398 If this functionality is unavailable, using it raises an exception.
9399[clinic start generated code]*/
9400
Larry Hastings2f936352014-08-05 14:04:04 +10009401static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009402os_pathconf_impl(PyObject *module, path_t *path, int name)
9403/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009404{
Victor Stinner8c62be82010-05-06 00:08:46 +00009405 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009406
Victor Stinner8c62be82010-05-06 00:08:46 +00009407 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009408#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009409 if (path->fd != -1)
9410 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009411 else
9412#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009413 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009414 if (limit == -1 && errno != 0) {
9415 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009416 /* could be a path or name problem */
9417 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009418 else
Larry Hastings2f936352014-08-05 14:04:04 +10009419 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009420 }
Larry Hastings2f936352014-08-05 14:04:04 +10009421
9422 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009423}
Larry Hastings2f936352014-08-05 14:04:04 +10009424#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009425
9426#ifdef HAVE_CONFSTR
9427static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009428#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009429 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009430#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009431#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009432 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009433#endif
9434#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009435 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009436#endif
Fred Draked86ed291999-12-15 15:34:33 +00009437#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009438 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009439#endif
9440#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009441 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009442#endif
9443#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009444 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009445#endif
9446#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009447 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009448#endif
Fred Drakec9680921999-12-13 16:37:25 +00009449#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009451#endif
9452#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009453 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009454#endif
9455#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009456 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009457#endif
9458#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009459 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009460#endif
9461#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009463#endif
9464#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009465 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009466#endif
9467#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009468 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009469#endif
9470#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009471 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009472#endif
Fred Draked86ed291999-12-15 15:34:33 +00009473#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009474 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009475#endif
Fred Drakec9680921999-12-13 16:37:25 +00009476#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009477 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009478#endif
Fred Draked86ed291999-12-15 15:34:33 +00009479#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009480 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009481#endif
9482#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009483 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009484#endif
9485#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009486 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009487#endif
9488#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009489 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009490#endif
Fred Drakec9680921999-12-13 16:37:25 +00009491#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009492 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009493#endif
9494#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009495 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009496#endif
9497#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009498 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009499#endif
9500#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009501 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009502#endif
9503#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009504 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009505#endif
9506#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009508#endif
9509#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009510 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009511#endif
9512#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009513 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009514#endif
9515#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009516 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009517#endif
9518#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009519 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009520#endif
9521#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009522 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009523#endif
9524#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009526#endif
9527#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009528 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009529#endif
9530#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009531 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009532#endif
9533#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009535#endif
9536#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009538#endif
Fred Draked86ed291999-12-15 15:34:33 +00009539#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
9542#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009544#endif
9545#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009547#endif
9548#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009550#endif
9551#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009553#endif
9554#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009556#endif
9557#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009559#endif
9560#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009562#endif
9563#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009565#endif
9566#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009568#endif
9569#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009571#endif
9572#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009574#endif
9575#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009577#endif
Fred Drakec9680921999-12-13 16:37:25 +00009578};
9579
9580static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009581conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009582{
9583 return conv_confname(arg, valuep, posix_constants_confstr,
9584 sizeof(posix_constants_confstr)
9585 / sizeof(struct constdef));
9586}
9587
Larry Hastings2f936352014-08-05 14:04:04 +10009588
9589/*[clinic input]
9590os.confstr
9591
9592 name: confstr_confname
9593 /
9594
9595Return a string-valued system configuration variable.
9596[clinic start generated code]*/
9597
Larry Hastings2f936352014-08-05 14:04:04 +10009598static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009599os_confstr_impl(PyObject *module, int name)
9600/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009601{
9602 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009603 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009604 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009605
Victor Stinnercb043522010-09-10 23:49:04 +00009606 errno = 0;
9607 len = confstr(name, buffer, sizeof(buffer));
9608 if (len == 0) {
9609 if (errno) {
9610 posix_error();
9611 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009612 }
9613 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009614 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009615 }
9616 }
Victor Stinnercb043522010-09-10 23:49:04 +00009617
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009618 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009619 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009620 char *buf = PyMem_Malloc(len);
9621 if (buf == NULL)
9622 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009623 len2 = confstr(name, buf, len);
9624 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009625 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009626 PyMem_Free(buf);
9627 }
9628 else
9629 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009630 return result;
9631}
Larry Hastings2f936352014-08-05 14:04:04 +10009632#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009633
9634
9635#ifdef HAVE_SYSCONF
9636static struct constdef posix_constants_sysconf[] = {
9637#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009639#endif
9640#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
9643#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
9646#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
9649#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009651#endif
9652#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009654#endif
9655#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
9658#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009660#endif
9661#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009663#endif
9664#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
Fred Draked86ed291999-12-15 15:34:33 +00009667#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009669#endif
9670#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009672#endif
Fred Drakec9680921999-12-13 16:37:25 +00009673#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009675#endif
Fred Drakec9680921999-12-13 16:37:25 +00009676#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009678#endif
9679#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009681#endif
9682#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009684#endif
9685#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009687#endif
9688#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009690#endif
Fred Draked86ed291999-12-15 15:34:33 +00009691#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009693#endif
Fred Drakec9680921999-12-13 16:37:25 +00009694#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
9700#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009702#endif
9703#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
Fred Draked86ed291999-12-15 15:34:33 +00009709#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009711#endif
Fred Drakec9680921999-12-13 16:37:25 +00009712#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009714#endif
9715#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
9718#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009720#endif
9721#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
9730#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
Fred Draked86ed291999-12-15 15:34:33 +00009781#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009783#endif
Fred Drakec9680921999-12-13 16:37:25 +00009784#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
Fred Draked86ed291999-12-15 15:34:33 +00009793#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009795#endif
Fred Drakec9680921999-12-13 16:37:25 +00009796#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
Fred Draked86ed291999-12-15 15:34:33 +00009799#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009801#endif
9802#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009804#endif
Fred Drakec9680921999-12-13 16:37:25 +00009805#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
Fred Draked86ed291999-12-15 15:34:33 +00009817#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009819#endif
Fred Drakec9680921999-12-13 16:37:25 +00009820#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
9835#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
9838#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009840#endif
Fred Draked86ed291999-12-15 15:34:33 +00009841#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
Fred Drakec9680921999-12-13 16:37:25 +00009844#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009846#endif
9847#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009849#endif
Fred Draked86ed291999-12-15 15:34:33 +00009850#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009852#endif
Fred Drakec9680921999-12-13 16:37:25 +00009853#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
Fred Draked86ed291999-12-15 15:34:33 +00009880#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009882#endif
9883#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009885#endif
Fred Drakec9680921999-12-13 16:37:25 +00009886#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
9898#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009900#endif
9901#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009903#endif
9904#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009906#endif
9907#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
Fred Draked86ed291999-12-15 15:34:33 +00009991#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009993#endif
Fred Drakec9680921999-12-13 16:37:25 +00009994#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129};
10130
10131static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010132conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010133{
10134 return conv_confname(arg, valuep, posix_constants_sysconf,
10135 sizeof(posix_constants_sysconf)
10136 / sizeof(struct constdef));
10137}
10138
Larry Hastings2f936352014-08-05 14:04:04 +100010139
10140/*[clinic input]
10141os.sysconf -> long
10142 name: sysconf_confname
10143 /
10144
10145Return an integer-valued system configuration variable.
10146[clinic start generated code]*/
10147
Larry Hastings2f936352014-08-05 14:04:04 +100010148static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010149os_sysconf_impl(PyObject *module, int name)
10150/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010151{
10152 long value;
10153
10154 errno = 0;
10155 value = sysconf(name);
10156 if (value == -1 && errno != 0)
10157 posix_error();
10158 return value;
10159}
10160#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010161
10162
Fred Drakebec628d1999-12-15 18:31:10 +000010163/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010164 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010165 * the exported dictionaries that are used to publish information about the
10166 * names available on the host platform.
10167 *
10168 * Sorting the table at runtime ensures that the table is properly ordered
10169 * when used, even for platforms we're not able to test on. It also makes
10170 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010171 */
Fred Drakebec628d1999-12-15 18:31:10 +000010172
10173static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010174cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010175{
10176 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010178 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010180
10181 return strcmp(c1->name, c2->name);
10182}
10183
10184static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010185setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010186 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010187{
Fred Drakebec628d1999-12-15 18:31:10 +000010188 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010189 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010190
10191 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10192 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010193 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010195
Barry Warsaw3155db32000-04-13 15:20:40 +000010196 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 PyObject *o = PyLong_FromLong(table[i].value);
10198 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10199 Py_XDECREF(o);
10200 Py_DECREF(d);
10201 return -1;
10202 }
10203 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010204 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010205 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010206}
10207
Fred Drakebec628d1999-12-15 18:31:10 +000010208/* Return -1 on failure, 0 on success. */
10209static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010210setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010211{
10212#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010213 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010214 sizeof(posix_constants_pathconf)
10215 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010216 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010217 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010218#endif
10219#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010220 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010221 sizeof(posix_constants_confstr)
10222 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010223 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010224 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010225#endif
10226#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010227 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010228 sizeof(posix_constants_sysconf)
10229 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010230 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010231 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010232#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010233 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010234}
Fred Draked86ed291999-12-15 15:34:33 +000010235
10236
Larry Hastings2f936352014-08-05 14:04:04 +100010237/*[clinic input]
10238os.abort
10239
10240Abort the interpreter immediately.
10241
10242This function 'dumps core' or otherwise fails in the hardest way possible
10243on the hosting operating system. This function never returns.
10244[clinic start generated code]*/
10245
Larry Hastings2f936352014-08-05 14:04:04 +100010246static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010247os_abort_impl(PyObject *module)
10248/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010249{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010250 abort();
10251 /*NOTREACHED*/
10252 Py_FatalError("abort() called from Python code didn't abort!");
10253 return NULL;
10254}
Fred Drakebec628d1999-12-15 18:31:10 +000010255
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010256#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010257/* Grab ShellExecute dynamically from shell32 */
10258static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010259static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10260 LPCWSTR, INT);
10261static int
10262check_ShellExecute()
10263{
10264 HINSTANCE hShell32;
10265
10266 /* only recheck */
10267 if (-1 == has_ShellExecute) {
10268 Py_BEGIN_ALLOW_THREADS
10269 hShell32 = LoadLibraryW(L"SHELL32");
10270 Py_END_ALLOW_THREADS
10271 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010272 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10273 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010274 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010275 } else {
10276 has_ShellExecute = 0;
10277 }
10278 }
10279 return has_ShellExecute;
10280}
10281
10282
Steve Dowercc16be82016-09-08 10:35:16 -070010283/*[clinic input]
10284os.startfile
10285 filepath: path_t
10286 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010287
Steve Dowercc16be82016-09-08 10:35:16 -070010288startfile(filepath [, operation])
10289
10290Start a file with its associated application.
10291
10292When "operation" is not specified or "open", this acts like
10293double-clicking the file in Explorer, or giving the file name as an
10294argument to the DOS "start" command: the file is opened with whatever
10295application (if any) its extension is associated.
10296When another "operation" is given, it specifies what should be done with
10297the file. A typical operation is "print".
10298
10299startfile returns as soon as the associated application is launched.
10300There is no option to wait for the application to close, and no way
10301to retrieve the application's exit status.
10302
10303The filepath is relative to the current directory. If you want to use
10304an absolute path, make sure the first character is not a slash ("/");
10305the underlying Win32 ShellExecute function doesn't work if it is.
10306[clinic start generated code]*/
10307
10308static PyObject *
10309os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10310/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10311{
10312 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010313
10314 if(!check_ShellExecute()) {
10315 /* If the OS doesn't have ShellExecute, return a
10316 NotImplementedError. */
10317 return PyErr_Format(PyExc_NotImplementedError,
10318 "startfile not available on this platform");
10319 }
10320
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010322 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010323 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 Py_END_ALLOW_THREADS
10325
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010327 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010328 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 }
Steve Dowercc16be82016-09-08 10:35:16 -070010330 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010331}
Larry Hastings2f936352014-08-05 14:04:04 +100010332#endif /* MS_WINDOWS */
10333
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010334
Martin v. Löwis438b5342002-12-27 10:16:42 +000010335#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010336/*[clinic input]
10337os.getloadavg
10338
10339Return average recent system load information.
10340
10341Return the number of processes in the system run queue averaged over
10342the last 1, 5, and 15 minutes as a tuple of three floats.
10343Raises OSError if the load average was unobtainable.
10344[clinic start generated code]*/
10345
Larry Hastings2f936352014-08-05 14:04:04 +100010346static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010347os_getloadavg_impl(PyObject *module)
10348/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010349{
10350 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010351 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010352 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10353 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010354 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010355 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010356}
Larry Hastings2f936352014-08-05 14:04:04 +100010357#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010358
Larry Hastings2f936352014-08-05 14:04:04 +100010359
10360/*[clinic input]
10361os.device_encoding
10362 fd: int
10363
10364Return a string describing the encoding of a terminal's file descriptor.
10365
10366The file descriptor must be attached to a terminal.
10367If the device is not a terminal, return None.
10368[clinic start generated code]*/
10369
Larry Hastings2f936352014-08-05 14:04:04 +100010370static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010371os_device_encoding_impl(PyObject *module, int fd)
10372/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010373{
Brett Cannonefb00c02012-02-29 18:31:31 -050010374 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010375}
10376
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010377
Larry Hastings2f936352014-08-05 14:04:04 +100010378#ifdef HAVE_SETRESUID
10379/*[clinic input]
10380os.setresuid
10381
10382 ruid: uid_t
10383 euid: uid_t
10384 suid: uid_t
10385 /
10386
10387Set the current process's real, effective, and saved user ids.
10388[clinic start generated code]*/
10389
Larry Hastings2f936352014-08-05 14:04:04 +100010390static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010391os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10392/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010393{
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 if (setresuid(ruid, euid, suid) < 0)
10395 return posix_error();
10396 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010397}
Larry Hastings2f936352014-08-05 14:04:04 +100010398#endif /* HAVE_SETRESUID */
10399
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010400
10401#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010402/*[clinic input]
10403os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010404
Larry Hastings2f936352014-08-05 14:04:04 +100010405 rgid: gid_t
10406 egid: gid_t
10407 sgid: gid_t
10408 /
10409
10410Set the current process's real, effective, and saved group ids.
10411[clinic start generated code]*/
10412
Larry Hastings2f936352014-08-05 14:04:04 +100010413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010414os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10415/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010416{
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 if (setresgid(rgid, egid, sgid) < 0)
10418 return posix_error();
10419 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010420}
Larry Hastings2f936352014-08-05 14:04:04 +100010421#endif /* HAVE_SETRESGID */
10422
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010423
10424#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010425/*[clinic input]
10426os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010427
Larry Hastings2f936352014-08-05 14:04:04 +100010428Return a tuple of the current process's real, effective, and saved user ids.
10429[clinic start generated code]*/
10430
Larry Hastings2f936352014-08-05 14:04:04 +100010431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010432os_getresuid_impl(PyObject *module)
10433/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010434{
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 if (getresuid(&ruid, &euid, &suid) < 0)
10437 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010438 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10439 _PyLong_FromUid(euid),
10440 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010441}
Larry Hastings2f936352014-08-05 14:04:04 +100010442#endif /* HAVE_GETRESUID */
10443
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010444
10445#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010446/*[clinic input]
10447os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010448
Larry Hastings2f936352014-08-05 14:04:04 +100010449Return a tuple of the current process's real, effective, and saved group ids.
10450[clinic start generated code]*/
10451
Larry Hastings2f936352014-08-05 14:04:04 +100010452static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010453os_getresgid_impl(PyObject *module)
10454/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010455{
10456 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010457 if (getresgid(&rgid, &egid, &sgid) < 0)
10458 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010459 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10460 _PyLong_FromGid(egid),
10461 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010462}
Larry Hastings2f936352014-08-05 14:04:04 +100010463#endif /* HAVE_GETRESGID */
10464
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010465
Benjamin Peterson9428d532011-09-14 11:45:52 -040010466#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010467/*[clinic input]
10468os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010469
Larry Hastings2f936352014-08-05 14:04:04 +100010470 path: path_t(allow_fd=True)
10471 attribute: path_t
10472 *
10473 follow_symlinks: bool = True
10474
10475Return the value of extended attribute attribute on path.
10476
10477path may be either a string or an open file descriptor.
10478If follow_symlinks is False, and the last element of the path is a symbolic
10479 link, getxattr will examine the symbolic link itself instead of the file
10480 the link points to.
10481
10482[clinic start generated code]*/
10483
Larry Hastings2f936352014-08-05 14:04:04 +100010484static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010485os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010486 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010487/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010488{
10489 Py_ssize_t i;
10490 PyObject *buffer = NULL;
10491
10492 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10493 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010494
Larry Hastings9cf065c2012-06-22 16:30:09 -070010495 for (i = 0; ; i++) {
10496 void *ptr;
10497 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010498 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010499 Py_ssize_t buffer_size = buffer_sizes[i];
10500 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010501 path_error(path);
10502 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010503 }
10504 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10505 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010506 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010507 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010508
Larry Hastings9cf065c2012-06-22 16:30:09 -070010509 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010510 if (path->fd >= 0)
10511 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010512 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010513 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010514 else
Larry Hastings2f936352014-08-05 14:04:04 +100010515 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010516 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010517
Larry Hastings9cf065c2012-06-22 16:30:09 -070010518 if (result < 0) {
10519 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010520 if (errno == ERANGE)
10521 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010522 path_error(path);
10523 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010524 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010525
Larry Hastings9cf065c2012-06-22 16:30:09 -070010526 if (result != buffer_size) {
10527 /* Can only shrink. */
10528 _PyBytes_Resize(&buffer, result);
10529 }
10530 break;
10531 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010532
Larry Hastings9cf065c2012-06-22 16:30:09 -070010533 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010534}
10535
Larry Hastings2f936352014-08-05 14:04:04 +100010536
10537/*[clinic input]
10538os.setxattr
10539
10540 path: path_t(allow_fd=True)
10541 attribute: path_t
10542 value: Py_buffer
10543 flags: int = 0
10544 *
10545 follow_symlinks: bool = True
10546
10547Set extended attribute attribute on path to value.
10548
10549path may be either a string or an open file descriptor.
10550If follow_symlinks is False, and the last element of the path is a symbolic
10551 link, setxattr will modify the symbolic link itself instead of the file
10552 the link points to.
10553
10554[clinic start generated code]*/
10555
Benjamin Peterson799bd802011-08-31 22:15:17 -040010556static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010557os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010558 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010559/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010560{
Larry Hastings2f936352014-08-05 14:04:04 +100010561 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010562
Larry Hastings2f936352014-08-05 14:04:04 +100010563 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010565
Benjamin Peterson799bd802011-08-31 22:15:17 -040010566 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010567 if (path->fd > -1)
10568 result = fsetxattr(path->fd, attribute->narrow,
10569 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010570 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010571 result = setxattr(path->narrow, attribute->narrow,
10572 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573 else
Larry Hastings2f936352014-08-05 14:04:04 +100010574 result = lsetxattr(path->narrow, attribute->narrow,
10575 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010576 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010577
Larry Hastings9cf065c2012-06-22 16:30:09 -070010578 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010579 path_error(path);
10580 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010581 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010582
Larry Hastings2f936352014-08-05 14:04:04 +100010583 Py_RETURN_NONE;
10584}
10585
10586
10587/*[clinic input]
10588os.removexattr
10589
10590 path: path_t(allow_fd=True)
10591 attribute: path_t
10592 *
10593 follow_symlinks: bool = True
10594
10595Remove extended attribute attribute on path.
10596
10597path may be either a string or an open file descriptor.
10598If follow_symlinks is False, and the last element of the path is a symbolic
10599 link, removexattr will modify the symbolic link itself instead of the file
10600 the link points to.
10601
10602[clinic start generated code]*/
10603
Larry Hastings2f936352014-08-05 14:04:04 +100010604static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010605os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010606 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010607/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010608{
10609 ssize_t result;
10610
10611 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10612 return NULL;
10613
10614 Py_BEGIN_ALLOW_THREADS;
10615 if (path->fd > -1)
10616 result = fremovexattr(path->fd, attribute->narrow);
10617 else if (follow_symlinks)
10618 result = removexattr(path->narrow, attribute->narrow);
10619 else
10620 result = lremovexattr(path->narrow, attribute->narrow);
10621 Py_END_ALLOW_THREADS;
10622
10623 if (result) {
10624 return path_error(path);
10625 }
10626
10627 Py_RETURN_NONE;
10628}
10629
10630
10631/*[clinic input]
10632os.listxattr
10633
10634 path: path_t(allow_fd=True, nullable=True) = None
10635 *
10636 follow_symlinks: bool = True
10637
10638Return a list of extended attributes on path.
10639
10640path may be either None, a string, or an open file descriptor.
10641if path is None, listxattr will examine the current directory.
10642If follow_symlinks is False, and the last element of the path is a symbolic
10643 link, listxattr will examine the symbolic link itself instead of the file
10644 the link points to.
10645[clinic start generated code]*/
10646
Larry Hastings2f936352014-08-05 14:04:04 +100010647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010648os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10649/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010650{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010651 Py_ssize_t i;
10652 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010653 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010654 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010655
Larry Hastings2f936352014-08-05 14:04:04 +100010656 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010657 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010658
Larry Hastings2f936352014-08-05 14:04:04 +100010659 name = path->narrow ? path->narrow : ".";
10660
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010662 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010663 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010664 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665 Py_ssize_t buffer_size = buffer_sizes[i];
10666 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010667 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010668 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010669 break;
10670 }
10671 buffer = PyMem_MALLOC(buffer_size);
10672 if (!buffer) {
10673 PyErr_NoMemory();
10674 break;
10675 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010676
Larry Hastings9cf065c2012-06-22 16:30:09 -070010677 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010678 if (path->fd > -1)
10679 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010680 else if (follow_symlinks)
10681 length = listxattr(name, buffer, buffer_size);
10682 else
10683 length = llistxattr(name, buffer, buffer_size);
10684 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010685
Larry Hastings9cf065c2012-06-22 16:30:09 -070010686 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010687 if (errno == ERANGE) {
10688 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010689 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010691 }
Larry Hastings2f936352014-08-05 14:04:04 +100010692 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010693 break;
10694 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010695
Larry Hastings9cf065c2012-06-22 16:30:09 -070010696 result = PyList_New(0);
10697 if (!result) {
10698 goto exit;
10699 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010700
Larry Hastings9cf065c2012-06-22 16:30:09 -070010701 end = buffer + length;
10702 for (trace = start = buffer; trace != end; trace++) {
10703 if (!*trace) {
10704 int error;
10705 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10706 trace - start);
10707 if (!attribute) {
10708 Py_DECREF(result);
10709 result = NULL;
10710 goto exit;
10711 }
10712 error = PyList_Append(result, attribute);
10713 Py_DECREF(attribute);
10714 if (error) {
10715 Py_DECREF(result);
10716 result = NULL;
10717 goto exit;
10718 }
10719 start = trace + 1;
10720 }
10721 }
10722 break;
10723 }
10724exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010725 if (buffer)
10726 PyMem_FREE(buffer);
10727 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010728}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010729#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010730
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010731
Larry Hastings2f936352014-08-05 14:04:04 +100010732/*[clinic input]
10733os.urandom
10734
10735 size: Py_ssize_t
10736 /
10737
10738Return a bytes object containing random bytes suitable for cryptographic use.
10739[clinic start generated code]*/
10740
Larry Hastings2f936352014-08-05 14:04:04 +100010741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010742os_urandom_impl(PyObject *module, Py_ssize_t size)
10743/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010744{
10745 PyObject *bytes;
10746 int result;
10747
Georg Brandl2fb477c2012-02-21 00:33:36 +010010748 if (size < 0)
10749 return PyErr_Format(PyExc_ValueError,
10750 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010751 bytes = PyBytes_FromStringAndSize(NULL, size);
10752 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010753 return NULL;
10754
Victor Stinnere66987e2016-09-06 16:33:52 -070010755 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010756 if (result == -1) {
10757 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010758 return NULL;
10759 }
Larry Hastings2f936352014-08-05 14:04:04 +100010760 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010761}
10762
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010763/* Terminal size querying */
10764
10765static PyTypeObject TerminalSizeType;
10766
10767PyDoc_STRVAR(TerminalSize_docstring,
10768 "A tuple of (columns, lines) for holding terminal window size");
10769
10770static PyStructSequence_Field TerminalSize_fields[] = {
10771 {"columns", "width of the terminal window in characters"},
10772 {"lines", "height of the terminal window in characters"},
10773 {NULL, NULL}
10774};
10775
10776static PyStructSequence_Desc TerminalSize_desc = {
10777 "os.terminal_size",
10778 TerminalSize_docstring,
10779 TerminalSize_fields,
10780 2,
10781};
10782
10783#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010784/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010785PyDoc_STRVAR(termsize__doc__,
10786 "Return the size of the terminal window as (columns, lines).\n" \
10787 "\n" \
10788 "The optional argument fd (default standard output) specifies\n" \
10789 "which file descriptor should be queried.\n" \
10790 "\n" \
10791 "If the file descriptor is not connected to a terminal, an OSError\n" \
10792 "is thrown.\n" \
10793 "\n" \
10794 "This function will only be defined if an implementation is\n" \
10795 "available for this system.\n" \
10796 "\n" \
10797 "shutil.get_terminal_size is the high-level function which should \n" \
10798 "normally be used, os.get_terminal_size is the low-level implementation.");
10799
10800static PyObject*
10801get_terminal_size(PyObject *self, PyObject *args)
10802{
10803 int columns, lines;
10804 PyObject *termsize;
10805
10806 int fd = fileno(stdout);
10807 /* Under some conditions stdout may not be connected and
10808 * fileno(stdout) may point to an invalid file descriptor. For example
10809 * GUI apps don't have valid standard streams by default.
10810 *
10811 * If this happens, and the optional fd argument is not present,
10812 * the ioctl below will fail returning EBADF. This is what we want.
10813 */
10814
10815 if (!PyArg_ParseTuple(args, "|i", &fd))
10816 return NULL;
10817
10818#ifdef TERMSIZE_USE_IOCTL
10819 {
10820 struct winsize w;
10821 if (ioctl(fd, TIOCGWINSZ, &w))
10822 return PyErr_SetFromErrno(PyExc_OSError);
10823 columns = w.ws_col;
10824 lines = w.ws_row;
10825 }
10826#endif /* TERMSIZE_USE_IOCTL */
10827
10828#ifdef TERMSIZE_USE_CONIO
10829 {
10830 DWORD nhandle;
10831 HANDLE handle;
10832 CONSOLE_SCREEN_BUFFER_INFO csbi;
10833 switch (fd) {
10834 case 0: nhandle = STD_INPUT_HANDLE;
10835 break;
10836 case 1: nhandle = STD_OUTPUT_HANDLE;
10837 break;
10838 case 2: nhandle = STD_ERROR_HANDLE;
10839 break;
10840 default:
10841 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10842 }
10843 handle = GetStdHandle(nhandle);
10844 if (handle == NULL)
10845 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10846 if (handle == INVALID_HANDLE_VALUE)
10847 return PyErr_SetFromWindowsErr(0);
10848
10849 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10850 return PyErr_SetFromWindowsErr(0);
10851
10852 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10853 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10854 }
10855#endif /* TERMSIZE_USE_CONIO */
10856
10857 termsize = PyStructSequence_New(&TerminalSizeType);
10858 if (termsize == NULL)
10859 return NULL;
10860 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10861 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10862 if (PyErr_Occurred()) {
10863 Py_DECREF(termsize);
10864 return NULL;
10865 }
10866 return termsize;
10867}
10868#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10869
Larry Hastings2f936352014-08-05 14:04:04 +100010870
10871/*[clinic input]
10872os.cpu_count
10873
Charles-François Natali80d62e62015-08-13 20:37:08 +010010874Return the number of CPUs in the system; return None if indeterminable.
10875
10876This number is not equivalent to the number of CPUs the current process can
10877use. The number of usable CPUs can be obtained with
10878``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010879[clinic start generated code]*/
10880
Larry Hastings2f936352014-08-05 14:04:04 +100010881static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010882os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010883/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010884{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010885 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010886#ifdef MS_WINDOWS
10887 SYSTEM_INFO sysinfo;
10888 GetSystemInfo(&sysinfo);
10889 ncpu = sysinfo.dwNumberOfProcessors;
10890#elif defined(__hpux)
10891 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10892#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10893 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010894#elif defined(__DragonFly__) || \
10895 defined(__OpenBSD__) || \
10896 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010897 defined(__NetBSD__) || \
10898 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010899 int mib[2];
10900 size_t len = sizeof(ncpu);
10901 mib[0] = CTL_HW;
10902 mib[1] = HW_NCPU;
10903 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10904 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010905#endif
10906 if (ncpu >= 1)
10907 return PyLong_FromLong(ncpu);
10908 else
10909 Py_RETURN_NONE;
10910}
10911
Victor Stinnerdaf45552013-08-28 00:53:59 +020010912
Larry Hastings2f936352014-08-05 14:04:04 +100010913/*[clinic input]
10914os.get_inheritable -> bool
10915
10916 fd: int
10917 /
10918
10919Get the close-on-exe flag of the specified file descriptor.
10920[clinic start generated code]*/
10921
Larry Hastings2f936352014-08-05 14:04:04 +100010922static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010923os_get_inheritable_impl(PyObject *module, int fd)
10924/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010925{
Steve Dower8fc89802015-04-12 00:26:27 -040010926 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040010927 _Py_BEGIN_SUPPRESS_IPH
10928 return_value = _Py_get_inheritable(fd);
10929 _Py_END_SUPPRESS_IPH
10930 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010931}
10932
10933
10934/*[clinic input]
10935os.set_inheritable
10936 fd: int
10937 inheritable: int
10938 /
10939
10940Set the inheritable flag of the specified file descriptor.
10941[clinic start generated code]*/
10942
Larry Hastings2f936352014-08-05 14:04:04 +100010943static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010944os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
10945/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020010946{
Steve Dower8fc89802015-04-12 00:26:27 -040010947 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010948
Steve Dower8fc89802015-04-12 00:26:27 -040010949 _Py_BEGIN_SUPPRESS_IPH
10950 result = _Py_set_inheritable(fd, inheritable, NULL);
10951 _Py_END_SUPPRESS_IPH
10952 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020010953 return NULL;
10954 Py_RETURN_NONE;
10955}
10956
10957
10958#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010959/*[clinic input]
10960os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070010961 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100010962 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020010963
Larry Hastings2f936352014-08-05 14:04:04 +100010964Get the close-on-exe flag of the specified file descriptor.
10965[clinic start generated code]*/
10966
Larry Hastings2f936352014-08-05 14:04:04 +100010967static int
Benjamin Petersonca470632016-09-06 13:47:26 -070010968os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070010969/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010970{
10971 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010972
10973 if (!GetHandleInformation((HANDLE)handle, &flags)) {
10974 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100010975 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010976 }
10977
Larry Hastings2f936352014-08-05 14:04:04 +100010978 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010979}
10980
Victor Stinnerdaf45552013-08-28 00:53:59 +020010981
Larry Hastings2f936352014-08-05 14:04:04 +100010982/*[clinic input]
10983os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070010984 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100010985 inheritable: bool
10986 /
10987
10988Set the inheritable flag of the specified handle.
10989[clinic start generated code]*/
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070010992os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040010993 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070010994/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010995{
10996 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010997 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
10998 PyErr_SetFromWindowsErr(0);
10999 return NULL;
11000 }
11001 Py_RETURN_NONE;
11002}
Larry Hastings2f936352014-08-05 14:04:04 +100011003#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011004
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011005#ifndef MS_WINDOWS
11006PyDoc_STRVAR(get_blocking__doc__,
11007 "get_blocking(fd) -> bool\n" \
11008 "\n" \
11009 "Get the blocking mode of the file descriptor:\n" \
11010 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11011
11012static PyObject*
11013posix_get_blocking(PyObject *self, PyObject *args)
11014{
11015 int fd;
11016 int blocking;
11017
11018 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11019 return NULL;
11020
Steve Dower8fc89802015-04-12 00:26:27 -040011021 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011022 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011023 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011024 if (blocking < 0)
11025 return NULL;
11026 return PyBool_FromLong(blocking);
11027}
11028
11029PyDoc_STRVAR(set_blocking__doc__,
11030 "set_blocking(fd, blocking)\n" \
11031 "\n" \
11032 "Set the blocking mode of the specified file descriptor.\n" \
11033 "Set the O_NONBLOCK flag if blocking is False,\n" \
11034 "clear the O_NONBLOCK flag otherwise.");
11035
11036static PyObject*
11037posix_set_blocking(PyObject *self, PyObject *args)
11038{
Steve Dower8fc89802015-04-12 00:26:27 -040011039 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011040
11041 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11042 return NULL;
11043
Steve Dower8fc89802015-04-12 00:26:27 -040011044 _Py_BEGIN_SUPPRESS_IPH
11045 result = _Py_set_blocking(fd, blocking);
11046 _Py_END_SUPPRESS_IPH
11047 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011048 return NULL;
11049 Py_RETURN_NONE;
11050}
11051#endif /* !MS_WINDOWS */
11052
11053
Victor Stinner6036e442015-03-08 01:58:04 +010011054PyDoc_STRVAR(posix_scandir__doc__,
11055"scandir(path='.') -> iterator of DirEntry objects for given path");
11056
11057static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11058
11059typedef struct {
11060 PyObject_HEAD
11061 PyObject *name;
11062 PyObject *path;
11063 PyObject *stat;
11064 PyObject *lstat;
11065#ifdef MS_WINDOWS
11066 struct _Py_stat_struct win32_lstat;
11067 __int64 win32_file_index;
11068 int got_file_index;
11069#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011070#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011071 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011072#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011073 ino_t d_ino;
11074#endif
11075} DirEntry;
11076
11077static void
11078DirEntry_dealloc(DirEntry *entry)
11079{
11080 Py_XDECREF(entry->name);
11081 Py_XDECREF(entry->path);
11082 Py_XDECREF(entry->stat);
11083 Py_XDECREF(entry->lstat);
11084 Py_TYPE(entry)->tp_free((PyObject *)entry);
11085}
11086
11087/* Forward reference */
11088static int
11089DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11090
11091/* Set exception and return -1 on error, 0 for False, 1 for True */
11092static int
11093DirEntry_is_symlink(DirEntry *self)
11094{
11095#ifdef MS_WINDOWS
11096 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011097#elif defined(HAVE_DIRENT_D_TYPE)
11098 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011099 if (self->d_type != DT_UNKNOWN)
11100 return self->d_type == DT_LNK;
11101 else
11102 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011103#else
11104 /* POSIX without d_type */
11105 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011106#endif
11107}
11108
11109static PyObject *
11110DirEntry_py_is_symlink(DirEntry *self)
11111{
11112 int result;
11113
11114 result = DirEntry_is_symlink(self);
11115 if (result == -1)
11116 return NULL;
11117 return PyBool_FromLong(result);
11118}
11119
11120static PyObject *
11121DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11122{
11123 int result;
11124 struct _Py_stat_struct st;
11125
11126#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011127 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011128
11129 path = PyUnicode_AsUnicode(self->path);
11130 if (!path)
11131 return NULL;
11132
11133 if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -070011134 result = win32_stat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011135 else
Steve Dowercc16be82016-09-08 10:35:16 -070011136 result = win32_lstat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011137
11138 if (result != 0) {
11139 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11140 0, self->path);
11141 }
11142#else /* POSIX */
11143 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011144 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011145
11146 if (!PyUnicode_FSConverter(self->path, &bytes))
11147 return NULL;
11148 path = PyBytes_AS_STRING(bytes);
11149
11150 if (follow_symlinks)
11151 result = STAT(path, &st);
11152 else
11153 result = LSTAT(path, &st);
11154 Py_DECREF(bytes);
11155
11156 if (result != 0)
11157 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11158#endif
11159
11160 return _pystat_fromstructstat(&st);
11161}
11162
11163static PyObject *
11164DirEntry_get_lstat(DirEntry *self)
11165{
11166 if (!self->lstat) {
11167#ifdef MS_WINDOWS
11168 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11169#else /* POSIX */
11170 self->lstat = DirEntry_fetch_stat(self, 0);
11171#endif
11172 }
11173 Py_XINCREF(self->lstat);
11174 return self->lstat;
11175}
11176
11177static PyObject *
11178DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11179{
11180 if (!follow_symlinks)
11181 return DirEntry_get_lstat(self);
11182
11183 if (!self->stat) {
11184 int result = DirEntry_is_symlink(self);
11185 if (result == -1)
11186 return NULL;
11187 else if (result)
11188 self->stat = DirEntry_fetch_stat(self, 1);
11189 else
11190 self->stat = DirEntry_get_lstat(self);
11191 }
11192
11193 Py_XINCREF(self->stat);
11194 return self->stat;
11195}
11196
11197static PyObject *
11198DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11199{
11200 int follow_symlinks = 1;
11201
11202 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11203 follow_symlinks_keywords, &follow_symlinks))
11204 return NULL;
11205
11206 return DirEntry_get_stat(self, follow_symlinks);
11207}
11208
11209/* Set exception and return -1 on error, 0 for False, 1 for True */
11210static int
11211DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11212{
11213 PyObject *stat = NULL;
11214 PyObject *st_mode = NULL;
11215 long mode;
11216 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011217#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011218 int is_symlink;
11219 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011220#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011221#ifdef MS_WINDOWS
11222 unsigned long dir_bits;
11223#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011224 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011225
11226#ifdef MS_WINDOWS
11227 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11228 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011229#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011230 is_symlink = self->d_type == DT_LNK;
11231 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11232#endif
11233
Victor Stinner35a97c02015-03-08 02:59:09 +010011234#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011235 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011236#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011237 stat = DirEntry_get_stat(self, follow_symlinks);
11238 if (!stat) {
11239 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11240 /* If file doesn't exist (anymore), then return False
11241 (i.e., say it's not a file/directory) */
11242 PyErr_Clear();
11243 return 0;
11244 }
11245 goto error;
11246 }
11247 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11248 if (!st_mode)
11249 goto error;
11250
11251 mode = PyLong_AsLong(st_mode);
11252 if (mode == -1 && PyErr_Occurred())
11253 goto error;
11254 Py_CLEAR(st_mode);
11255 Py_CLEAR(stat);
11256 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011257#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011258 }
11259 else if (is_symlink) {
11260 assert(mode_bits != S_IFLNK);
11261 result = 0;
11262 }
11263 else {
11264 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11265#ifdef MS_WINDOWS
11266 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11267 if (mode_bits == S_IFDIR)
11268 result = dir_bits != 0;
11269 else
11270 result = dir_bits == 0;
11271#else /* POSIX */
11272 if (mode_bits == S_IFDIR)
11273 result = self->d_type == DT_DIR;
11274 else
11275 result = self->d_type == DT_REG;
11276#endif
11277 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011278#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011279
11280 return result;
11281
11282error:
11283 Py_XDECREF(st_mode);
11284 Py_XDECREF(stat);
11285 return -1;
11286}
11287
11288static PyObject *
11289DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11290{
11291 int result;
11292
11293 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11294 if (result == -1)
11295 return NULL;
11296 return PyBool_FromLong(result);
11297}
11298
11299static PyObject *
11300DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11301{
11302 int follow_symlinks = 1;
11303
11304 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11305 follow_symlinks_keywords, &follow_symlinks))
11306 return NULL;
11307
11308 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11309}
11310
11311static PyObject *
11312DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11313{
11314 int follow_symlinks = 1;
11315
11316 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11317 follow_symlinks_keywords, &follow_symlinks))
11318 return NULL;
11319
11320 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11321}
11322
11323static PyObject *
11324DirEntry_inode(DirEntry *self)
11325{
11326#ifdef MS_WINDOWS
11327 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011328 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011329 struct _Py_stat_struct stat;
11330
11331 path = PyUnicode_AsUnicode(self->path);
11332 if (!path)
11333 return NULL;
11334
Steve Dowercc16be82016-09-08 10:35:16 -070011335 if (win32_lstat(path, &stat) != 0) {
Victor Stinner6036e442015-03-08 01:58:04 +010011336 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11337 0, self->path);
11338 }
11339
11340 self->win32_file_index = stat.st_ino;
11341 self->got_file_index = 1;
11342 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011343 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011344#else /* POSIX */
11345#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011346 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011347#else
11348 return PyLong_FromLong((long)self->d_ino);
11349#endif
11350#endif
11351}
11352
11353static PyObject *
11354DirEntry_repr(DirEntry *self)
11355{
11356 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11357}
11358
Brett Cannon96881cd2016-06-10 14:37:21 -070011359static PyObject *
11360DirEntry_fspath(DirEntry *self)
11361{
11362 Py_INCREF(self->path);
11363 return self->path;
11364}
11365
Victor Stinner6036e442015-03-08 01:58:04 +010011366static PyMemberDef DirEntry_members[] = {
11367 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11368 "the entry's base filename, relative to scandir() \"path\" argument"},
11369 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11370 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11371 {NULL}
11372};
11373
11374static PyMethodDef DirEntry_methods[] = {
11375 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11376 "return True if the entry is a directory; cached per entry"
11377 },
11378 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11379 "return True if the entry is a file; cached per entry"
11380 },
11381 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11382 "return True if the entry is a symbolic link; cached per entry"
11383 },
11384 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11385 "return stat_result object for the entry; cached per entry"
11386 },
11387 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11388 "return inode of the entry; cached per entry",
11389 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011390 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11391 "returns the path for the entry",
11392 },
Victor Stinner6036e442015-03-08 01:58:04 +010011393 {NULL}
11394};
11395
Benjamin Peterson5646de42015-04-12 17:56:34 -040011396static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011397 PyVarObject_HEAD_INIT(NULL, 0)
11398 MODNAME ".DirEntry", /* tp_name */
11399 sizeof(DirEntry), /* tp_basicsize */
11400 0, /* tp_itemsize */
11401 /* methods */
11402 (destructor)DirEntry_dealloc, /* tp_dealloc */
11403 0, /* tp_print */
11404 0, /* tp_getattr */
11405 0, /* tp_setattr */
11406 0, /* tp_compare */
11407 (reprfunc)DirEntry_repr, /* tp_repr */
11408 0, /* tp_as_number */
11409 0, /* tp_as_sequence */
11410 0, /* tp_as_mapping */
11411 0, /* tp_hash */
11412 0, /* tp_call */
11413 0, /* tp_str */
11414 0, /* tp_getattro */
11415 0, /* tp_setattro */
11416 0, /* tp_as_buffer */
11417 Py_TPFLAGS_DEFAULT, /* tp_flags */
11418 0, /* tp_doc */
11419 0, /* tp_traverse */
11420 0, /* tp_clear */
11421 0, /* tp_richcompare */
11422 0, /* tp_weaklistoffset */
11423 0, /* tp_iter */
11424 0, /* tp_iternext */
11425 DirEntry_methods, /* tp_methods */
11426 DirEntry_members, /* tp_members */
11427};
11428
11429#ifdef MS_WINDOWS
11430
11431static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011432join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011433{
11434 Py_ssize_t path_len;
11435 Py_ssize_t size;
11436 wchar_t *result;
11437 wchar_t ch;
11438
11439 if (!path_wide) { /* Default arg: "." */
11440 path_wide = L".";
11441 path_len = 1;
11442 }
11443 else {
11444 path_len = wcslen(path_wide);
11445 }
11446
11447 /* The +1's are for the path separator and the NUL */
11448 size = path_len + 1 + wcslen(filename) + 1;
11449 result = PyMem_New(wchar_t, size);
11450 if (!result) {
11451 PyErr_NoMemory();
11452 return NULL;
11453 }
11454 wcscpy(result, path_wide);
11455 if (path_len > 0) {
11456 ch = result[path_len - 1];
11457 if (ch != SEP && ch != ALTSEP && ch != L':')
11458 result[path_len++] = SEP;
11459 wcscpy(result + path_len, filename);
11460 }
11461 return result;
11462}
11463
11464static PyObject *
11465DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11466{
11467 DirEntry *entry;
11468 BY_HANDLE_FILE_INFORMATION file_info;
11469 ULONG reparse_tag;
11470 wchar_t *joined_path;
11471
11472 entry = PyObject_New(DirEntry, &DirEntryType);
11473 if (!entry)
11474 return NULL;
11475 entry->name = NULL;
11476 entry->path = NULL;
11477 entry->stat = NULL;
11478 entry->lstat = NULL;
11479 entry->got_file_index = 0;
11480
11481 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11482 if (!entry->name)
11483 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011484 if (path->narrow) {
11485 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11486 if (!entry->name)
11487 goto error;
11488 }
Victor Stinner6036e442015-03-08 01:58:04 +010011489
11490 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11491 if (!joined_path)
11492 goto error;
11493
11494 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11495 PyMem_Free(joined_path);
11496 if (!entry->path)
11497 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011498 if (path->narrow) {
11499 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11500 if (!entry->path)
11501 goto error;
11502 }
Victor Stinner6036e442015-03-08 01:58:04 +010011503
Steve Dowercc16be82016-09-08 10:35:16 -070011504 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011505 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11506
11507 return (PyObject *)entry;
11508
11509error:
11510 Py_DECREF(entry);
11511 return NULL;
11512}
11513
11514#else /* POSIX */
11515
11516static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011517join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011518{
11519 Py_ssize_t path_len;
11520 Py_ssize_t size;
11521 char *result;
11522
11523 if (!path_narrow) { /* Default arg: "." */
11524 path_narrow = ".";
11525 path_len = 1;
11526 }
11527 else {
11528 path_len = strlen(path_narrow);
11529 }
11530
11531 if (filename_len == -1)
11532 filename_len = strlen(filename);
11533
11534 /* The +1's are for the path separator and the NUL */
11535 size = path_len + 1 + filename_len + 1;
11536 result = PyMem_New(char, size);
11537 if (!result) {
11538 PyErr_NoMemory();
11539 return NULL;
11540 }
11541 strcpy(result, path_narrow);
11542 if (path_len > 0 && result[path_len - 1] != '/')
11543 result[path_len++] = '/';
11544 strcpy(result + path_len, filename);
11545 return result;
11546}
11547
11548static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011549DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011550 ino_t d_ino
11551#ifdef HAVE_DIRENT_D_TYPE
11552 , unsigned char d_type
11553#endif
11554 )
Victor Stinner6036e442015-03-08 01:58:04 +010011555{
11556 DirEntry *entry;
11557 char *joined_path;
11558
11559 entry = PyObject_New(DirEntry, &DirEntryType);
11560 if (!entry)
11561 return NULL;
11562 entry->name = NULL;
11563 entry->path = NULL;
11564 entry->stat = NULL;
11565 entry->lstat = NULL;
11566
11567 joined_path = join_path_filename(path->narrow, name, name_len);
11568 if (!joined_path)
11569 goto error;
11570
11571 if (!path->narrow || !PyBytes_Check(path->object)) {
11572 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11573 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11574 }
11575 else {
11576 entry->name = PyBytes_FromStringAndSize(name, name_len);
11577 entry->path = PyBytes_FromString(joined_path);
11578 }
11579 PyMem_Free(joined_path);
11580 if (!entry->name || !entry->path)
11581 goto error;
11582
Victor Stinner35a97c02015-03-08 02:59:09 +010011583#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011584 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011585#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011586 entry->d_ino = d_ino;
11587
11588 return (PyObject *)entry;
11589
11590error:
11591 Py_XDECREF(entry);
11592 return NULL;
11593}
11594
11595#endif
11596
11597
11598typedef struct {
11599 PyObject_HEAD
11600 path_t path;
11601#ifdef MS_WINDOWS
11602 HANDLE handle;
11603 WIN32_FIND_DATAW file_data;
11604 int first_time;
11605#else /* POSIX */
11606 DIR *dirp;
11607#endif
11608} ScandirIterator;
11609
11610#ifdef MS_WINDOWS
11611
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011612static int
11613ScandirIterator_is_closed(ScandirIterator *iterator)
11614{
11615 return iterator->handle == INVALID_HANDLE_VALUE;
11616}
11617
Victor Stinner6036e442015-03-08 01:58:04 +010011618static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011619ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011620{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011621 HANDLE handle = iterator->handle;
11622
11623 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011624 return;
11625
Victor Stinner6036e442015-03-08 01:58:04 +010011626 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011627 Py_BEGIN_ALLOW_THREADS
11628 FindClose(handle);
11629 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011630}
11631
11632static PyObject *
11633ScandirIterator_iternext(ScandirIterator *iterator)
11634{
11635 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11636 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011637 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011638
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011639 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011640 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011641 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011642
11643 while (1) {
11644 if (!iterator->first_time) {
11645 Py_BEGIN_ALLOW_THREADS
11646 success = FindNextFileW(iterator->handle, file_data);
11647 Py_END_ALLOW_THREADS
11648 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011649 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011650 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011651 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011652 break;
11653 }
11654 }
11655 iterator->first_time = 0;
11656
11657 /* Skip over . and .. */
11658 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011659 wcscmp(file_data->cFileName, L"..") != 0) {
11660 entry = DirEntry_from_find_data(&iterator->path, file_data);
11661 if (!entry)
11662 break;
11663 return entry;
11664 }
Victor Stinner6036e442015-03-08 01:58:04 +010011665
11666 /* Loop till we get a non-dot directory or finish iterating */
11667 }
11668
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011669 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011670 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011671 return NULL;
11672}
11673
11674#else /* POSIX */
11675
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011676static int
11677ScandirIterator_is_closed(ScandirIterator *iterator)
11678{
11679 return !iterator->dirp;
11680}
11681
Victor Stinner6036e442015-03-08 01:58:04 +010011682static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011683ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011684{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011685 DIR *dirp = iterator->dirp;
11686
11687 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011688 return;
11689
Victor Stinner6036e442015-03-08 01:58:04 +010011690 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011691 Py_BEGIN_ALLOW_THREADS
11692 closedir(dirp);
11693 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011694 return;
11695}
11696
11697static PyObject *
11698ScandirIterator_iternext(ScandirIterator *iterator)
11699{
11700 struct dirent *direntp;
11701 Py_ssize_t name_len;
11702 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011703 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011704
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011705 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011706 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011707 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011708
11709 while (1) {
11710 errno = 0;
11711 Py_BEGIN_ALLOW_THREADS
11712 direntp = readdir(iterator->dirp);
11713 Py_END_ALLOW_THREADS
11714
11715 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011716 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011717 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011718 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011719 break;
11720 }
11721
11722 /* Skip over . and .. */
11723 name_len = NAMLEN(direntp);
11724 is_dot = direntp->d_name[0] == '.' &&
11725 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11726 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011727 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011728 name_len, direntp->d_ino
11729#ifdef HAVE_DIRENT_D_TYPE
11730 , direntp->d_type
11731#endif
11732 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011733 if (!entry)
11734 break;
11735 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011736 }
11737
11738 /* Loop till we get a non-dot directory or finish iterating */
11739 }
11740
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011741 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011742 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011743 return NULL;
11744}
11745
11746#endif
11747
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011748static PyObject *
11749ScandirIterator_close(ScandirIterator *self, PyObject *args)
11750{
11751 ScandirIterator_closedir(self);
11752 Py_RETURN_NONE;
11753}
11754
11755static PyObject *
11756ScandirIterator_enter(PyObject *self, PyObject *args)
11757{
11758 Py_INCREF(self);
11759 return self;
11760}
11761
11762static PyObject *
11763ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11764{
11765 ScandirIterator_closedir(self);
11766 Py_RETURN_NONE;
11767}
11768
Victor Stinner6036e442015-03-08 01:58:04 +010011769static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011770ScandirIterator_finalize(ScandirIterator *iterator)
11771{
11772 PyObject *error_type, *error_value, *error_traceback;
11773
11774 /* Save the current exception, if any. */
11775 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11776
11777 if (!ScandirIterator_is_closed(iterator)) {
11778 ScandirIterator_closedir(iterator);
11779
11780 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11781 "unclosed scandir iterator %R", iterator)) {
11782 /* Spurious errors can appear at shutdown */
11783 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11784 PyErr_WriteUnraisable((PyObject *) iterator);
11785 }
11786 }
11787 }
11788
11789 Py_CLEAR(iterator->path.object);
11790 path_cleanup(&iterator->path);
11791
11792 /* Restore the saved exception. */
11793 PyErr_Restore(error_type, error_value, error_traceback);
11794}
11795
11796static void
Victor Stinner6036e442015-03-08 01:58:04 +010011797ScandirIterator_dealloc(ScandirIterator *iterator)
11798{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011799 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11800 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011801
Victor Stinner6036e442015-03-08 01:58:04 +010011802 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11803}
11804
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011805static PyMethodDef ScandirIterator_methods[] = {
11806 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11807 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11808 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11809 {NULL}
11810};
11811
Benjamin Peterson5646de42015-04-12 17:56:34 -040011812static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011813 PyVarObject_HEAD_INIT(NULL, 0)
11814 MODNAME ".ScandirIterator", /* tp_name */
11815 sizeof(ScandirIterator), /* tp_basicsize */
11816 0, /* tp_itemsize */
11817 /* methods */
11818 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11819 0, /* tp_print */
11820 0, /* tp_getattr */
11821 0, /* tp_setattr */
11822 0, /* tp_compare */
11823 0, /* tp_repr */
11824 0, /* tp_as_number */
11825 0, /* tp_as_sequence */
11826 0, /* tp_as_mapping */
11827 0, /* tp_hash */
11828 0, /* tp_call */
11829 0, /* tp_str */
11830 0, /* tp_getattro */
11831 0, /* tp_setattro */
11832 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011833 Py_TPFLAGS_DEFAULT
11834 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011835 0, /* tp_doc */
11836 0, /* tp_traverse */
11837 0, /* tp_clear */
11838 0, /* tp_richcompare */
11839 0, /* tp_weaklistoffset */
11840 PyObject_SelfIter, /* tp_iter */
11841 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011842 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011843 0, /* tp_members */
11844 0, /* tp_getset */
11845 0, /* tp_base */
11846 0, /* tp_dict */
11847 0, /* tp_descr_get */
11848 0, /* tp_descr_set */
11849 0, /* tp_dictoffset */
11850 0, /* tp_init */
11851 0, /* tp_alloc */
11852 0, /* tp_new */
11853 0, /* tp_free */
11854 0, /* tp_is_gc */
11855 0, /* tp_bases */
11856 0, /* tp_mro */
11857 0, /* tp_cache */
11858 0, /* tp_subclasses */
11859 0, /* tp_weaklist */
11860 0, /* tp_del */
11861 0, /* tp_version_tag */
11862 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011863};
11864
11865static PyObject *
11866posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11867{
11868 ScandirIterator *iterator;
11869 static char *keywords[] = {"path", NULL};
11870#ifdef MS_WINDOWS
11871 wchar_t *path_strW;
11872#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011873 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011874#endif
11875
11876 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11877 if (!iterator)
11878 return NULL;
11879 memset(&iterator->path, 0, sizeof(path_t));
11880 iterator->path.function_name = "scandir";
11881 iterator->path.nullable = 1;
11882
11883#ifdef MS_WINDOWS
11884 iterator->handle = INVALID_HANDLE_VALUE;
11885#else
11886 iterator->dirp = NULL;
11887#endif
11888
11889 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11890 path_converter, &iterator->path))
11891 goto error;
11892
11893 /* path_converter doesn't keep path.object around, so do it
11894 manually for the lifetime of the iterator here (the refcount
11895 is decremented in ScandirIterator_dealloc)
11896 */
11897 Py_XINCREF(iterator->path.object);
11898
11899#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011900 iterator->first_time = 1;
11901
11902 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11903 if (!path_strW)
11904 goto error;
11905
11906 Py_BEGIN_ALLOW_THREADS
11907 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11908 Py_END_ALLOW_THREADS
11909
11910 PyMem_Free(path_strW);
11911
11912 if (iterator->handle == INVALID_HANDLE_VALUE) {
11913 path_error(&iterator->path);
11914 goto error;
11915 }
11916#else /* POSIX */
11917 if (iterator->path.narrow)
11918 path = iterator->path.narrow;
11919 else
11920 path = ".";
11921
11922 errno = 0;
11923 Py_BEGIN_ALLOW_THREADS
11924 iterator->dirp = opendir(path);
11925 Py_END_ALLOW_THREADS
11926
11927 if (!iterator->dirp) {
11928 path_error(&iterator->path);
11929 goto error;
11930 }
11931#endif
11932
11933 return (PyObject *)iterator;
11934
11935error:
11936 Py_DECREF(iterator);
11937 return NULL;
11938}
11939
Ethan Furman410ef8e2016-06-04 12:06:26 -070011940/*
11941 Return the file system path representation of the object.
11942
11943 If the object is str or bytes, then allow it to pass through with
11944 an incremented refcount. If the object defines __fspath__(), then
11945 return the result of that method. All other types raise a TypeError.
11946*/
11947PyObject *
11948PyOS_FSPath(PyObject *path)
11949{
Brett Cannon3f9183b2016-08-26 14:44:48 -070011950 /* For error message reasons, this function is manually inlined in
11951 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070011952 _Py_IDENTIFIER(__fspath__);
11953 PyObject *func = NULL;
11954 PyObject *path_repr = NULL;
11955
11956 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
11957 Py_INCREF(path);
11958 return path;
11959 }
11960
11961 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
11962 if (NULL == func) {
11963 return PyErr_Format(PyExc_TypeError,
11964 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070011965 "not %.200s",
11966 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070011967 }
11968
11969 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
11970 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070011971 if (NULL == path_repr) {
11972 return NULL;
11973 }
11974
Brett Cannonc78ca1e2016-06-24 12:03:43 -070011975 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
11976 PyErr_Format(PyExc_TypeError,
11977 "expected %.200s.__fspath__() to return str or bytes, "
11978 "not %.200s", Py_TYPE(path)->tp_name,
11979 Py_TYPE(path_repr)->tp_name);
11980 Py_DECREF(path_repr);
11981 return NULL;
11982 }
11983
Ethan Furman410ef8e2016-06-04 12:06:26 -070011984 return path_repr;
11985}
11986
11987/*[clinic input]
11988os.fspath
11989
11990 path: object
11991
11992Return the file system path representation of the object.
11993
Brett Cannonb4f43e92016-06-09 14:32:08 -070011994If the object is str or bytes, then allow it to pass through as-is. If the
11995object defines __fspath__(), then return the result of that method. All other
11996types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070011997[clinic start generated code]*/
11998
11999static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012000os_fspath_impl(PyObject *module, PyObject *path)
12001/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012002{
12003 return PyOS_FSPath(path);
12004}
Victor Stinner6036e442015-03-08 01:58:04 +010012005
Victor Stinner9b1f4742016-09-06 16:18:52 -070012006#ifdef HAVE_GETRANDOM_SYSCALL
12007/*[clinic input]
12008os.getrandom
12009
12010 size: Py_ssize_t
12011 flags: int=0
12012
12013Obtain a series of random bytes.
12014[clinic start generated code]*/
12015
12016static PyObject *
12017os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12018/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12019{
12020 char *buffer;
12021 Py_ssize_t n;
12022 PyObject *bytes;
12023
12024 if (size < 0) {
12025 errno = EINVAL;
12026 return posix_error();
12027 }
12028
12029 buffer = PyMem_Malloc(size);
12030 if (buffer == NULL) {
12031 PyErr_NoMemory();
12032 return NULL;
12033 }
12034
12035 while (1) {
12036 n = syscall(SYS_getrandom, buffer, size, flags);
12037 if (n < 0 && errno == EINTR) {
12038 if (PyErr_CheckSignals() < 0) {
12039 return NULL;
12040 }
12041 continue;
12042 }
12043 break;
12044 }
12045
12046 if (n < 0) {
12047 PyMem_Free(buffer);
12048 PyErr_SetFromErrno(PyExc_OSError);
12049 return NULL;
12050 }
12051
12052 bytes = PyBytes_FromStringAndSize(buffer, n);
12053 PyMem_Free(buffer);
12054
12055 return bytes;
12056}
12057#endif /* HAVE_GETRANDOM_SYSCALL */
12058
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012059#include "clinic/posixmodule.c.h"
12060
Larry Hastings7726ac92014-01-31 22:03:12 -080012061/*[clinic input]
12062dump buffer
12063[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012064/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012065
Larry Hastings31826802013-10-19 00:09:25 -070012066
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012067static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012068
12069 OS_STAT_METHODDEF
12070 OS_ACCESS_METHODDEF
12071 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012072 OS_CHDIR_METHODDEF
12073 OS_CHFLAGS_METHODDEF
12074 OS_CHMOD_METHODDEF
12075 OS_FCHMOD_METHODDEF
12076 OS_LCHMOD_METHODDEF
12077 OS_CHOWN_METHODDEF
12078 OS_FCHOWN_METHODDEF
12079 OS_LCHOWN_METHODDEF
12080 OS_LCHFLAGS_METHODDEF
12081 OS_CHROOT_METHODDEF
12082 OS_CTERMID_METHODDEF
12083 OS_GETCWD_METHODDEF
12084 OS_GETCWDB_METHODDEF
12085 OS_LINK_METHODDEF
12086 OS_LISTDIR_METHODDEF
12087 OS_LSTAT_METHODDEF
12088 OS_MKDIR_METHODDEF
12089 OS_NICE_METHODDEF
12090 OS_GETPRIORITY_METHODDEF
12091 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012092#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012093 {"readlink", (PyCFunction)posix_readlink,
12094 METH_VARARGS | METH_KEYWORDS,
12095 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012096#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012097#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012098 {"readlink", (PyCFunction)win_readlink,
12099 METH_VARARGS | METH_KEYWORDS,
12100 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012101#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012102 OS_RENAME_METHODDEF
12103 OS_REPLACE_METHODDEF
12104 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012105 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012106 OS_SYMLINK_METHODDEF
12107 OS_SYSTEM_METHODDEF
12108 OS_UMASK_METHODDEF
12109 OS_UNAME_METHODDEF
12110 OS_UNLINK_METHODDEF
12111 OS_REMOVE_METHODDEF
12112 OS_UTIME_METHODDEF
12113 OS_TIMES_METHODDEF
12114 OS__EXIT_METHODDEF
12115 OS_EXECV_METHODDEF
12116 OS_EXECVE_METHODDEF
12117 OS_SPAWNV_METHODDEF
12118 OS_SPAWNVE_METHODDEF
12119 OS_FORK1_METHODDEF
12120 OS_FORK_METHODDEF
12121 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12122 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12123 OS_SCHED_GETPARAM_METHODDEF
12124 OS_SCHED_GETSCHEDULER_METHODDEF
12125 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12126 OS_SCHED_SETPARAM_METHODDEF
12127 OS_SCHED_SETSCHEDULER_METHODDEF
12128 OS_SCHED_YIELD_METHODDEF
12129 OS_SCHED_SETAFFINITY_METHODDEF
12130 OS_SCHED_GETAFFINITY_METHODDEF
12131 OS_OPENPTY_METHODDEF
12132 OS_FORKPTY_METHODDEF
12133 OS_GETEGID_METHODDEF
12134 OS_GETEUID_METHODDEF
12135 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012136#ifdef HAVE_GETGROUPLIST
12137 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12138#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012139 OS_GETGROUPS_METHODDEF
12140 OS_GETPID_METHODDEF
12141 OS_GETPGRP_METHODDEF
12142 OS_GETPPID_METHODDEF
12143 OS_GETUID_METHODDEF
12144 OS_GETLOGIN_METHODDEF
12145 OS_KILL_METHODDEF
12146 OS_KILLPG_METHODDEF
12147 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012148#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012149 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012150#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012151 OS_SETUID_METHODDEF
12152 OS_SETEUID_METHODDEF
12153 OS_SETREUID_METHODDEF
12154 OS_SETGID_METHODDEF
12155 OS_SETEGID_METHODDEF
12156 OS_SETREGID_METHODDEF
12157 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012158#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012159 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012160#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012161 OS_GETPGID_METHODDEF
12162 OS_SETPGRP_METHODDEF
12163 OS_WAIT_METHODDEF
12164 OS_WAIT3_METHODDEF
12165 OS_WAIT4_METHODDEF
12166 OS_WAITID_METHODDEF
12167 OS_WAITPID_METHODDEF
12168 OS_GETSID_METHODDEF
12169 OS_SETSID_METHODDEF
12170 OS_SETPGID_METHODDEF
12171 OS_TCGETPGRP_METHODDEF
12172 OS_TCSETPGRP_METHODDEF
12173 OS_OPEN_METHODDEF
12174 OS_CLOSE_METHODDEF
12175 OS_CLOSERANGE_METHODDEF
12176 OS_DEVICE_ENCODING_METHODDEF
12177 OS_DUP_METHODDEF
12178 OS_DUP2_METHODDEF
12179 OS_LOCKF_METHODDEF
12180 OS_LSEEK_METHODDEF
12181 OS_READ_METHODDEF
12182 OS_READV_METHODDEF
12183 OS_PREAD_METHODDEF
12184 OS_WRITE_METHODDEF
12185 OS_WRITEV_METHODDEF
12186 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012187#ifdef HAVE_SENDFILE
12188 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12189 posix_sendfile__doc__},
12190#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012191 OS_FSTAT_METHODDEF
12192 OS_ISATTY_METHODDEF
12193 OS_PIPE_METHODDEF
12194 OS_PIPE2_METHODDEF
12195 OS_MKFIFO_METHODDEF
12196 OS_MKNOD_METHODDEF
12197 OS_MAJOR_METHODDEF
12198 OS_MINOR_METHODDEF
12199 OS_MAKEDEV_METHODDEF
12200 OS_FTRUNCATE_METHODDEF
12201 OS_TRUNCATE_METHODDEF
12202 OS_POSIX_FALLOCATE_METHODDEF
12203 OS_POSIX_FADVISE_METHODDEF
12204 OS_PUTENV_METHODDEF
12205 OS_UNSETENV_METHODDEF
12206 OS_STRERROR_METHODDEF
12207 OS_FCHDIR_METHODDEF
12208 OS_FSYNC_METHODDEF
12209 OS_SYNC_METHODDEF
12210 OS_FDATASYNC_METHODDEF
12211 OS_WCOREDUMP_METHODDEF
12212 OS_WIFCONTINUED_METHODDEF
12213 OS_WIFSTOPPED_METHODDEF
12214 OS_WIFSIGNALED_METHODDEF
12215 OS_WIFEXITED_METHODDEF
12216 OS_WEXITSTATUS_METHODDEF
12217 OS_WTERMSIG_METHODDEF
12218 OS_WSTOPSIG_METHODDEF
12219 OS_FSTATVFS_METHODDEF
12220 OS_STATVFS_METHODDEF
12221 OS_CONFSTR_METHODDEF
12222 OS_SYSCONF_METHODDEF
12223 OS_FPATHCONF_METHODDEF
12224 OS_PATHCONF_METHODDEF
12225 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012226 OS__GETFULLPATHNAME_METHODDEF
12227 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012228 OS__GETDISKUSAGE_METHODDEF
12229 OS__GETFINALPATHNAME_METHODDEF
12230 OS__GETVOLUMEPATHNAME_METHODDEF
12231 OS_GETLOADAVG_METHODDEF
12232 OS_URANDOM_METHODDEF
12233 OS_SETRESUID_METHODDEF
12234 OS_SETRESGID_METHODDEF
12235 OS_GETRESUID_METHODDEF
12236 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012237
Larry Hastings2f936352014-08-05 14:04:04 +100012238 OS_GETXATTR_METHODDEF
12239 OS_SETXATTR_METHODDEF
12240 OS_REMOVEXATTR_METHODDEF
12241 OS_LISTXATTR_METHODDEF
12242
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012243#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12244 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12245#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012246 OS_CPU_COUNT_METHODDEF
12247 OS_GET_INHERITABLE_METHODDEF
12248 OS_SET_INHERITABLE_METHODDEF
12249 OS_GET_HANDLE_INHERITABLE_METHODDEF
12250 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012251#ifndef MS_WINDOWS
12252 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12253 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12254#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012255 {"scandir", (PyCFunction)posix_scandir,
12256 METH_VARARGS | METH_KEYWORDS,
12257 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012258 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012259 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012260 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012261};
12262
12263
Brian Curtin52173d42010-12-02 18:29:18 +000012264#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012265static int
Brian Curtin52173d42010-12-02 18:29:18 +000012266enable_symlink()
12267{
12268 HANDLE tok;
12269 TOKEN_PRIVILEGES tok_priv;
12270 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012271
12272 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012273 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012274
12275 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012276 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012277
12278 tok_priv.PrivilegeCount = 1;
12279 tok_priv.Privileges[0].Luid = luid;
12280 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12281
12282 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12283 sizeof(TOKEN_PRIVILEGES),
12284 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012285 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012286
Brian Curtin3b4499c2010-12-28 14:31:47 +000012287 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12288 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012289}
12290#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12291
Barry Warsaw4a342091996-12-19 23:50:02 +000012292static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012293all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012294{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012295#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012296 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012297#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012298#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012299 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012300#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012301#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012302 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012303#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012304#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012305 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012306#endif
Fred Drakec9680921999-12-13 16:37:25 +000012307#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012308 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012309#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012310#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012311 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012312#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012313#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012314 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012315#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012316#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012317 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012318#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012319#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012320 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012321#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012322#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012323 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012324#endif
12325#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012326 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012327#endif
12328#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012329 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012330#endif
12331#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012332 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012333#endif
12334#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012335 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012336#endif
12337#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012338 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012339#endif
12340#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012341 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012342#endif
12343#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012344 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012345#endif
12346#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012347 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012348#endif
12349#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012350 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012351#endif
12352#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012353 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012354#endif
12355#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012356 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012357#endif
12358#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012359 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012360#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012361#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012362 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012363#endif
12364#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012365 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012366#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012367#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012368 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012369#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012370#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012371 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012372#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012373#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012374#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012375 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012376#endif
12377#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012378 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012379#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012380#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012381#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012383#endif
12384#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012386#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012387#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012389#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012390#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012392#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012393#ifdef O_TMPFILE
12394 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12395#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012396#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012398#endif
12399#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012401#endif
12402#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012404#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012405#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012407#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012408#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012410#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012411
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012412
Jesus Cea94363612012-06-22 18:32:07 +020012413#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012415#endif
12416#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012418#endif
12419
Tim Peters5aa91602002-01-30 05:46:57 +000012420/* MS Windows */
12421#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012422 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012424#endif
12425#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012426 /* Optimize for short life (keep in memory). */
12427 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012428 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012429#endif
12430#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012431 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012433#endif
12434#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012435 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012437#endif
12438#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012439 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012441#endif
12442
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012443/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012444#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012445 /* Send a SIGIO signal whenever input or output
12446 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012447 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012448#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012449#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012450 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012452#endif
12453#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012454 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012456#endif
12457#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012458 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012460#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012461#ifdef O_NOLINKS
12462 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012463 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012464#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012465#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012466 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012468#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012469
Victor Stinner8c62be82010-05-06 00:08:46 +000012470 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012471#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012472 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012473#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012474#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012475 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012476#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012477#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012478 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012479#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012480#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012481 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012482#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012483#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012484 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012485#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012486#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012487 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012488#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012489#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012490 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012491#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012492#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012493 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012494#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012495#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012497#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012498#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012499 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012500#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012501#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012502 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012503#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012504#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012506#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012507#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012508 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012509#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012510#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012512#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012513#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012514 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012515#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012516#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012517 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012518#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012519#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012520 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012521#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012522
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012523 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012524#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012525 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012526#endif /* ST_RDONLY */
12527#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012528 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012529#endif /* ST_NOSUID */
12530
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012531 /* GNU extensions */
12532#ifdef ST_NODEV
12533 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12534#endif /* ST_NODEV */
12535#ifdef ST_NOEXEC
12536 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12537#endif /* ST_NOEXEC */
12538#ifdef ST_SYNCHRONOUS
12539 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12540#endif /* ST_SYNCHRONOUS */
12541#ifdef ST_MANDLOCK
12542 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12543#endif /* ST_MANDLOCK */
12544#ifdef ST_WRITE
12545 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12546#endif /* ST_WRITE */
12547#ifdef ST_APPEND
12548 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12549#endif /* ST_APPEND */
12550#ifdef ST_NOATIME
12551 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12552#endif /* ST_NOATIME */
12553#ifdef ST_NODIRATIME
12554 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12555#endif /* ST_NODIRATIME */
12556#ifdef ST_RELATIME
12557 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12558#endif /* ST_RELATIME */
12559
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012560 /* FreeBSD sendfile() constants */
12561#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012563#endif
12564#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012565 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012566#endif
12567#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012568 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012569#endif
12570
Ross Lagerwall7807c352011-03-17 20:20:30 +020012571 /* constants for posix_fadvise */
12572#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012573 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012574#endif
12575#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012577#endif
12578#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012580#endif
12581#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012583#endif
12584#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012586#endif
12587#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012589#endif
12590
12591 /* constants for waitid */
12592#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12594 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12595 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012596#endif
12597#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012599#endif
12600#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012602#endif
12603#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012605#endif
12606#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012608#endif
12609#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012611#endif
12612#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012614#endif
12615#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012617#endif
12618
12619 /* constants for lockf */
12620#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012622#endif
12623#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012625#endif
12626#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012628#endif
12629#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012630 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012631#endif
12632
Guido van Rossum246bc171999-02-01 23:54:31 +000012633#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12635 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12636 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12637 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12638 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012639#endif
12640
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012641#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012642#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012644#endif
12645#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012647#endif
12648#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012650#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012651#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012653#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012654#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012656#endif
12657#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012659#endif
12660#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012662#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012663#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012665#endif
12666#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012668#endif
12669#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012671#endif
12672#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012674#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012675#endif
12676
Benjamin Peterson9428d532011-09-14 11:45:52 -040012677#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12679 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12680 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012681#endif
12682
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012683#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012685#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012686#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012688#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012689#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012691#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012692#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012694#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012695#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012697#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012698#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012700#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012701#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012702 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012703#endif
12704
Victor Stinner9b1f4742016-09-06 16:18:52 -070012705#ifdef HAVE_GETRANDOM_SYSCALL
12706 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12707 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12708#endif
12709
Victor Stinner8c62be82010-05-06 00:08:46 +000012710 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012711}
12712
12713
Martin v. Löwis1a214512008-06-11 05:26:20 +000012714static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012715 PyModuleDef_HEAD_INIT,
12716 MODNAME,
12717 posix__doc__,
12718 -1,
12719 posix_methods,
12720 NULL,
12721 NULL,
12722 NULL,
12723 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012724};
12725
12726
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012727static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012728
12729#ifdef HAVE_FACCESSAT
12730 "HAVE_FACCESSAT",
12731#endif
12732
12733#ifdef HAVE_FCHDIR
12734 "HAVE_FCHDIR",
12735#endif
12736
12737#ifdef HAVE_FCHMOD
12738 "HAVE_FCHMOD",
12739#endif
12740
12741#ifdef HAVE_FCHMODAT
12742 "HAVE_FCHMODAT",
12743#endif
12744
12745#ifdef HAVE_FCHOWN
12746 "HAVE_FCHOWN",
12747#endif
12748
Larry Hastings00964ed2013-08-12 13:49:30 -040012749#ifdef HAVE_FCHOWNAT
12750 "HAVE_FCHOWNAT",
12751#endif
12752
Larry Hastings9cf065c2012-06-22 16:30:09 -070012753#ifdef HAVE_FEXECVE
12754 "HAVE_FEXECVE",
12755#endif
12756
12757#ifdef HAVE_FDOPENDIR
12758 "HAVE_FDOPENDIR",
12759#endif
12760
Georg Brandl306336b2012-06-24 12:55:33 +020012761#ifdef HAVE_FPATHCONF
12762 "HAVE_FPATHCONF",
12763#endif
12764
Larry Hastings9cf065c2012-06-22 16:30:09 -070012765#ifdef HAVE_FSTATAT
12766 "HAVE_FSTATAT",
12767#endif
12768
12769#ifdef HAVE_FSTATVFS
12770 "HAVE_FSTATVFS",
12771#endif
12772
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012773#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012774 "HAVE_FTRUNCATE",
12775#endif
12776
Larry Hastings9cf065c2012-06-22 16:30:09 -070012777#ifdef HAVE_FUTIMENS
12778 "HAVE_FUTIMENS",
12779#endif
12780
12781#ifdef HAVE_FUTIMES
12782 "HAVE_FUTIMES",
12783#endif
12784
12785#ifdef HAVE_FUTIMESAT
12786 "HAVE_FUTIMESAT",
12787#endif
12788
12789#ifdef HAVE_LINKAT
12790 "HAVE_LINKAT",
12791#endif
12792
12793#ifdef HAVE_LCHFLAGS
12794 "HAVE_LCHFLAGS",
12795#endif
12796
12797#ifdef HAVE_LCHMOD
12798 "HAVE_LCHMOD",
12799#endif
12800
12801#ifdef HAVE_LCHOWN
12802 "HAVE_LCHOWN",
12803#endif
12804
12805#ifdef HAVE_LSTAT
12806 "HAVE_LSTAT",
12807#endif
12808
12809#ifdef HAVE_LUTIMES
12810 "HAVE_LUTIMES",
12811#endif
12812
12813#ifdef HAVE_MKDIRAT
12814 "HAVE_MKDIRAT",
12815#endif
12816
12817#ifdef HAVE_MKFIFOAT
12818 "HAVE_MKFIFOAT",
12819#endif
12820
12821#ifdef HAVE_MKNODAT
12822 "HAVE_MKNODAT",
12823#endif
12824
12825#ifdef HAVE_OPENAT
12826 "HAVE_OPENAT",
12827#endif
12828
12829#ifdef HAVE_READLINKAT
12830 "HAVE_READLINKAT",
12831#endif
12832
12833#ifdef HAVE_RENAMEAT
12834 "HAVE_RENAMEAT",
12835#endif
12836
12837#ifdef HAVE_SYMLINKAT
12838 "HAVE_SYMLINKAT",
12839#endif
12840
12841#ifdef HAVE_UNLINKAT
12842 "HAVE_UNLINKAT",
12843#endif
12844
12845#ifdef HAVE_UTIMENSAT
12846 "HAVE_UTIMENSAT",
12847#endif
12848
12849#ifdef MS_WINDOWS
12850 "MS_WINDOWS",
12851#endif
12852
12853 NULL
12854};
12855
12856
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012857PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012858INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012859{
Victor Stinner8c62be82010-05-06 00:08:46 +000012860 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012861 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012862 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012863
Brian Curtin52173d42010-12-02 18:29:18 +000012864#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012865 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012866#endif
12867
Victor Stinner8c62be82010-05-06 00:08:46 +000012868 m = PyModule_Create(&posixmodule);
12869 if (m == NULL)
12870 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012871
Victor Stinner8c62be82010-05-06 00:08:46 +000012872 /* Initialize environ dictionary */
12873 v = convertenviron();
12874 Py_XINCREF(v);
12875 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12876 return NULL;
12877 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012878
Victor Stinner8c62be82010-05-06 00:08:46 +000012879 if (all_ins(m))
12880 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012881
Victor Stinner8c62be82010-05-06 00:08:46 +000012882 if (setup_confname_tables(m))
12883 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012884
Victor Stinner8c62be82010-05-06 00:08:46 +000012885 Py_INCREF(PyExc_OSError);
12886 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012887
Guido van Rossumb3d39562000-01-31 18:41:26 +000012888#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012889 if (posix_putenv_garbage == NULL)
12890 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012891#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012892
Victor Stinner8c62be82010-05-06 00:08:46 +000012893 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012894#if defined(HAVE_WAITID) && !defined(__APPLE__)
12895 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012896 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12897 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012898#endif
12899
Christian Heimes25827622013-10-12 01:27:08 +020012900 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012901 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12902 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12903 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012904 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12905 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012906 structseq_new = StatResultType.tp_new;
12907 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012908
Christian Heimes25827622013-10-12 01:27:08 +020012909 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012910 if (PyStructSequence_InitType2(&StatVFSResultType,
12911 &statvfs_result_desc) < 0)
12912 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012913#ifdef NEED_TICKS_PER_SECOND
12914# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012915 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012916# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012917 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012918# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012919 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012920# endif
12921#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012922
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012923#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012924 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012925 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12926 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012927 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012928#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012929
12930 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012931 if (PyStructSequence_InitType2(&TerminalSizeType,
12932 &TerminalSize_desc) < 0)
12933 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012934
12935 /* initialize scandir types */
12936 if (PyType_Ready(&ScandirIteratorType) < 0)
12937 return NULL;
12938 if (PyType_Ready(&DirEntryType) < 0)
12939 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012940 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012941#if defined(HAVE_WAITID) && !defined(__APPLE__)
12942 Py_INCREF((PyObject*) &WaitidResultType);
12943 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12944#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012945 Py_INCREF((PyObject*) &StatResultType);
12946 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12947 Py_INCREF((PyObject*) &StatVFSResultType);
12948 PyModule_AddObject(m, "statvfs_result",
12949 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012950
12951#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012952 Py_INCREF(&SchedParamType);
12953 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012954#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012955
Larry Hastings605a62d2012-06-24 04:33:36 -070012956 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012957 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12958 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012959 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12960
12961 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012962 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12963 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012964 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12965
Thomas Wouters477c8d52006-05-27 19:21:47 +000012966#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012967 /*
12968 * Step 2 of weak-linking support on Mac OS X.
12969 *
12970 * The code below removes functions that are not available on the
12971 * currently active platform.
12972 *
12973 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012974 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 * OSX 10.4.
12976 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012977#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 if (fstatvfs == NULL) {
12979 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12980 return NULL;
12981 }
12982 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012983#endif /* HAVE_FSTATVFS */
12984
12985#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 if (statvfs == NULL) {
12987 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12988 return NULL;
12989 }
12990 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012991#endif /* HAVE_STATVFS */
12992
12993# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012994 if (lchown == NULL) {
12995 if (PyObject_DelAttrString(m, "lchown") == -1) {
12996 return NULL;
12997 }
12998 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012999#endif /* HAVE_LCHOWN */
13000
13001
13002#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013003
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013004 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013005 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13006
Larry Hastings6fe20b32012-04-19 15:07:49 -070013007 billion = PyLong_FromLong(1000000000);
13008 if (!billion)
13009 return NULL;
13010
Larry Hastings9cf065c2012-06-22 16:30:09 -070013011 /* suppress "function not used" warnings */
13012 {
13013 int ignored;
13014 fd_specified("", -1);
13015 follow_symlinks_specified("", 1);
13016 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13017 dir_fd_converter(Py_None, &ignored);
13018 dir_fd_unavailable(Py_None, &ignored);
13019 }
13020
13021 /*
13022 * provide list of locally available functions
13023 * so os.py can populate support_* lists
13024 */
13025 list = PyList_New(0);
13026 if (!list)
13027 return NULL;
13028 for (trace = have_functions; *trace; trace++) {
13029 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13030 if (!unicode)
13031 return NULL;
13032 if (PyList_Append(list, unicode))
13033 return NULL;
13034 Py_DECREF(unicode);
13035 }
13036 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013037
13038 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013039 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013040
13041 initialized = 1;
13042
Victor Stinner8c62be82010-05-06 00:08:46 +000013043 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013044}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013045
13046#ifdef __cplusplus
13047}
13048#endif