blob: 4f5ec99e4ad0b9b1ce1f64ae27f9494ca53fb092 [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
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001181
Steve Dowerd81431f2015-03-06 14:47:02 -08001182#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1183/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1184 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001185 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001186#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001187#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001188#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001189#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001190#define _NO_CONSOLE_FILENO (intptr_t)-2
1191
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001192/* the special case of checking dup2. The target fd must be in a sensible range */
1193static int
1194_PyVerify_fd_dup2(int fd1, int fd2)
1195{
Victor Stinner8c62be82010-05-06 00:08:46 +00001196 if (!_PyVerify_fd(fd1))
1197 return 0;
1198 if (fd2 == _NO_CONSOLE_FILENO)
1199 return 0;
1200 if ((unsigned)fd2 < _NHANDLE_)
1201 return 1;
1202 else
1203 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001204}
1205#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001206#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001207#endif
1208
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001209#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001210
1211static int
Brian Curtind25aef52011-06-13 15:16:04 -05001212win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001213{
Martin Panter70214ad2016-08-04 02:38:59 +00001214 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1215 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001216 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001217
1218 if (0 == DeviceIoControl(
1219 reparse_point_handle,
1220 FSCTL_GET_REPARSE_POINT,
1221 NULL, 0, /* in buffer */
1222 target_buffer, sizeof(target_buffer),
1223 &n_bytes_returned,
1224 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001225 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001226
1227 if (reparse_tag)
1228 *reparse_tag = rdb->ReparseTag;
1229
Brian Curtind25aef52011-06-13 15:16:04 -05001230 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001231}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001232
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001233#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001234
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001235/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001236#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001237/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001238** environ directly, we must obtain it with _NSGetEnviron(). See also
1239** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001240*/
1241#include <crt_externs.h>
1242static char **environ;
1243#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001244extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001245#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001246
Barry Warsaw53699e91996-12-10 23:23:01 +00001247static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001248convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249{
Victor Stinner8c62be82010-05-06 00:08:46 +00001250 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001251#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001252 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001253#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001255#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001256
Victor Stinner8c62be82010-05-06 00:08:46 +00001257 d = PyDict_New();
1258 if (d == NULL)
1259 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001260#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001261 if (environ == NULL)
1262 environ = *_NSGetEnviron();
1263#endif
1264#ifdef MS_WINDOWS
1265 /* _wenviron must be initialized in this way if the program is started
1266 through main() instead of wmain(). */
1267 _wgetenv(L"");
1268 if (_wenviron == NULL)
1269 return d;
1270 /* This part ignores errors */
1271 for (e = _wenviron; *e != NULL; e++) {
1272 PyObject *k;
1273 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001274 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 if (p == NULL)
1276 continue;
1277 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1278 if (k == NULL) {
1279 PyErr_Clear();
1280 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001281 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001282 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1283 if (v == NULL) {
1284 PyErr_Clear();
1285 Py_DECREF(k);
1286 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001287 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 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);
1294 }
1295#else
1296 if (environ == NULL)
1297 return d;
1298 /* This part ignores errors */
1299 for (e = environ; *e != NULL; e++) {
1300 PyObject *k;
1301 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001302 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001303 if (p == NULL)
1304 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001305 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001306 if (k == NULL) {
1307 PyErr_Clear();
1308 continue;
1309 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001310 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 if (v == NULL) {
1312 PyErr_Clear();
1313 Py_DECREF(k);
1314 continue;
1315 }
1316 if (PyDict_GetItem(d, k) == NULL) {
1317 if (PyDict_SetItem(d, k, v) != 0)
1318 PyErr_Clear();
1319 }
1320 Py_DECREF(k);
1321 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001322 }
1323#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001325}
1326
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001327/* Set a POSIX-specific error from errno, and return NULL */
1328
Barry Warsawd58d7641998-07-23 16:14:40 +00001329static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001330posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001331{
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001333}
Mark Hammondef8b6542001-05-13 08:04:26 +00001334
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001335#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001336static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001337win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001338{
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 /* XXX We should pass the function name along in the future.
1340 (winreg.c also wants to pass the function name.)
1341 This would however require an additional param to the
1342 Windows error object, which is non-trivial.
1343 */
1344 errno = GetLastError();
1345 if (filename)
1346 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1347 else
1348 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001349}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001350
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001351static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001352win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001353{
1354 /* XXX - see win32_error for comments on 'function' */
1355 errno = GetLastError();
1356 if (filename)
1357 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001358 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001359 errno,
1360 filename);
1361 else
1362 return PyErr_SetFromWindowsErr(errno);
1363}
1364
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001365#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001366
Larry Hastings9cf065c2012-06-22 16:30:09 -07001367static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001368path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001369{
1370#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001371 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1372 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001373#else
Victor Stinner292c8352012-10-30 02:17:38 +01001374 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001375#endif
1376}
1377
Larry Hastings31826802013-10-19 00:09:25 -07001378
Larry Hastingsb0827312014-02-09 22:05:19 -08001379static PyObject *
1380path_error2(path_t *path, path_t *path2)
1381{
1382#ifdef MS_WINDOWS
1383 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1384 0, path->object, path2->object);
1385#else
1386 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1387 path->object, path2->object);
1388#endif
1389}
1390
1391
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001392/* POSIX generic methods */
1393
Larry Hastings2f936352014-08-05 14:04:04 +10001394static int
1395fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001396{
Victor Stinner8c62be82010-05-06 00:08:46 +00001397 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001398 int *pointer = (int *)p;
1399 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001400 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001401 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001402 *pointer = fd;
1403 return 1;
1404}
1405
1406static PyObject *
1407posix_fildes_fd(int fd, int (*func)(int))
1408{
1409 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001410 int async_err = 0;
1411
Steve Dower8fc89802015-04-12 00:26:27 -04001412 if (!_PyVerify_fd(fd))
1413 return posix_error();
1414
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001415 do {
1416 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001417 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001418 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001419 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001420 Py_END_ALLOW_THREADS
1421 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1422 if (res != 0)
1423 return (!async_err) ? posix_error() : NULL;
1424 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001425}
Guido van Rossum21142a01999-01-08 21:05:37 +00001426
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001427
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001428#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001429/* This is a reimplementation of the C library's chdir function,
1430 but one that produces Win32 errors instead of DOS error codes.
1431 chdir is essentially a wrapper around SetCurrentDirectory; however,
1432 it also needs to set "magic" environment variables indicating
1433 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001434static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001435win32_wchdir(LPCWSTR path)
1436{
Victor Stinnered537822015-12-13 21:40:26 +01001437 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 int result;
1439 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001440
Victor Stinner8c62be82010-05-06 00:08:46 +00001441 if(!SetCurrentDirectoryW(path))
1442 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001443 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001444 if (!result)
1445 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001446 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001447 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001448 if (!new_path) {
1449 SetLastError(ERROR_OUTOFMEMORY);
1450 return FALSE;
1451 }
1452 result = GetCurrentDirectoryW(result, new_path);
1453 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001454 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001455 return FALSE;
1456 }
1457 }
1458 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1459 wcsncmp(new_path, L"//", 2) == 0)
1460 /* UNC path, nothing to do. */
1461 return TRUE;
1462 env[1] = new_path[0];
1463 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001464 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001465 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001466 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001467}
1468#endif
1469
Martin v. Löwis14694662006-02-03 12:54:16 +00001470#ifdef MS_WINDOWS
1471/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1472 - time stamps are restricted to second resolution
1473 - file modification times suffer from forth-and-back conversions between
1474 UTC and local time
1475 Therefore, we implement our own stat, based on the Win32 API directly.
1476*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001477#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001478#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001479
Victor Stinner6036e442015-03-08 01:58:04 +01001480static void
Steve Dowercc16be82016-09-08 10:35:16 -07001481find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1482 BY_HANDLE_FILE_INFORMATION *info,
1483 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001484{
1485 memset(info, 0, sizeof(*info));
1486 info->dwFileAttributes = pFileData->dwFileAttributes;
1487 info->ftCreationTime = pFileData->ftCreationTime;
1488 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1489 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1490 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1491 info->nFileSizeLow = pFileData->nFileSizeLow;
1492/* info->nNumberOfLinks = 1; */
1493 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1494 *reparse_tag = pFileData->dwReserved0;
1495 else
1496 *reparse_tag = 0;
1497}
1498
Guido van Rossumd8faa362007-04-27 19:54:29 +00001499static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001500attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001501{
Victor Stinner8c62be82010-05-06 00:08:46 +00001502 HANDLE hFindFile;
1503 WIN32_FIND_DATAW FileData;
1504 hFindFile = FindFirstFileW(pszFile, &FileData);
1505 if (hFindFile == INVALID_HANDLE_VALUE)
1506 return FALSE;
1507 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001508 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001509 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001510}
1511
Brian Curtind25aef52011-06-13 15:16:04 -05001512static BOOL
1513get_target_path(HANDLE hdl, wchar_t **target_path)
1514{
1515 int buf_size, result_length;
1516 wchar_t *buf;
1517
1518 /* We have a good handle to the target, use it to determine
1519 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001520 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1521 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001522 if(!buf_size)
1523 return FALSE;
1524
Victor Stinnerc36674a2016-03-16 14:30:16 +01001525 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001526 if (!buf) {
1527 SetLastError(ERROR_OUTOFMEMORY);
1528 return FALSE;
1529 }
1530
Steve Dower2ea51c92015-03-20 21:49:12 -07001531 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001532 buf, buf_size, VOLUME_NAME_DOS);
1533
1534 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001535 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001536 return FALSE;
1537 }
1538
1539 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001540 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001541 return FALSE;
1542 }
1543
1544 buf[result_length] = 0;
1545
1546 *target_path = buf;
1547 return TRUE;
1548}
1549
1550static int
Steve Dowercc16be82016-09-08 10:35:16 -07001551win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001552 BOOL traverse)
1553{
Victor Stinner26de69d2011-06-17 15:15:38 +02001554 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001555 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001556 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001557 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001558 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001559 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560
Steve Dowercc16be82016-09-08 10:35:16 -07001561 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001562 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001563 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 0, /* share mode */
1565 NULL, /* security attributes */
1566 OPEN_EXISTING,
1567 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001568 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1569 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001570 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001571 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1572 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 NULL);
1574
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001575 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576 /* Either the target doesn't exist, or we don't have access to
1577 get a handle to it. If the former, we need to return an error.
1578 If the latter, we can use attributes_from_dir. */
1579 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001580 return -1;
1581 /* Could not get attributes on open file. Fall back to
1582 reading the directory. */
1583 if (!attributes_from_dir(path, &info, &reparse_tag))
1584 /* Very strange. This should not fail now */
1585 return -1;
1586 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1587 if (traverse) {
1588 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001590 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001591 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001592 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001593 } else {
1594 if (!GetFileInformationByHandle(hFile, &info)) {
1595 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001596 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001597 }
1598 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001599 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1600 return -1;
1601
1602 /* Close the outer open file handle now that we're about to
1603 reopen it with different flags. */
1604 if (!CloseHandle(hFile))
1605 return -1;
1606
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001608 /* In order to call GetFinalPathNameByHandle we need to open
1609 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001610 hFile2 = CreateFileW(
1611 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1612 NULL, OPEN_EXISTING,
1613 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1614 NULL);
1615 if (hFile2 == INVALID_HANDLE_VALUE)
1616 return -1;
1617
1618 if (!get_target_path(hFile2, &target_path))
1619 return -1;
1620
Steve Dowercc16be82016-09-08 10:35:16 -07001621 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001622 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return code;
1624 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001625 } else
1626 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001627 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001628 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001629
1630 /* Set S_IEXEC if it is an .exe, .bat, ... */
1631 dot = wcsrchr(path, '.');
1632 if (dot) {
1633 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1634 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1635 result->st_mode |= 0111;
1636 }
1637 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001638}
1639
1640static int
Steve Dowercc16be82016-09-08 10:35:16 -07001641win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001642{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 /* Protocol violation: we explicitly clear errno, instead of
1644 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001645 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001646 errno = 0;
1647 return code;
1648}
Brian Curtind25aef52011-06-13 15:16:04 -05001649/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001650
1651 In Posix, stat automatically traverses symlinks and returns the stat
1652 structure for the target. In Windows, the equivalent GetFileAttributes by
1653 default does not traverse symlinks and instead returns attributes for
1654 the symlink.
1655
1656 Therefore, win32_lstat will get the attributes traditionally, and
1657 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001658 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001659
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001660static int
Steve Dowercc16be82016-09-08 10:35:16 -07001661win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001662{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001663 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001664}
1665
Victor Stinner8c62be82010-05-06 00:08:46 +00001666static int
Steve Dowercc16be82016-09-08 10:35:16 -07001667win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001668{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001669 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001670}
1671
Martin v. Löwis14694662006-02-03 12:54:16 +00001672#endif /* MS_WINDOWS */
1673
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001674PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001675"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001676This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001677 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001678or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1679\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001680Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1681or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001682\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001683See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001684
1685static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001686 {"st_mode", "protection bits"},
1687 {"st_ino", "inode"},
1688 {"st_dev", "device"},
1689 {"st_nlink", "number of hard links"},
1690 {"st_uid", "user ID of owner"},
1691 {"st_gid", "group ID of owner"},
1692 {"st_size", "total size, in bytes"},
1693 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1694 {NULL, "integer time of last access"},
1695 {NULL, "integer time of last modification"},
1696 {NULL, "integer time of last change"},
1697 {"st_atime", "time of last access"},
1698 {"st_mtime", "time of last modification"},
1699 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001700 {"st_atime_ns", "time of last access in nanoseconds"},
1701 {"st_mtime_ns", "time of last modification in nanoseconds"},
1702 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001703#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001704 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001705#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001706#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001707 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001708#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001709#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001710 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001711#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001712#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001713 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001714#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001715#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001716 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001717#endif
1718#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001719 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001720#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001721#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1722 {"st_file_attributes", "Windows file attribute bits"},
1723#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001724 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001725};
1726
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001727#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001728#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001729#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001730#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001731#endif
1732
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001733#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001734#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1735#else
1736#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1737#endif
1738
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001739#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001740#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1741#else
1742#define ST_RDEV_IDX ST_BLOCKS_IDX
1743#endif
1744
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001745#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1746#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1747#else
1748#define ST_FLAGS_IDX ST_RDEV_IDX
1749#endif
1750
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001751#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001752#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001753#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001754#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001755#endif
1756
1757#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1758#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1759#else
1760#define ST_BIRTHTIME_IDX ST_GEN_IDX
1761#endif
1762
Zachary Ware63f277b2014-06-19 09:46:37 -05001763#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1764#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1765#else
1766#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1767#endif
1768
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001769static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 "stat_result", /* name */
1771 stat_result__doc__, /* doc */
1772 stat_result_fields,
1773 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001774};
1775
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001776PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1778This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001779 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001780or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001781\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001782See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783
1784static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001785 {"f_bsize", },
1786 {"f_frsize", },
1787 {"f_blocks", },
1788 {"f_bfree", },
1789 {"f_bavail", },
1790 {"f_files", },
1791 {"f_ffree", },
1792 {"f_favail", },
1793 {"f_flag", },
1794 {"f_namemax",},
1795 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001796};
1797
1798static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001799 "statvfs_result", /* name */
1800 statvfs_result__doc__, /* doc */
1801 statvfs_result_fields,
1802 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001803};
1804
Ross Lagerwall7807c352011-03-17 20:20:30 +02001805#if defined(HAVE_WAITID) && !defined(__APPLE__)
1806PyDoc_STRVAR(waitid_result__doc__,
1807"waitid_result: Result from waitid.\n\n\
1808This object may be accessed either as a tuple of\n\
1809 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1810or via the attributes si_pid, si_uid, and so on.\n\
1811\n\
1812See os.waitid for more information.");
1813
1814static PyStructSequence_Field waitid_result_fields[] = {
1815 {"si_pid", },
1816 {"si_uid", },
1817 {"si_signo", },
1818 {"si_status", },
1819 {"si_code", },
1820 {0}
1821};
1822
1823static PyStructSequence_Desc waitid_result_desc = {
1824 "waitid_result", /* name */
1825 waitid_result__doc__, /* doc */
1826 waitid_result_fields,
1827 5
1828};
1829static PyTypeObject WaitidResultType;
1830#endif
1831
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001832static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001833static PyTypeObject StatResultType;
1834static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001835#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001836static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001837#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001838static newfunc structseq_new;
1839
1840static PyObject *
1841statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1842{
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 PyStructSequence *result;
1844 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001845
Victor Stinner8c62be82010-05-06 00:08:46 +00001846 result = (PyStructSequence*)structseq_new(type, args, kwds);
1847 if (!result)
1848 return NULL;
1849 /* If we have been initialized from a tuple,
1850 st_?time might be set to None. Initialize it
1851 from the int slots. */
1852 for (i = 7; i <= 9; i++) {
1853 if (result->ob_item[i+3] == Py_None) {
1854 Py_DECREF(Py_None);
1855 Py_INCREF(result->ob_item[i]);
1856 result->ob_item[i+3] = result->ob_item[i];
1857 }
1858 }
1859 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001860}
1861
1862
1863
1864/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001865static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001866
1867PyDoc_STRVAR(stat_float_times__doc__,
1868"stat_float_times([newval]) -> oldval\n\n\
1869Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001870\n\
1871If value is True, future calls to stat() return floats; if it is False,\n\
1872future calls return ints.\n\
1873If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001874
Larry Hastings2f936352014-08-05 14:04:04 +10001875/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001876static PyObject*
1877stat_float_times(PyObject* self, PyObject *args)
1878{
Victor Stinner8c62be82010-05-06 00:08:46 +00001879 int newval = -1;
1880 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1881 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001882 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1883 "stat_float_times() is deprecated",
1884 1))
1885 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 if (newval == -1)
1887 /* Return old value */
1888 return PyBool_FromLong(_stat_float_times);
1889 _stat_float_times = newval;
1890 Py_INCREF(Py_None);
1891 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001892}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893
Larry Hastings6fe20b32012-04-19 15:07:49 -07001894static PyObject *billion = NULL;
1895
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001896static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001897fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001898{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001899 PyObject *s = _PyLong_FromTime_t(sec);
1900 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1901 PyObject *s_in_ns = NULL;
1902 PyObject *ns_total = NULL;
1903 PyObject *float_s = NULL;
1904
1905 if (!(s && ns_fractional))
1906 goto exit;
1907
1908 s_in_ns = PyNumber_Multiply(s, billion);
1909 if (!s_in_ns)
1910 goto exit;
1911
1912 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1913 if (!ns_total)
1914 goto exit;
1915
Victor Stinner4195b5c2012-02-08 23:03:19 +01001916 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001917 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1918 if (!float_s)
1919 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001920 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001921 else {
1922 float_s = s;
1923 Py_INCREF(float_s);
1924 }
1925
1926 PyStructSequence_SET_ITEM(v, index, s);
1927 PyStructSequence_SET_ITEM(v, index+3, float_s);
1928 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1929 s = NULL;
1930 float_s = NULL;
1931 ns_total = NULL;
1932exit:
1933 Py_XDECREF(s);
1934 Py_XDECREF(ns_fractional);
1935 Py_XDECREF(s_in_ns);
1936 Py_XDECREF(ns_total);
1937 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001938}
1939
Tim Peters5aa91602002-01-30 05:46:57 +00001940/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001941 (used by posix_stat() and posix_fstat()) */
1942static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001943_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001944{
Victor Stinner8c62be82010-05-06 00:08:46 +00001945 unsigned long ansec, mnsec, cnsec;
1946 PyObject *v = PyStructSequence_New(&StatResultType);
1947 if (v == NULL)
1948 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001949
Victor Stinner8c62be82010-05-06 00:08:46 +00001950 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001951#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001952 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001953 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001954#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001956#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001957#ifdef MS_WINDOWS
1958 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001959#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001960 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001961#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001962 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001963#if defined(MS_WINDOWS)
1964 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1965 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1966#else
1967 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1968 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1969#endif
Fred Drake699f3522000-06-29 21:12:41 +00001970#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001972 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001973#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001975#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001976
Martin v. Löwis14694662006-02-03 12:54:16 +00001977#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 ansec = st->st_atim.tv_nsec;
1979 mnsec = st->st_mtim.tv_nsec;
1980 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001981#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 ansec = st->st_atimespec.tv_nsec;
1983 mnsec = st->st_mtimespec.tv_nsec;
1984 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001985#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001986 ansec = st->st_atime_nsec;
1987 mnsec = st->st_mtime_nsec;
1988 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001989#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001990 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001991#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001992 fill_time(v, 7, st->st_atime, ansec);
1993 fill_time(v, 8, st->st_mtime, mnsec);
1994 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001995
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001996#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001997 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1998 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001999#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002000#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2002 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002003#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002004#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2006 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002008#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2010 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002011#endif
2012#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002014 PyObject *val;
2015 unsigned long bsec,bnsec;
2016 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002017#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002018 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002019#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002020 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002021#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002022 if (_stat_float_times) {
2023 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2024 } else {
2025 val = PyLong_FromLong((long)bsec);
2026 }
2027 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2028 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002030#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002031#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2033 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002034#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002035#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2036 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2037 PyLong_FromUnsignedLong(st->st_file_attributes));
2038#endif
Fred Drake699f3522000-06-29 21:12:41 +00002039
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 if (PyErr_Occurred()) {
2041 Py_DECREF(v);
2042 return NULL;
2043 }
Fred Drake699f3522000-06-29 21:12:41 +00002044
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002046}
2047
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002048/* POSIX methods */
2049
Guido van Rossum94f6f721999-01-06 18:42:14 +00002050
2051static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002052posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002053 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002054{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002055 STRUCT_STAT st;
2056 int result;
2057
2058#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2059 if (follow_symlinks_specified(function_name, follow_symlinks))
2060 return NULL;
2061#endif
2062
2063 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2064 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2065 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2066 return NULL;
2067
2068 Py_BEGIN_ALLOW_THREADS
2069 if (path->fd != -1)
2070 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002071#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002072 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002073 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002074 else
Steve Dowercc16be82016-09-08 10:35:16 -07002075 result = win32_lstat(path->wide, &st);
2076#else
2077 else
2078#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002079 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2080 result = LSTAT(path->narrow, &st);
2081 else
Steve Dowercc16be82016-09-08 10:35:16 -07002082#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002083#ifdef HAVE_FSTATAT
2084 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2085 result = fstatat(dir_fd, path->narrow, &st,
2086 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2087 else
Steve Dowercc16be82016-09-08 10:35:16 -07002088#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002089 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002090#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002091 Py_END_ALLOW_THREADS
2092
Victor Stinner292c8352012-10-30 02:17:38 +01002093 if (result != 0) {
2094 return path_error(path);
2095 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002096
2097 return _pystat_fromstructstat(&st);
2098}
2099
Larry Hastings2f936352014-08-05 14:04:04 +10002100/*[python input]
2101
2102for s in """
2103
2104FACCESSAT
2105FCHMODAT
2106FCHOWNAT
2107FSTATAT
2108LINKAT
2109MKDIRAT
2110MKFIFOAT
2111MKNODAT
2112OPENAT
2113READLINKAT
2114SYMLINKAT
2115UNLINKAT
2116
2117""".strip().split():
2118 s = s.strip()
2119 print("""
2120#ifdef HAVE_{s}
2121 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002122#else
Larry Hastings2f936352014-08-05 14:04:04 +10002123 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002124#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002125""".rstrip().format(s=s))
2126
2127for s in """
2128
2129FCHDIR
2130FCHMOD
2131FCHOWN
2132FDOPENDIR
2133FEXECVE
2134FPATHCONF
2135FSTATVFS
2136FTRUNCATE
2137
2138""".strip().split():
2139 s = s.strip()
2140 print("""
2141#ifdef HAVE_{s}
2142 #define PATH_HAVE_{s} 1
2143#else
2144 #define PATH_HAVE_{s} 0
2145#endif
2146
2147""".rstrip().format(s=s))
2148[python start generated code]*/
2149
2150#ifdef HAVE_FACCESSAT
2151 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2152#else
2153 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2154#endif
2155
2156#ifdef HAVE_FCHMODAT
2157 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2158#else
2159 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2160#endif
2161
2162#ifdef HAVE_FCHOWNAT
2163 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2164#else
2165 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2166#endif
2167
2168#ifdef HAVE_FSTATAT
2169 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2170#else
2171 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2172#endif
2173
2174#ifdef HAVE_LINKAT
2175 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2176#else
2177 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2178#endif
2179
2180#ifdef HAVE_MKDIRAT
2181 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2182#else
2183 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2184#endif
2185
2186#ifdef HAVE_MKFIFOAT
2187 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2188#else
2189 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2190#endif
2191
2192#ifdef HAVE_MKNODAT
2193 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2194#else
2195 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2196#endif
2197
2198#ifdef HAVE_OPENAT
2199 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2200#else
2201 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2202#endif
2203
2204#ifdef HAVE_READLINKAT
2205 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2206#else
2207 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2208#endif
2209
2210#ifdef HAVE_SYMLINKAT
2211 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2212#else
2213 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2214#endif
2215
2216#ifdef HAVE_UNLINKAT
2217 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2218#else
2219 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2220#endif
2221
2222#ifdef HAVE_FCHDIR
2223 #define PATH_HAVE_FCHDIR 1
2224#else
2225 #define PATH_HAVE_FCHDIR 0
2226#endif
2227
2228#ifdef HAVE_FCHMOD
2229 #define PATH_HAVE_FCHMOD 1
2230#else
2231 #define PATH_HAVE_FCHMOD 0
2232#endif
2233
2234#ifdef HAVE_FCHOWN
2235 #define PATH_HAVE_FCHOWN 1
2236#else
2237 #define PATH_HAVE_FCHOWN 0
2238#endif
2239
2240#ifdef HAVE_FDOPENDIR
2241 #define PATH_HAVE_FDOPENDIR 1
2242#else
2243 #define PATH_HAVE_FDOPENDIR 0
2244#endif
2245
2246#ifdef HAVE_FEXECVE
2247 #define PATH_HAVE_FEXECVE 1
2248#else
2249 #define PATH_HAVE_FEXECVE 0
2250#endif
2251
2252#ifdef HAVE_FPATHCONF
2253 #define PATH_HAVE_FPATHCONF 1
2254#else
2255 #define PATH_HAVE_FPATHCONF 0
2256#endif
2257
2258#ifdef HAVE_FSTATVFS
2259 #define PATH_HAVE_FSTATVFS 1
2260#else
2261 #define PATH_HAVE_FSTATVFS 0
2262#endif
2263
2264#ifdef HAVE_FTRUNCATE
2265 #define PATH_HAVE_FTRUNCATE 1
2266#else
2267 #define PATH_HAVE_FTRUNCATE 0
2268#endif
2269/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002270
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002271#ifdef MS_WINDOWS
2272 #undef PATH_HAVE_FTRUNCATE
2273 #define PATH_HAVE_FTRUNCATE 1
2274#endif
Larry Hastings31826802013-10-19 00:09:25 -07002275
Larry Hastings61272b72014-01-07 12:41:53 -08002276/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002277
2278class path_t_converter(CConverter):
2279
2280 type = "path_t"
2281 impl_by_reference = True
2282 parse_by_reference = True
2283
2284 converter = 'path_converter'
2285
2286 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002287 # right now path_t doesn't support default values.
2288 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002289 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002290 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002291
Larry Hastings2f936352014-08-05 14:04:04 +10002292 if self.c_default not in (None, 'Py_None'):
2293 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002294
2295 self.nullable = nullable
2296 self.allow_fd = allow_fd
2297
Larry Hastings7726ac92014-01-31 22:03:12 -08002298 def pre_render(self):
2299 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002300 if isinstance(value, str):
2301 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002302 return str(int(bool(value)))
2303
2304 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002305 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002306 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002307 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002308 strify(self.nullable),
2309 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002310 )
2311
2312 def cleanup(self):
2313 return "path_cleanup(&" + self.name + ");\n"
2314
2315
2316class dir_fd_converter(CConverter):
2317 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002318
Larry Hastings2f936352014-08-05 14:04:04 +10002319 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002320 if self.default in (unspecified, None):
2321 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002322 if isinstance(requires, str):
2323 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2324 else:
2325 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002326
Larry Hastings2f936352014-08-05 14:04:04 +10002327class fildes_converter(CConverter):
2328 type = 'int'
2329 converter = 'fildes_converter'
2330
2331class uid_t_converter(CConverter):
2332 type = "uid_t"
2333 converter = '_Py_Uid_Converter'
2334
2335class gid_t_converter(CConverter):
2336 type = "gid_t"
2337 converter = '_Py_Gid_Converter'
2338
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002339class dev_t_converter(CConverter):
2340 type = 'dev_t'
2341 converter = '_Py_Dev_Converter'
2342
2343class dev_t_return_converter(unsigned_long_return_converter):
2344 type = 'dev_t'
2345 conversion_fn = '_PyLong_FromDev'
2346 unsigned_cast = '(dev_t)'
2347
Larry Hastings2f936352014-08-05 14:04:04 +10002348class FSConverter_converter(CConverter):
2349 type = 'PyObject *'
2350 converter = 'PyUnicode_FSConverter'
2351 def converter_init(self):
2352 if self.default is not unspecified:
2353 fail("FSConverter_converter does not support default values")
2354 self.c_default = 'NULL'
2355
2356 def cleanup(self):
2357 return "Py_XDECREF(" + self.name + ");\n"
2358
2359class pid_t_converter(CConverter):
2360 type = 'pid_t'
2361 format_unit = '" _Py_PARSE_PID "'
2362
2363class idtype_t_converter(int_converter):
2364 type = 'idtype_t'
2365
2366class id_t_converter(CConverter):
2367 type = 'id_t'
2368 format_unit = '" _Py_PARSE_PID "'
2369
Benjamin Petersonca470632016-09-06 13:47:26 -07002370class intptr_t_converter(CConverter):
2371 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002372 format_unit = '" _Py_PARSE_INTPTR "'
2373
2374class Py_off_t_converter(CConverter):
2375 type = 'Py_off_t'
2376 converter = 'Py_off_t_converter'
2377
2378class Py_off_t_return_converter(long_return_converter):
2379 type = 'Py_off_t'
2380 conversion_fn = 'PyLong_FromPy_off_t'
2381
2382class path_confname_converter(CConverter):
2383 type="int"
2384 converter="conv_path_confname"
2385
2386class confstr_confname_converter(path_confname_converter):
2387 converter='conv_confstr_confname'
2388
2389class sysconf_confname_converter(path_confname_converter):
2390 converter="conv_sysconf_confname"
2391
2392class sched_param_converter(CConverter):
2393 type = 'struct sched_param'
2394 converter = 'convert_sched_param'
2395 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002396
Larry Hastings61272b72014-01-07 12:41:53 -08002397[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002398/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002399
Larry Hastings61272b72014-01-07 12:41:53 -08002400/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002401
Larry Hastings2a727912014-01-16 11:32:01 -08002402os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002403
2404 path : path_t(allow_fd=True)
2405 Path to be examined; can be string, bytes, or open-file-descriptor int.
2406
2407 *
2408
Larry Hastings2f936352014-08-05 14:04:04 +10002409 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002410 If not None, it should be a file descriptor open to a directory,
2411 and path should be a relative string; path will then be relative to
2412 that directory.
2413
2414 follow_symlinks: bool = True
2415 If False, and the last element of the path is a symbolic link,
2416 stat will examine the symbolic link itself instead of the file
2417 the link points to.
2418
2419Perform a stat system call on the given path.
2420
2421dir_fd and follow_symlinks may not be implemented
2422 on your platform. If they are unavailable, using them will raise a
2423 NotImplementedError.
2424
2425It's an error to use dir_fd or follow_symlinks when specifying path as
2426 an open file descriptor.
2427
Larry Hastings61272b72014-01-07 12:41:53 -08002428[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002429
Larry Hastings31826802013-10-19 00:09:25 -07002430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002431os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2432/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002433{
2434 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2435}
2436
Larry Hastings2f936352014-08-05 14:04:04 +10002437
2438/*[clinic input]
2439os.lstat
2440
2441 path : path_t
2442
2443 *
2444
2445 dir_fd : dir_fd(requires='fstatat') = None
2446
2447Perform a stat system call on the given path, without following symbolic links.
2448
2449Like stat(), but do not follow symbolic links.
2450Equivalent to stat(path, follow_symlinks=False).
2451[clinic start generated code]*/
2452
Larry Hastings2f936352014-08-05 14:04:04 +10002453static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002454os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2455/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002456{
2457 int follow_symlinks = 0;
2458 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2459}
Larry Hastings31826802013-10-19 00:09:25 -07002460
Larry Hastings2f936352014-08-05 14:04:04 +10002461
Larry Hastings61272b72014-01-07 12:41:53 -08002462/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002463os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002464
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002465 path: path_t
2466 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002467
2468 mode: int
2469 Operating-system mode bitfield. Can be F_OK to test existence,
2470 or the inclusive-OR of R_OK, W_OK, and X_OK.
2471
2472 *
2473
Larry Hastings2f936352014-08-05 14:04:04 +10002474 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002475 If not None, it should be a file descriptor open to a directory,
2476 and path should be relative; path will then be relative to that
2477 directory.
2478
2479 effective_ids: bool = False
2480 If True, access will use the effective uid/gid instead of
2481 the real uid/gid.
2482
2483 follow_symlinks: bool = True
2484 If False, and the last element of the path is a symbolic link,
2485 access will examine the symbolic link itself instead of the file
2486 the link points to.
2487
2488Use the real uid/gid to test for access to a path.
2489
2490{parameters}
2491dir_fd, effective_ids, and follow_symlinks may not be implemented
2492 on your platform. If they are unavailable, using them will raise a
2493 NotImplementedError.
2494
2495Note that most operations will use the effective uid/gid, therefore this
2496 routine can be used in a suid/sgid environment to test if the invoking user
2497 has the specified access to the path.
2498
Larry Hastings61272b72014-01-07 12:41:53 -08002499[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002500
Larry Hastings2f936352014-08-05 14:04:04 +10002501static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002502os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002503 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002504/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002505{
Larry Hastings2f936352014-08-05 14:04:04 +10002506 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002507
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002508#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002509 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002510#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002511 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002512#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002513
Larry Hastings9cf065c2012-06-22 16:30:09 -07002514#ifndef HAVE_FACCESSAT
2515 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002516 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002517
2518 if (effective_ids) {
2519 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002520 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002521 }
2522#endif
2523
2524#ifdef MS_WINDOWS
2525 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002526 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 Py_END_ALLOW_THREADS
2528
2529 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002530 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002531 * * we didn't get a -1, and
2532 * * write access wasn't requested,
2533 * * or the file isn't read-only,
2534 * * or it's a directory.
2535 * (Directories cannot be read-only on Windows.)
2536 */
Larry Hastings2f936352014-08-05 14:04:04 +10002537 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002538 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002539 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002540 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002541#else
2542
2543 Py_BEGIN_ALLOW_THREADS
2544#ifdef HAVE_FACCESSAT
2545 if ((dir_fd != DEFAULT_DIR_FD) ||
2546 effective_ids ||
2547 !follow_symlinks) {
2548 int flags = 0;
2549 if (!follow_symlinks)
2550 flags |= AT_SYMLINK_NOFOLLOW;
2551 if (effective_ids)
2552 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002553 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002554 }
2555 else
2556#endif
Larry Hastings31826802013-10-19 00:09:25 -07002557 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002559 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560#endif
2561
Larry Hastings9cf065c2012-06-22 16:30:09 -07002562 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002563}
2564
Guido van Rossumd371ff11999-01-25 16:12:23 +00002565#ifndef F_OK
2566#define F_OK 0
2567#endif
2568#ifndef R_OK
2569#define R_OK 4
2570#endif
2571#ifndef W_OK
2572#define W_OK 2
2573#endif
2574#ifndef X_OK
2575#define X_OK 1
2576#endif
2577
Larry Hastings31826802013-10-19 00:09:25 -07002578
Guido van Rossumd371ff11999-01-25 16:12:23 +00002579#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002580/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002581os.ttyname -> DecodeFSDefault
2582
2583 fd: int
2584 Integer file descriptor handle.
2585
2586 /
2587
2588Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002589[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002590
Larry Hastings31826802013-10-19 00:09:25 -07002591static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002592os_ttyname_impl(PyObject *module, int fd)
2593/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002594{
2595 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002596
Larry Hastings31826802013-10-19 00:09:25 -07002597 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002599 posix_error();
2600 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002601}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002602#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002603
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002604#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002605/*[clinic input]
2606os.ctermid
2607
2608Return the name of the controlling terminal for this process.
2609[clinic start generated code]*/
2610
Larry Hastings2f936352014-08-05 14:04:04 +10002611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002612os_ctermid_impl(PyObject *module)
2613/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002614{
Victor Stinner8c62be82010-05-06 00:08:46 +00002615 char *ret;
2616 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002617
Greg Wardb48bc172000-03-01 21:51:56 +00002618#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002619 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002620#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002621 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002622#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002623 if (ret == NULL)
2624 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002625 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002626}
Larry Hastings2f936352014-08-05 14:04:04 +10002627#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002628
Larry Hastings2f936352014-08-05 14:04:04 +10002629
2630/*[clinic input]
2631os.chdir
2632
2633 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2634
2635Change the current working directory to the specified path.
2636
2637path may always be specified as a string.
2638On some platforms, path may also be specified as an open file descriptor.
2639 If this functionality is unavailable, using it raises an exception.
2640[clinic start generated code]*/
2641
Larry Hastings2f936352014-08-05 14:04:04 +10002642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002643os_chdir_impl(PyObject *module, path_t *path)
2644/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002645{
2646 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002647
2648 Py_BEGIN_ALLOW_THREADS
2649#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002650 /* on unix, success = 0, on windows, success = !0 */
2651 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652#else
2653#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002654 if (path->fd != -1)
2655 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002656 else
2657#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002658 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002659#endif
2660 Py_END_ALLOW_THREADS
2661
2662 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002663 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002664 }
2665
Larry Hastings2f936352014-08-05 14:04:04 +10002666 Py_RETURN_NONE;
2667}
2668
2669
2670#ifdef HAVE_FCHDIR
2671/*[clinic input]
2672os.fchdir
2673
2674 fd: fildes
2675
2676Change to the directory of the given file descriptor.
2677
2678fd must be opened on a directory, not a file.
2679Equivalent to os.chdir(fd).
2680
2681[clinic start generated code]*/
2682
Fred Drake4d1e64b2002-04-15 19:40:07 +00002683static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002684os_fchdir_impl(PyObject *module, int fd)
2685/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002686{
Larry Hastings2f936352014-08-05 14:04:04 +10002687 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002688}
2689#endif /* HAVE_FCHDIR */
2690
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002691
Larry Hastings2f936352014-08-05 14:04:04 +10002692/*[clinic input]
2693os.chmod
2694
2695 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2696 Path to be modified. May always be specified as a str or bytes.
2697 On some platforms, path may also be specified as an open file descriptor.
2698 If this functionality is unavailable, using it raises an exception.
2699
2700 mode: int
2701 Operating-system mode bitfield.
2702
2703 *
2704
2705 dir_fd : dir_fd(requires='fchmodat') = None
2706 If not None, it should be a file descriptor open to a directory,
2707 and path should be relative; path will then be relative to that
2708 directory.
2709
2710 follow_symlinks: bool = True
2711 If False, and the last element of the path is a symbolic link,
2712 chmod will modify the symbolic link itself instead of the file
2713 the link points to.
2714
2715Change the access permissions of a file.
2716
2717It is an error to use dir_fd or follow_symlinks when specifying path as
2718 an open file descriptor.
2719dir_fd and follow_symlinks may not be implemented on your platform.
2720 If they are unavailable, using them will raise a NotImplementedError.
2721
2722[clinic start generated code]*/
2723
Larry Hastings2f936352014-08-05 14:04:04 +10002724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002725os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002726 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002727/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002728{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002730
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002731#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002732 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002734
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735#ifdef HAVE_FCHMODAT
2736 int fchmodat_nofollow_unsupported = 0;
2737#endif
2738
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2740 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002741 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002742#endif
2743
2744#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002745 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002746 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002747 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002748 result = 0;
2749 else {
2750 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002751 attr &= ~FILE_ATTRIBUTE_READONLY;
2752 else
2753 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002754 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755 }
2756 Py_END_ALLOW_THREADS
2757
2758 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002759 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002760 }
2761#else /* MS_WINDOWS */
2762 Py_BEGIN_ALLOW_THREADS
2763#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002764 if (path->fd != -1)
2765 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002766 else
2767#endif
2768#ifdef HAVE_LCHMOD
2769 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002770 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002771 else
2772#endif
2773#ifdef HAVE_FCHMODAT
2774 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2775 /*
2776 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2777 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002778 * and then says it isn't implemented yet.
2779 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002780 *
2781 * Once it is supported, os.chmod will automatically
2782 * support dir_fd and follow_symlinks=False. (Hopefully.)
2783 * Until then, we need to be careful what exception we raise.
2784 */
Larry Hastings2f936352014-08-05 14:04:04 +10002785 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002786 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2787 /*
2788 * But wait! We can't throw the exception without allowing threads,
2789 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2790 */
2791 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002792 result &&
2793 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2794 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002795 }
2796 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002797#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002798 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799 Py_END_ALLOW_THREADS
2800
2801 if (result) {
2802#ifdef HAVE_FCHMODAT
2803 if (fchmodat_nofollow_unsupported) {
2804 if (dir_fd != DEFAULT_DIR_FD)
2805 dir_fd_and_follow_symlinks_invalid("chmod",
2806 dir_fd, follow_symlinks);
2807 else
2808 follow_symlinks_specified("chmod", follow_symlinks);
2809 }
2810 else
2811#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002812 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 }
2814#endif
2815
Larry Hastings2f936352014-08-05 14:04:04 +10002816 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002817}
2818
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819
Christian Heimes4e30a842007-11-30 22:12:06 +00002820#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002821/*[clinic input]
2822os.fchmod
2823
2824 fd: int
2825 mode: int
2826
2827Change the access permissions of the file given by file descriptor fd.
2828
2829Equivalent to os.chmod(fd, mode).
2830[clinic start generated code]*/
2831
Larry Hastings2f936352014-08-05 14:04:04 +10002832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002833os_fchmod_impl(PyObject *module, int fd, int mode)
2834/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002835{
2836 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002837 int async_err = 0;
2838
2839 do {
2840 Py_BEGIN_ALLOW_THREADS
2841 res = fchmod(fd, mode);
2842 Py_END_ALLOW_THREADS
2843 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2844 if (res != 0)
2845 return (!async_err) ? posix_error() : NULL;
2846
Victor Stinner8c62be82010-05-06 00:08:46 +00002847 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002848}
2849#endif /* HAVE_FCHMOD */
2850
Larry Hastings2f936352014-08-05 14:04:04 +10002851
Christian Heimes4e30a842007-11-30 22:12:06 +00002852#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002853/*[clinic input]
2854os.lchmod
2855
2856 path: path_t
2857 mode: int
2858
2859Change the access permissions of a file, without following symbolic links.
2860
2861If path is a symlink, this affects the link itself rather than the target.
2862Equivalent to chmod(path, mode, follow_symlinks=False)."
2863[clinic start generated code]*/
2864
Larry Hastings2f936352014-08-05 14:04:04 +10002865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002866os_lchmod_impl(PyObject *module, path_t *path, int mode)
2867/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002868{
Victor Stinner8c62be82010-05-06 00:08:46 +00002869 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002871 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002872 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002873 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002874 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002875 return NULL;
2876 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002877 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002878}
2879#endif /* HAVE_LCHMOD */
2880
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002881
Thomas Wouterscf297e42007-02-23 15:07:44 +00002882#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002883/*[clinic input]
2884os.chflags
2885
2886 path: path_t
2887 flags: unsigned_long(bitwise=True)
2888 follow_symlinks: bool=True
2889
2890Set file flags.
2891
2892If follow_symlinks is False, and the last element of the path is a symbolic
2893 link, chflags will change flags on the symbolic link itself instead of the
2894 file the link points to.
2895follow_symlinks may not be implemented on your platform. If it is
2896unavailable, using it will raise a NotImplementedError.
2897
2898[clinic start generated code]*/
2899
Larry Hastings2f936352014-08-05 14:04:04 +10002900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002901os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002902 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002903/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002904{
2905 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002906
2907#ifndef HAVE_LCHFLAGS
2908 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002909 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002910#endif
2911
Victor Stinner8c62be82010-05-06 00:08:46 +00002912 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002913#ifdef HAVE_LCHFLAGS
2914 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002915 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002916 else
2917#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002918 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002919 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002920
Larry Hastings2f936352014-08-05 14:04:04 +10002921 if (result)
2922 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002923
Larry Hastings2f936352014-08-05 14:04:04 +10002924 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002925}
2926#endif /* HAVE_CHFLAGS */
2927
Larry Hastings2f936352014-08-05 14:04:04 +10002928
Thomas Wouterscf297e42007-02-23 15:07:44 +00002929#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002930/*[clinic input]
2931os.lchflags
2932
2933 path: path_t
2934 flags: unsigned_long(bitwise=True)
2935
2936Set file flags.
2937
2938This function will not follow symbolic links.
2939Equivalent to chflags(path, flags, follow_symlinks=False).
2940[clinic start generated code]*/
2941
Larry Hastings2f936352014-08-05 14:04:04 +10002942static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002943os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2944/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002945{
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002947 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002948 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002949 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002950 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002951 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002952 }
Victor Stinner292c8352012-10-30 02:17:38 +01002953 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002954}
2955#endif /* HAVE_LCHFLAGS */
2956
Larry Hastings2f936352014-08-05 14:04:04 +10002957
Martin v. Löwis244edc82001-10-04 22:44:26 +00002958#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002959/*[clinic input]
2960os.chroot
2961 path: path_t
2962
2963Change root directory to path.
2964
2965[clinic start generated code]*/
2966
Larry Hastings2f936352014-08-05 14:04:04 +10002967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002968os_chroot_impl(PyObject *module, path_t *path)
2969/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002970{
2971 int res;
2972 Py_BEGIN_ALLOW_THREADS
2973 res = chroot(path->narrow);
2974 Py_END_ALLOW_THREADS
2975 if (res < 0)
2976 return path_error(path);
2977 Py_RETURN_NONE;
2978}
2979#endif /* HAVE_CHROOT */
2980
Martin v. Löwis244edc82001-10-04 22:44:26 +00002981
Guido van Rossum21142a01999-01-08 21:05:37 +00002982#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002983/*[clinic input]
2984os.fsync
2985
2986 fd: fildes
2987
2988Force write of fd to disk.
2989[clinic start generated code]*/
2990
Larry Hastings2f936352014-08-05 14:04:04 +10002991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002992os_fsync_impl(PyObject *module, int fd)
2993/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002994{
2995 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002996}
2997#endif /* HAVE_FSYNC */
2998
Larry Hastings2f936352014-08-05 14:04:04 +10002999
Ross Lagerwall7807c352011-03-17 20:20:30 +02003000#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003001/*[clinic input]
3002os.sync
3003
3004Force write of everything to disk.
3005[clinic start generated code]*/
3006
Larry Hastings2f936352014-08-05 14:04:04 +10003007static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003008os_sync_impl(PyObject *module)
3009/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003010{
3011 Py_BEGIN_ALLOW_THREADS
3012 sync();
3013 Py_END_ALLOW_THREADS
3014 Py_RETURN_NONE;
3015}
Larry Hastings2f936352014-08-05 14:04:04 +10003016#endif /* HAVE_SYNC */
3017
Ross Lagerwall7807c352011-03-17 20:20:30 +02003018
Guido van Rossum21142a01999-01-08 21:05:37 +00003019#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003020#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003021extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3022#endif
3023
Larry Hastings2f936352014-08-05 14:04:04 +10003024/*[clinic input]
3025os.fdatasync
3026
3027 fd: fildes
3028
3029Force write of fd to disk without forcing update of metadata.
3030[clinic start generated code]*/
3031
Larry Hastings2f936352014-08-05 14:04:04 +10003032static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003033os_fdatasync_impl(PyObject *module, int fd)
3034/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003035{
3036 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003037}
3038#endif /* HAVE_FDATASYNC */
3039
3040
Fredrik Lundh10723342000-07-10 16:38:09 +00003041#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003042/*[clinic input]
3043os.chown
3044
3045 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3046 Path to be examined; can be string, bytes, or open-file-descriptor int.
3047
3048 uid: uid_t
3049
3050 gid: gid_t
3051
3052 *
3053
3054 dir_fd : dir_fd(requires='fchownat') = None
3055 If not None, it should be a file descriptor open to a directory,
3056 and path should be relative; path will then be relative to that
3057 directory.
3058
3059 follow_symlinks: bool = True
3060 If False, and the last element of the path is a symbolic link,
3061 stat will examine the symbolic link itself instead of the file
3062 the link points to.
3063
3064Change the owner and group id of path to the numeric uid and gid.\
3065
3066path may always be specified as a string.
3067On some platforms, path may also be specified as an open file descriptor.
3068 If this functionality is unavailable, using it raises an exception.
3069If dir_fd is not None, it should be a file descriptor open to a directory,
3070 and path should be relative; path will then be relative to that directory.
3071If follow_symlinks is False, and the last element of the path is a symbolic
3072 link, chown will modify the symbolic link itself instead of the file the
3073 link points to.
3074It is an error to use dir_fd or follow_symlinks when specifying path as
3075 an open file descriptor.
3076dir_fd and follow_symlinks may not be implemented on your platform.
3077 If they are unavailable, using them will raise a NotImplementedError.
3078
3079[clinic start generated code]*/
3080
Larry Hastings2f936352014-08-05 14:04:04 +10003081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003082os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003083 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003084/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003085{
3086 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087
3088#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3089 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003090 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003091#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003092 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3093 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3094 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003095
3096#ifdef __APPLE__
3097 /*
3098 * This is for Mac OS X 10.3, which doesn't have lchown.
3099 * (But we still have an lchown symbol because of weak-linking.)
3100 * It doesn't have fchownat either. So there's no possibility
3101 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003102 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003103 if ((!follow_symlinks) && (lchown == NULL)) {
3104 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003105 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003106 }
3107#endif
3108
Victor Stinner8c62be82010-05-06 00:08:46 +00003109 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003110#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003111 if (path->fd != -1)
3112 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003113 else
3114#endif
3115#ifdef HAVE_LCHOWN
3116 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003117 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003118 else
3119#endif
3120#ifdef HAVE_FCHOWNAT
3121 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003122 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003123 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3124 else
3125#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003126 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003127 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003128
Larry Hastings2f936352014-08-05 14:04:04 +10003129 if (result)
3130 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003131
Larry Hastings2f936352014-08-05 14:04:04 +10003132 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003133}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003134#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003135
Larry Hastings2f936352014-08-05 14:04:04 +10003136
Christian Heimes4e30a842007-11-30 22:12:06 +00003137#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003138/*[clinic input]
3139os.fchown
3140
3141 fd: int
3142 uid: uid_t
3143 gid: gid_t
3144
3145Change the owner and group id of the file specified by file descriptor.
3146
3147Equivalent to os.chown(fd, uid, gid).
3148
3149[clinic start generated code]*/
3150
Larry Hastings2f936352014-08-05 14:04:04 +10003151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003152os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3153/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003154{
Victor Stinner8c62be82010-05-06 00:08:46 +00003155 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003156 int async_err = 0;
3157
3158 do {
3159 Py_BEGIN_ALLOW_THREADS
3160 res = fchown(fd, uid, gid);
3161 Py_END_ALLOW_THREADS
3162 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3163 if (res != 0)
3164 return (!async_err) ? posix_error() : NULL;
3165
Victor Stinner8c62be82010-05-06 00:08:46 +00003166 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003167}
3168#endif /* HAVE_FCHOWN */
3169
Larry Hastings2f936352014-08-05 14:04:04 +10003170
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003171#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003172/*[clinic input]
3173os.lchown
3174
3175 path : path_t
3176 uid: uid_t
3177 gid: gid_t
3178
3179Change the owner and group id of path to the numeric uid and gid.
3180
3181This function will not follow symbolic links.
3182Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3183[clinic start generated code]*/
3184
Larry Hastings2f936352014-08-05 14:04:04 +10003185static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003186os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3187/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003188{
Victor Stinner8c62be82010-05-06 00:08:46 +00003189 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003190 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003191 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003193 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003194 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003195 }
Larry Hastings2f936352014-08-05 14:04:04 +10003196 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003197}
3198#endif /* HAVE_LCHOWN */
3199
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003200
Barry Warsaw53699e91996-12-10 23:23:01 +00003201static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003202posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003203{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003204 char *buf, *tmpbuf;
3205 char *cwd;
3206 const size_t chunk = 1024;
3207 size_t buflen = 0;
3208 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003209
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003210#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003212 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003213 wchar_t *wbuf2 = wbuf;
3214 PyObject *resobj;
3215 DWORD len;
3216 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003217 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003218 /* If the buffer is large enough, len does not include the
3219 terminating \0. If the buffer is too small, len includes
3220 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003221 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003222 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003223 if (wbuf2)
3224 len = GetCurrentDirectoryW(len, wbuf2);
3225 }
3226 Py_END_ALLOW_THREADS
3227 if (!wbuf2) {
3228 PyErr_NoMemory();
3229 return NULL;
3230 }
3231 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003232 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003233 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003234 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 }
3236 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003237 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003238 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 return resobj;
3240 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003241
3242 if (win32_warn_bytes_api())
3243 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003244#endif
3245
Victor Stinner4403d7d2015-04-25 00:16:10 +02003246 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003247 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003248 do {
3249 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003250#ifdef MS_WINDOWS
3251 if (buflen > INT_MAX) {
3252 PyErr_NoMemory();
3253 break;
3254 }
3255#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003256 tmpbuf = PyMem_RawRealloc(buf, buflen);
3257 if (tmpbuf == NULL)
3258 break;
3259
3260 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003261#ifdef MS_WINDOWS
3262 cwd = getcwd(buf, (int)buflen);
3263#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003264 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003265#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003266 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003268
3269 if (cwd == NULL) {
3270 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003271 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003272 }
3273
Victor Stinner8c62be82010-05-06 00:08:46 +00003274 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003275 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3276 else
3277 obj = PyUnicode_DecodeFSDefault(buf);
3278 PyMem_RawFree(buf);
3279
3280 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003281}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003282
Larry Hastings2f936352014-08-05 14:04:04 +10003283
3284/*[clinic input]
3285os.getcwd
3286
3287Return a unicode string representing the current working directory.
3288[clinic start generated code]*/
3289
Larry Hastings2f936352014-08-05 14:04:04 +10003290static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003291os_getcwd_impl(PyObject *module)
3292/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003293{
3294 return posix_getcwd(0);
3295}
3296
Larry Hastings2f936352014-08-05 14:04:04 +10003297
3298/*[clinic input]
3299os.getcwdb
3300
3301Return a bytes string representing the current working directory.
3302[clinic start generated code]*/
3303
Larry Hastings2f936352014-08-05 14:04:04 +10003304static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003305os_getcwdb_impl(PyObject *module)
3306/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003307{
3308 return posix_getcwd(1);
3309}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003310
Larry Hastings2f936352014-08-05 14:04:04 +10003311
Larry Hastings9cf065c2012-06-22 16:30:09 -07003312#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3313#define HAVE_LINK 1
3314#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003315
Guido van Rossumb6775db1994-08-01 11:34:53 +00003316#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003317/*[clinic input]
3318
3319os.link
3320
3321 src : path_t
3322 dst : path_t
3323 *
3324 src_dir_fd : dir_fd = None
3325 dst_dir_fd : dir_fd = None
3326 follow_symlinks: bool = True
3327
3328Create a hard link to a file.
3329
3330If either src_dir_fd or dst_dir_fd is not None, it should be a file
3331 descriptor open to a directory, and the respective path string (src or dst)
3332 should be relative; the path will then be relative to that directory.
3333If follow_symlinks is False, and the last element of src is a symbolic
3334 link, link will create a link to the symbolic link itself instead of the
3335 file the link points to.
3336src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3337 platform. If they are unavailable, using them will raise a
3338 NotImplementedError.
3339[clinic start generated code]*/
3340
Larry Hastings2f936352014-08-05 14:04:04 +10003341static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003342os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003343 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003344/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003345{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003346#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003347 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003348#else
3349 int result;
3350#endif
3351
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352#ifndef HAVE_LINKAT
3353 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3354 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003355 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 }
3357#endif
3358
Steve Dowercc16be82016-09-08 10:35:16 -07003359#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003360 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361 PyErr_SetString(PyExc_NotImplementedError,
3362 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003363 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364 }
Steve Dowercc16be82016-09-08 10:35:16 -07003365#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003366
Brian Curtin1b9df392010-11-24 20:24:31 +00003367#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003369 if (src->wide)
3370 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003372
Larry Hastings2f936352014-08-05 14:04:04 +10003373 if (!result)
3374 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375#else
3376 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003377#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3379 (dst_dir_fd != DEFAULT_DIR_FD) ||
3380 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003381 result = linkat(src_dir_fd, src->narrow,
3382 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003383 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3384 else
Steve Dowercc16be82016-09-08 10:35:16 -07003385#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003386 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003387 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003388
Larry Hastings2f936352014-08-05 14:04:04 +10003389 if (result)
3390 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003391#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003392
Larry Hastings2f936352014-08-05 14:04:04 +10003393 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003394}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003395#endif
3396
Brian Curtin1b9df392010-11-24 20:24:31 +00003397
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003398#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003399static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003400_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003401{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402 PyObject *v;
3403 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3404 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003405 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003406 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003407 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409
Steve Dowercc16be82016-09-08 10:35:16 -07003410 WIN32_FIND_DATAW wFileData;
3411 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003412
Steve Dowercc16be82016-09-08 10:35:16 -07003413 if (!path->wide) { /* Default arg: "." */
3414 po_wchars = L".";
3415 len = 1;
3416 } else {
3417 po_wchars = path->wide;
3418 len = wcslen(path->wide);
3419 }
3420 /* The +5 is so we can append "\\*.*\0" */
3421 wnamebuf = PyMem_New(wchar_t, len + 5);
3422 if (!wnamebuf) {
3423 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 }
Steve Dowercc16be82016-09-08 10:35:16 -07003426 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003427 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003428 wchar_t wch = wnamebuf[len-1];
3429 if (wch != SEP && wch != ALTSEP && wch != L':')
3430 wnamebuf[len++] = SEP;
3431 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003432 }
Steve Dowercc16be82016-09-08 10:35:16 -07003433 if ((list = PyList_New(0)) == NULL) {
3434 goto exit;
3435 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003436 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003437 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003438 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 if (hFindFile == INVALID_HANDLE_VALUE) {
3440 int error = GetLastError();
3441 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 goto exit;
3443 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003444 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003446 }
3447 do {
3448 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003449 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3450 wcscmp(wFileData.cFileName, L"..") != 0) {
3451 v = PyUnicode_FromWideChar(wFileData.cFileName,
3452 wcslen(wFileData.cFileName));
3453 if (path->narrow && v) {
3454 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3455 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 Py_DECREF(list);
3458 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003459 break;
3460 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003462 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 Py_DECREF(list);
3464 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003465 break;
3466 }
3467 Py_DECREF(v);
3468 }
3469 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003470 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003471 Py_END_ALLOW_THREADS
3472 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3473 it got to the end of the directory. */
3474 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003476 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003478 }
3479 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003480
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481exit:
3482 if (hFindFile != INVALID_HANDLE_VALUE) {
3483 if (FindClose(hFindFile) == FALSE) {
3484 if (list != NULL) {
3485 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003486 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 }
3488 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003490 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003491
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003493} /* end of _listdir_windows_no_opendir */
3494
3495#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3496
3497static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003498_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003499{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003500 PyObject *v;
3501 DIR *dirp = NULL;
3502 struct dirent *ep;
3503 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003504#ifdef HAVE_FDOPENDIR
3505 int fd = -1;
3506#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003507
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003510 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003512 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003513 if (fd == -1)
3514 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003515
Larry Hastingsfdaea062012-06-25 04:42:23 -07003516 return_str = 1;
3517
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 Py_BEGIN_ALLOW_THREADS
3519 dirp = fdopendir(fd);
3520 Py_END_ALLOW_THREADS
3521 }
3522 else
3523#endif
3524 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003525 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003526 if (path->narrow) {
3527 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003528 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003529 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003530 }
3531 else {
3532 name = ".";
3533 return_str = 1;
3534 }
3535
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 Py_BEGIN_ALLOW_THREADS
3537 dirp = opendir(name);
3538 Py_END_ALLOW_THREADS
3539 }
3540
3541 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003542 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003543#ifdef HAVE_FDOPENDIR
3544 if (fd != -1) {
3545 Py_BEGIN_ALLOW_THREADS
3546 close(fd);
3547 Py_END_ALLOW_THREADS
3548 }
3549#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 goto exit;
3551 }
3552 if ((list = PyList_New(0)) == NULL) {
3553 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 }
3555 for (;;) {
3556 errno = 0;
3557 Py_BEGIN_ALLOW_THREADS
3558 ep = readdir(dirp);
3559 Py_END_ALLOW_THREADS
3560 if (ep == NULL) {
3561 if (errno == 0) {
3562 break;
3563 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003565 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 }
3568 }
3569 if (ep->d_name[0] == '.' &&
3570 (NAMLEN(ep) == 1 ||
3571 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3572 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003573 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003574 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3575 else
3576 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 break;
3580 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003583 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003584 break;
3585 }
3586 Py_DECREF(v);
3587 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003588
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589exit:
3590 if (dirp != NULL) {
3591 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003592#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593 if (fd > -1)
3594 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003595#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596 closedir(dirp);
3597 Py_END_ALLOW_THREADS
3598 }
3599
Larry Hastings9cf065c2012-06-22 16:30:09 -07003600 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003601} /* end of _posix_listdir */
3602#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003603
Larry Hastings2f936352014-08-05 14:04:04 +10003604
3605/*[clinic input]
3606os.listdir
3607
3608 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3609
3610Return a list containing the names of the files in the directory.
3611
3612path can be specified as either str or bytes. If path is bytes,
3613 the filenames returned will also be bytes; in all other circumstances
3614 the filenames returned will be str.
3615If path is None, uses the path='.'.
3616On some platforms, path may also be specified as an open file descriptor;\
3617 the file descriptor must refer to a directory.
3618 If this functionality is unavailable, using it raises NotImplementedError.
3619
3620The list is in arbitrary order. It does not include the special
3621entries '.' and '..' even if they are present in the directory.
3622
3623
3624[clinic start generated code]*/
3625
Larry Hastings2f936352014-08-05 14:04:04 +10003626static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003627os_listdir_impl(PyObject *module, path_t *path)
3628/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003629{
3630#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3631 return _listdir_windows_no_opendir(path, NULL);
3632#else
3633 return _posix_listdir(path, NULL);
3634#endif
3635}
3636
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003637#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003638/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003639/*[clinic input]
3640os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003641
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003642 path: path_t
3643 /
3644
3645[clinic start generated code]*/
3646
3647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003648os__getfullpathname_impl(PyObject *module, path_t *path)
3649/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003650{
Steve Dowercc16be82016-09-08 10:35:16 -07003651 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3652 wchar_t *wtemp;
3653 DWORD result;
3654 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003655
Steve Dowercc16be82016-09-08 10:35:16 -07003656 result = GetFullPathNameW(path->wide,
3657 Py_ARRAY_LENGTH(woutbuf),
3658 woutbuf, &wtemp);
3659 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3660 woutbufp = PyMem_New(wchar_t, result);
3661 if (!woutbufp)
3662 return PyErr_NoMemory();
3663 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 }
Steve Dowercc16be82016-09-08 10:35:16 -07003665 if (result) {
3666 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3667 if (path->narrow)
3668 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3669 } else
3670 v = win32_error_object("GetFullPathNameW", path->object);
3671 if (woutbufp != woutbuf)
3672 PyMem_Free(woutbufp);
3673 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003674}
Brian Curtind40e6f72010-07-08 21:39:08 +00003675
Brian Curtind25aef52011-06-13 15:16:04 -05003676
Larry Hastings2f936352014-08-05 14:04:04 +10003677/*[clinic input]
3678os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003679
Larry Hastings2f936352014-08-05 14:04:04 +10003680 path: unicode
3681 /
3682
3683A helper function for samepath on windows.
3684[clinic start generated code]*/
3685
Larry Hastings2f936352014-08-05 14:04:04 +10003686static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003687os__getfinalpathname_impl(PyObject *module, PyObject *path)
3688/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003689{
3690 HANDLE hFile;
3691 int buf_size;
3692 wchar_t *target_path;
3693 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003694 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003695 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003696
Larry Hastings2f936352014-08-05 14:04:04 +10003697 path_wchar = PyUnicode_AsUnicode(path);
3698 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003699 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003700
Brian Curtind40e6f72010-07-08 21:39:08 +00003701 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003702 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003703 0, /* desired access */
3704 0, /* share mode */
3705 NULL, /* security attributes */
3706 OPEN_EXISTING,
3707 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3708 FILE_FLAG_BACKUP_SEMANTICS,
3709 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003710
Victor Stinnereb5657a2011-09-30 01:44:27 +02003711 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003712 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003713
3714 /* We have a good handle to the target, use it to determine the
3715 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003716 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003717
3718 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003719 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003720
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003721 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003722 if(!target_path)
3723 return PyErr_NoMemory();
3724
Steve Dower2ea51c92015-03-20 21:49:12 -07003725 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3726 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003727 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003728 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003729
3730 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003731 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003732
3733 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003734 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003735 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003736 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003737}
Brian Curtin62857742010-09-06 17:07:27 +00003738
Brian Curtin95d028f2011-06-09 09:10:38 -05003739PyDoc_STRVAR(posix__isdir__doc__,
3740"Return true if the pathname refers to an existing directory.");
3741
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003742/*[clinic input]
3743os._isdir
3744
3745 path: path_t
3746 /
3747
3748[clinic start generated code]*/
3749
Brian Curtin9c669cc2011-06-08 18:17:18 -05003750static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003751os__isdir_impl(PyObject *module, path_t *path)
3752/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003753{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003754 DWORD attributes;
3755
Steve Dowerb22a6772016-07-17 20:49:38 -07003756 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003757 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003758 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003759
Brian Curtin9c669cc2011-06-08 18:17:18 -05003760 if (attributes == INVALID_FILE_ATTRIBUTES)
3761 Py_RETURN_FALSE;
3762
Brian Curtin9c669cc2011-06-08 18:17:18 -05003763 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3764 Py_RETURN_TRUE;
3765 else
3766 Py_RETURN_FALSE;
3767}
Tim Golden6b528062013-08-01 12:44:00 +01003768
Tim Golden6b528062013-08-01 12:44:00 +01003769
Larry Hastings2f936352014-08-05 14:04:04 +10003770/*[clinic input]
3771os._getvolumepathname
3772
3773 path: unicode
3774
3775A helper function for ismount on Win32.
3776[clinic start generated code]*/
3777
Larry Hastings2f936352014-08-05 14:04:04 +10003778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003779os__getvolumepathname_impl(PyObject *module, PyObject *path)
3780/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003781{
3782 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003783 const wchar_t *path_wchar;
3784 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003785 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003786 BOOL ret;
3787
Larry Hastings2f936352014-08-05 14:04:04 +10003788 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3789 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003790 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003791 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003792
3793 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003794 buflen = Py_MAX(buflen, MAX_PATH);
3795
3796 if (buflen > DWORD_MAX) {
3797 PyErr_SetString(PyExc_OverflowError, "path too long");
3798 return NULL;
3799 }
3800
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003801 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003802 if (mountpath == NULL)
3803 return PyErr_NoMemory();
3804
3805 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003806 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003807 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003808 Py_END_ALLOW_THREADS
3809
3810 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003811 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003812 goto exit;
3813 }
3814 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3815
3816exit:
3817 PyMem_Free(mountpath);
3818 return result;
3819}
Tim Golden6b528062013-08-01 12:44:00 +01003820
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003821#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003822
Larry Hastings2f936352014-08-05 14:04:04 +10003823
3824/*[clinic input]
3825os.mkdir
3826
3827 path : path_t
3828
3829 mode: int = 0o777
3830
3831 *
3832
3833 dir_fd : dir_fd(requires='mkdirat') = None
3834
3835# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3836
3837Create a directory.
3838
3839If dir_fd is not None, it should be a file descriptor open to a directory,
3840 and path should be relative; path will then be relative to that directory.
3841dir_fd may not be implemented on your platform.
3842 If it is unavailable, using it will raise a NotImplementedError.
3843
3844The mode argument is ignored on Windows.
3845[clinic start generated code]*/
3846
Larry Hastings2f936352014-08-05 14:04:04 +10003847static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003848os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3849/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003850{
3851 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003852
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003853#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003854 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003855 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003856 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003857
Larry Hastings2f936352014-08-05 14:04:04 +10003858 if (!result)
3859 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003860#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003861 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003862#if HAVE_MKDIRAT
3863 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003864 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003865 else
3866#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003867#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003868 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003869#else
Larry Hastings2f936352014-08-05 14:04:04 +10003870 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003871#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003872 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003873 if (result < 0)
3874 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003875#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003876 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003877}
3878
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003879
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003880/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3881#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003882#include <sys/resource.h>
3883#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003884
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003885
3886#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003887/*[clinic input]
3888os.nice
3889
3890 increment: int
3891 /
3892
3893Add increment to the priority of process and return the new priority.
3894[clinic start generated code]*/
3895
Larry Hastings2f936352014-08-05 14:04:04 +10003896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003897os_nice_impl(PyObject *module, int increment)
3898/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003899{
3900 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003901
Victor Stinner8c62be82010-05-06 00:08:46 +00003902 /* There are two flavours of 'nice': one that returns the new
3903 priority (as required by almost all standards out there) and the
3904 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3905 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003906
Victor Stinner8c62be82010-05-06 00:08:46 +00003907 If we are of the nice family that returns the new priority, we
3908 need to clear errno before the call, and check if errno is filled
3909 before calling posix_error() on a returnvalue of -1, because the
3910 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003911
Victor Stinner8c62be82010-05-06 00:08:46 +00003912 errno = 0;
3913 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003914#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003915 if (value == 0)
3916 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003917#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003918 if (value == -1 && errno != 0)
3919 /* either nice() or getpriority() returned an error */
3920 return posix_error();
3921 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003922}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003923#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003924
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003925
3926#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003927/*[clinic input]
3928os.getpriority
3929
3930 which: int
3931 who: int
3932
3933Return program scheduling priority.
3934[clinic start generated code]*/
3935
Larry Hastings2f936352014-08-05 14:04:04 +10003936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003937os_getpriority_impl(PyObject *module, int which, int who)
3938/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003939{
3940 int retval;
3941
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003942 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003943 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003944 if (errno != 0)
3945 return posix_error();
3946 return PyLong_FromLong((long)retval);
3947}
3948#endif /* HAVE_GETPRIORITY */
3949
3950
3951#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003952/*[clinic input]
3953os.setpriority
3954
3955 which: int
3956 who: int
3957 priority: int
3958
3959Set program scheduling priority.
3960[clinic start generated code]*/
3961
Larry Hastings2f936352014-08-05 14:04:04 +10003962static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003963os_setpriority_impl(PyObject *module, int which, int who, int priority)
3964/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003965{
3966 int retval;
3967
3968 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003969 if (retval == -1)
3970 return posix_error();
3971 Py_RETURN_NONE;
3972}
3973#endif /* HAVE_SETPRIORITY */
3974
3975
Barry Warsaw53699e91996-12-10 23:23:01 +00003976static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003977internal_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 +00003978{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003979 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003980 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003982#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003984 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003985#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003987#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003988
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3990 (dst_dir_fd != DEFAULT_DIR_FD);
3991#ifndef HAVE_RENAMEAT
3992 if (dir_fd_specified) {
3993 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003994 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003995 }
3996#endif
3997
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998#ifdef MS_WINDOWS
3999 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004000 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004001 Py_END_ALLOW_THREADS
4002
Larry Hastings2f936352014-08-05 14:04:04 +10004003 if (!result)
4004 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005
4006#else
Steve Dowercc16be82016-09-08 10:35:16 -07004007 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
4008 PyErr_Format(PyExc_ValueError,
4009 "%s: src and dst must be the same type", function_name);
4010 return NULL;
4011 }
4012
Larry Hastings9cf065c2012-06-22 16:30:09 -07004013 Py_BEGIN_ALLOW_THREADS
4014#ifdef HAVE_RENAMEAT
4015 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004016 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004017 else
4018#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004019 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004020 Py_END_ALLOW_THREADS
4021
Larry Hastings2f936352014-08-05 14:04:04 +10004022 if (result)
4023 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004024#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004025 Py_RETURN_NONE;
4026}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004027
Larry Hastings2f936352014-08-05 14:04:04 +10004028
4029/*[clinic input]
4030os.rename
4031
4032 src : path_t
4033 dst : path_t
4034 *
4035 src_dir_fd : dir_fd = None
4036 dst_dir_fd : dir_fd = None
4037
4038Rename a file or directory.
4039
4040If either src_dir_fd or dst_dir_fd is not None, it should be a file
4041 descriptor open to a directory, and the respective path string (src or dst)
4042 should be relative; the path will then be relative to that directory.
4043src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4044 If they are unavailable, using them will raise a NotImplementedError.
4045[clinic start generated code]*/
4046
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004048os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004049 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004050/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004051{
Larry Hastings2f936352014-08-05 14:04:04 +10004052 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004053}
4054
Larry Hastings2f936352014-08-05 14:04:04 +10004055
4056/*[clinic input]
4057os.replace = os.rename
4058
4059Rename a file or directory, overwriting the destination.
4060
4061If either src_dir_fd or dst_dir_fd is not None, it should be a file
4062 descriptor open to a directory, and the respective path string (src or dst)
4063 should be relative; the path will then be relative to that directory.
4064src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4065 If they are unavailable, using them will raise a NotImplementedError."
4066[clinic start generated code]*/
4067
Larry Hastings2f936352014-08-05 14:04:04 +10004068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004069os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4070 int dst_dir_fd)
4071/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004072{
4073 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4074}
4075
4076
4077/*[clinic input]
4078os.rmdir
4079
4080 path: path_t
4081 *
4082 dir_fd: dir_fd(requires='unlinkat') = None
4083
4084Remove a directory.
4085
4086If dir_fd is not None, it should be a file descriptor open to a directory,
4087 and path should be relative; path will then be relative to that directory.
4088dir_fd may not be implemented on your platform.
4089 If it is unavailable, using it will raise a NotImplementedError.
4090[clinic start generated code]*/
4091
Larry Hastings2f936352014-08-05 14:04:04 +10004092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004093os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4094/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004095{
4096 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004097
4098 Py_BEGIN_ALLOW_THREADS
4099#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004100 /* Windows, success=1, UNIX, success=0 */
4101 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004102#else
4103#ifdef HAVE_UNLINKAT
4104 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004105 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004106 else
4107#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004108 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004109#endif
4110 Py_END_ALLOW_THREADS
4111
Larry Hastings2f936352014-08-05 14:04:04 +10004112 if (result)
4113 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004114
Larry Hastings2f936352014-08-05 14:04:04 +10004115 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004116}
4117
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004118
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004119#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004120#ifdef MS_WINDOWS
4121/*[clinic input]
4122os.system -> long
4123
4124 command: Py_UNICODE
4125
4126Execute the command in a subshell.
4127[clinic start generated code]*/
4128
Larry Hastings2f936352014-08-05 14:04:04 +10004129static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004130os_system_impl(PyObject *module, Py_UNICODE *command)
4131/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004132{
4133 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004134 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004135 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004136 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004137 return result;
4138}
4139#else /* MS_WINDOWS */
4140/*[clinic input]
4141os.system -> long
4142
4143 command: FSConverter
4144
4145Execute the command in a subshell.
4146[clinic start generated code]*/
4147
Larry Hastings2f936352014-08-05 14:04:04 +10004148static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004149os_system_impl(PyObject *module, PyObject *command)
4150/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004151{
4152 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004153 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004154 Py_BEGIN_ALLOW_THREADS
4155 result = system(bytes);
4156 Py_END_ALLOW_THREADS
4157 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004158}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004159#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004160#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004161
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004162
Larry Hastings2f936352014-08-05 14:04:04 +10004163/*[clinic input]
4164os.umask
4165
4166 mask: int
4167 /
4168
4169Set the current numeric umask and return the previous umask.
4170[clinic start generated code]*/
4171
Larry Hastings2f936352014-08-05 14:04:04 +10004172static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004173os_umask_impl(PyObject *module, int mask)
4174/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004175{
4176 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004177 if (i < 0)
4178 return posix_error();
4179 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004180}
4181
Brian Curtind40e6f72010-07-08 21:39:08 +00004182#ifdef MS_WINDOWS
4183
4184/* override the default DeleteFileW behavior so that directory
4185symlinks can be removed with this function, the same as with
4186Unix symlinks */
4187BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4188{
4189 WIN32_FILE_ATTRIBUTE_DATA info;
4190 WIN32_FIND_DATAW find_data;
4191 HANDLE find_data_handle;
4192 int is_directory = 0;
4193 int is_link = 0;
4194
4195 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4196 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004197
Brian Curtind40e6f72010-07-08 21:39:08 +00004198 /* Get WIN32_FIND_DATA structure for the path to determine if
4199 it is a symlink */
4200 if(is_directory &&
4201 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4202 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4203
4204 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004205 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4206 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4207 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4208 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004209 FindClose(find_data_handle);
4210 }
4211 }
4212 }
4213
4214 if (is_directory && is_link)
4215 return RemoveDirectoryW(lpFileName);
4216
4217 return DeleteFileW(lpFileName);
4218}
4219#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004220
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004221
Larry Hastings2f936352014-08-05 14:04:04 +10004222/*[clinic input]
4223os.unlink
4224
4225 path: path_t
4226 *
4227 dir_fd: dir_fd(requires='unlinkat')=None
4228
4229Remove a file (same as remove()).
4230
4231If dir_fd is not None, it should be a file descriptor open to a directory,
4232 and path should be relative; path will then be relative to that directory.
4233dir_fd may not be implemented on your platform.
4234 If it is unavailable, using it will raise a NotImplementedError.
4235
4236[clinic start generated code]*/
4237
Larry Hastings2f936352014-08-05 14:04:04 +10004238static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004239os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4240/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004241{
4242 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004243
4244 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004245 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004246#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004247 /* Windows, success=1, UNIX, success=0 */
4248 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004249#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004250#ifdef HAVE_UNLINKAT
4251 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004252 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004253 else
4254#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004255 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004256#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004257 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004258 Py_END_ALLOW_THREADS
4259
Larry Hastings2f936352014-08-05 14:04:04 +10004260 if (result)
4261 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004262
Larry Hastings2f936352014-08-05 14:04:04 +10004263 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004264}
4265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Larry Hastings2f936352014-08-05 14:04:04 +10004267/*[clinic input]
4268os.remove = os.unlink
4269
4270Remove a file (same as unlink()).
4271
4272If dir_fd is not None, it should be a file descriptor open to a directory,
4273 and path should be relative; path will then be relative to that directory.
4274dir_fd may not be implemented on your platform.
4275 If it is unavailable, using it will raise a NotImplementedError.
4276[clinic start generated code]*/
4277
Larry Hastings2f936352014-08-05 14:04:04 +10004278static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004279os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4280/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004281{
4282 return os_unlink_impl(module, path, dir_fd);
4283}
4284
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004285
Larry Hastings605a62d2012-06-24 04:33:36 -07004286static PyStructSequence_Field uname_result_fields[] = {
4287 {"sysname", "operating system name"},
4288 {"nodename", "name of machine on network (implementation-defined)"},
4289 {"release", "operating system release"},
4290 {"version", "operating system version"},
4291 {"machine", "hardware identifier"},
4292 {NULL}
4293};
4294
4295PyDoc_STRVAR(uname_result__doc__,
4296"uname_result: Result from os.uname().\n\n\
4297This object may be accessed either as a tuple of\n\
4298 (sysname, nodename, release, version, machine),\n\
4299or via the attributes sysname, nodename, release, version, and machine.\n\
4300\n\
4301See os.uname for more information.");
4302
4303static PyStructSequence_Desc uname_result_desc = {
4304 "uname_result", /* name */
4305 uname_result__doc__, /* doc */
4306 uname_result_fields,
4307 5
4308};
4309
4310static PyTypeObject UnameResultType;
4311
4312
4313#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004314/*[clinic input]
4315os.uname
4316
4317Return an object identifying the current operating system.
4318
4319The object behaves like a named tuple with the following fields:
4320 (sysname, nodename, release, version, machine)
4321
4322[clinic start generated code]*/
4323
Larry Hastings2f936352014-08-05 14:04:04 +10004324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004325os_uname_impl(PyObject *module)
4326/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004327{
Victor Stinner8c62be82010-05-06 00:08:46 +00004328 struct utsname u;
4329 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004330 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004331
Victor Stinner8c62be82010-05-06 00:08:46 +00004332 Py_BEGIN_ALLOW_THREADS
4333 res = uname(&u);
4334 Py_END_ALLOW_THREADS
4335 if (res < 0)
4336 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004337
4338 value = PyStructSequence_New(&UnameResultType);
4339 if (value == NULL)
4340 return NULL;
4341
4342#define SET(i, field) \
4343 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004344 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004345 if (!o) { \
4346 Py_DECREF(value); \
4347 return NULL; \
4348 } \
4349 PyStructSequence_SET_ITEM(value, i, o); \
4350 } \
4351
4352 SET(0, u.sysname);
4353 SET(1, u.nodename);
4354 SET(2, u.release);
4355 SET(3, u.version);
4356 SET(4, u.machine);
4357
4358#undef SET
4359
4360 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004361}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004362#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004363
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004364
Larry Hastings9cf065c2012-06-22 16:30:09 -07004365
4366typedef struct {
4367 int now;
4368 time_t atime_s;
4369 long atime_ns;
4370 time_t mtime_s;
4371 long mtime_ns;
4372} utime_t;
4373
4374/*
Victor Stinner484df002014-10-09 13:52:31 +02004375 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376 * they also intentionally leak the declaration of a pointer named "time"
4377 */
4378#define UTIME_TO_TIMESPEC \
4379 struct timespec ts[2]; \
4380 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004381 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 time = NULL; \
4383 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004384 ts[0].tv_sec = ut->atime_s; \
4385 ts[0].tv_nsec = ut->atime_ns; \
4386 ts[1].tv_sec = ut->mtime_s; \
4387 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388 time = ts; \
4389 } \
4390
4391#define UTIME_TO_TIMEVAL \
4392 struct timeval tv[2]; \
4393 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004394 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004395 time = NULL; \
4396 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004397 tv[0].tv_sec = ut->atime_s; \
4398 tv[0].tv_usec = ut->atime_ns / 1000; \
4399 tv[1].tv_sec = ut->mtime_s; \
4400 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004401 time = tv; \
4402 } \
4403
4404#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004405 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004406 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004407 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408 time = NULL; \
4409 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004410 u.actime = ut->atime_s; \
4411 u.modtime = ut->mtime_s; \
4412 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004413 }
4414
4415#define UTIME_TO_TIME_T \
4416 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004417 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004418 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004419 time = NULL; \
4420 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004421 timet[0] = ut->atime_s; \
4422 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004423 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004424 } \
4425
4426
Victor Stinner528a9ab2015-09-03 21:30:26 +02004427#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004428
4429static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004430utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004431{
4432#ifdef HAVE_UTIMENSAT
4433 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4434 UTIME_TO_TIMESPEC;
4435 return utimensat(dir_fd, path, time, flags);
4436#elif defined(HAVE_FUTIMESAT)
4437 UTIME_TO_TIMEVAL;
4438 /*
4439 * follow_symlinks will never be false here;
4440 * we only allow !follow_symlinks and dir_fd together
4441 * if we have utimensat()
4442 */
4443 assert(follow_symlinks);
4444 return futimesat(dir_fd, path, time);
4445#endif
4446}
4447
Larry Hastings2f936352014-08-05 14:04:04 +10004448 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4449#else
4450 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004451#endif
4452
Victor Stinner528a9ab2015-09-03 21:30:26 +02004453#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004454
4455static int
Victor Stinner484df002014-10-09 13:52:31 +02004456utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004457{
4458#ifdef HAVE_FUTIMENS
4459 UTIME_TO_TIMESPEC;
4460 return futimens(fd, time);
4461#else
4462 UTIME_TO_TIMEVAL;
4463 return futimes(fd, time);
4464#endif
4465}
4466
Larry Hastings2f936352014-08-05 14:04:04 +10004467 #define PATH_UTIME_HAVE_FD 1
4468#else
4469 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004470#endif
4471
Victor Stinner5ebae872015-09-22 01:29:33 +02004472#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4473# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4474#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004475
Victor Stinner4552ced2015-09-21 22:37:15 +02004476#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004477
4478static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004479utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004480{
4481#ifdef HAVE_UTIMENSAT
4482 UTIME_TO_TIMESPEC;
4483 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4484#else
4485 UTIME_TO_TIMEVAL;
4486 return lutimes(path, time);
4487#endif
4488}
4489
4490#endif
4491
4492#ifndef MS_WINDOWS
4493
4494static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004495utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004496{
4497#ifdef HAVE_UTIMENSAT
4498 UTIME_TO_TIMESPEC;
4499 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4500#elif defined(HAVE_UTIMES)
4501 UTIME_TO_TIMEVAL;
4502 return utimes(path, time);
4503#elif defined(HAVE_UTIME_H)
4504 UTIME_TO_UTIMBUF;
4505 return utime(path, time);
4506#else
4507 UTIME_TO_TIME_T;
4508 return utime(path, time);
4509#endif
4510}
4511
4512#endif
4513
Larry Hastings76ad59b2012-05-03 00:30:07 -07004514static int
4515split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4516{
4517 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004518 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004519 divmod = PyNumber_Divmod(py_long, billion);
4520 if (!divmod)
4521 goto exit;
4522 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4523 if ((*s == -1) && PyErr_Occurred())
4524 goto exit;
4525 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004526 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004527 goto exit;
4528
4529 result = 1;
4530exit:
4531 Py_XDECREF(divmod);
4532 return result;
4533}
4534
Larry Hastings2f936352014-08-05 14:04:04 +10004535
4536/*[clinic input]
4537os.utime
4538
4539 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4540 times: object = NULL
4541 *
4542 ns: object = NULL
4543 dir_fd: dir_fd(requires='futimensat') = None
4544 follow_symlinks: bool=True
4545
Martin Panter0ff89092015-09-09 01:56:53 +00004546# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004547
4548Set the access and modified time of path.
4549
4550path may always be specified as a string.
4551On some platforms, path may also be specified as an open file descriptor.
4552 If this functionality is unavailable, using it raises an exception.
4553
4554If times is not None, it must be a tuple (atime, mtime);
4555 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004556If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004557 atime_ns and mtime_ns should be expressed as integer nanoseconds
4558 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004559If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004560Specifying tuples for both times and ns is an error.
4561
4562If dir_fd is not None, it should be a file descriptor open to a directory,
4563 and path should be relative; path will then be relative to that directory.
4564If follow_symlinks is False, and the last element of the path is a symbolic
4565 link, utime will modify the symbolic link itself instead of the file the
4566 link points to.
4567It is an error to use dir_fd or follow_symlinks when specifying path
4568 as an open file descriptor.
4569dir_fd and follow_symlinks may not be available on your platform.
4570 If they are unavailable, using them will raise a NotImplementedError.
4571
4572[clinic start generated code]*/
4573
Larry Hastings2f936352014-08-05 14:04:04 +10004574static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004575os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4576 int dir_fd, int follow_symlinks)
4577/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004578{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579#ifdef MS_WINDOWS
4580 HANDLE hFile;
4581 FILETIME atime, mtime;
4582#else
4583 int result;
4584#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004585
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004587 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004588
Christian Heimesb3c87242013-08-01 00:08:16 +02004589 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004590
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591 if (times && (times != Py_None) && ns) {
4592 PyErr_SetString(PyExc_ValueError,
4593 "utime: you may specify either 'times'"
4594 " or 'ns' but not both");
4595 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004596 }
4597
4598 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004599 time_t a_sec, m_sec;
4600 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004601 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602 PyErr_SetString(PyExc_TypeError,
4603 "utime: 'times' must be either"
4604 " a tuple of two ints or None");
4605 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004606 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004608 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004609 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004610 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004611 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004613 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004614 utime.atime_s = a_sec;
4615 utime.atime_ns = a_nsec;
4616 utime.mtime_s = m_sec;
4617 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004618 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004619 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004620 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621 PyErr_SetString(PyExc_TypeError,
4622 "utime: 'ns' must be a tuple of two ints");
4623 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004624 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004625 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004626 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004628 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629 &utime.mtime_s, &utime.mtime_ns)) {
4630 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004631 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 }
4633 else {
4634 /* times and ns are both None/unspecified. use "now". */
4635 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004636 }
4637
Victor Stinner4552ced2015-09-21 22:37:15 +02004638#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639 if (follow_symlinks_specified("utime", follow_symlinks))
4640 goto exit;
4641#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004642
Larry Hastings2f936352014-08-05 14:04:04 +10004643 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4644 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4645 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004646 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004647
Larry Hastings9cf065c2012-06-22 16:30:09 -07004648#if !defined(HAVE_UTIMENSAT)
4649 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004650 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 "utime: cannot use dir_fd and follow_symlinks "
4652 "together on this platform");
4653 goto exit;
4654 }
4655#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004656
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004657#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004658 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004659 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4660 NULL, OPEN_EXISTING,
4661 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662 Py_END_ALLOW_THREADS
4663 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004664 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004666 }
4667
Larry Hastings9cf065c2012-06-22 16:30:09 -07004668 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004669 GetSystemTimeAsFileTime(&mtime);
4670 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004671 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004672 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004673 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4674 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004675 }
4676 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4677 /* Avoid putting the file name into the error here,
4678 as that may confuse the user into believing that
4679 something is wrong with the file, when it also
4680 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004681 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004682 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004683 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004684#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004686
Victor Stinner4552ced2015-09-21 22:37:15 +02004687#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004688 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004689 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004691#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004692
Victor Stinner528a9ab2015-09-03 21:30:26 +02004693#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004694 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004695 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696 else
4697#endif
4698
Victor Stinner528a9ab2015-09-03 21:30:26 +02004699#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004700 if (path->fd != -1)
4701 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004702 else
4703#endif
4704
Larry Hastings2f936352014-08-05 14:04:04 +10004705 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706
4707 Py_END_ALLOW_THREADS
4708
4709 if (result < 0) {
4710 /* see previous comment about not putting filename in error here */
4711 return_value = posix_error();
4712 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004713 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004714
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004715#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004716
4717 Py_INCREF(Py_None);
4718 return_value = Py_None;
4719
4720exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004721#ifdef MS_WINDOWS
4722 if (hFile != INVALID_HANDLE_VALUE)
4723 CloseHandle(hFile);
4724#endif
4725 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004726}
4727
Guido van Rossum3b066191991-06-04 19:40:25 +00004728/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004729
Larry Hastings2f936352014-08-05 14:04:04 +10004730
4731/*[clinic input]
4732os._exit
4733
4734 status: int
4735
4736Exit to the system with specified status, without normal exit processing.
4737[clinic start generated code]*/
4738
Larry Hastings2f936352014-08-05 14:04:04 +10004739static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004740os__exit_impl(PyObject *module, int status)
4741/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004742{
4743 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004744 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004745}
4746
Steve Dowercc16be82016-09-08 10:35:16 -07004747#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4748#define EXECV_CHAR wchar_t
4749#else
4750#define EXECV_CHAR char
4751#endif
4752
Martin v. Löwis114619e2002-10-07 06:44:21 +00004753#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4754static void
Steve Dowercc16be82016-09-08 10:35:16 -07004755free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004756{
Victor Stinner8c62be82010-05-06 00:08:46 +00004757 Py_ssize_t i;
4758 for (i = 0; i < count; i++)
4759 PyMem_Free(array[i]);
4760 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004761}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004762
Antoine Pitrou69f71142009-05-24 21:25:49 +00004763static
Steve Dowercc16be82016-09-08 10:35:16 -07004764int fsconvert_strdup(PyObject *o, EXECV_CHAR**out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004765{
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 Py_ssize_t size;
Steve Dowercc16be82016-09-08 10:35:16 -07004767#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4768 *out = PyUnicode_AsWideCharString(o, &size);
4769 if (!*out)
4770 return 0;
4771#else
4772 PyObject *bytes;
Victor Stinner8c62be82010-05-06 00:08:46 +00004773 if (!PyUnicode_FSConverter(o, &bytes))
4774 return 0;
4775 size = PyBytes_GET_SIZE(bytes);
4776 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004777 if (!*out) {
4778 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004779 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004780 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004781 memcpy(*out, PyBytes_AsString(bytes), size+1);
4782 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07004783#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004784 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004785}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004786#endif
4787
Ross Lagerwall7807c352011-03-17 20:20:30 +02004788#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004789static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004790parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4791{
Victor Stinner8c62be82010-05-06 00:08:46 +00004792 Py_ssize_t i, pos, envc;
4793 PyObject *keys=NULL, *vals=NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004794 PyObject *key, *val, *keyval;
4795 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004796
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 i = PyMapping_Size(env);
4798 if (i < 0)
4799 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004800 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 if (envlist == NULL) {
4802 PyErr_NoMemory();
4803 return NULL;
4804 }
4805 envc = 0;
4806 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004807 if (!keys)
4808 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004809 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004810 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 goto error;
4812 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4813 PyErr_Format(PyExc_TypeError,
4814 "env.keys() or env.values() is not a list");
4815 goto error;
4816 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004817
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 for (pos = 0; pos < i; pos++) {
4819 key = PyList_GetItem(keys, pos);
4820 val = PyList_GetItem(vals, pos);
4821 if (!key || !val)
4822 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004823
Steve Dowercc16be82016-09-08 10:35:16 -07004824 keyval = PyUnicode_FromFormat("%U=%U", key, val);
4825 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004826 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004827
4828 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4829 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004830 goto error;
4831 }
Steve Dowercc16be82016-09-08 10:35:16 -07004832
4833 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 }
4835 Py_DECREF(vals);
4836 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004837
Victor Stinner8c62be82010-05-06 00:08:46 +00004838 envlist[envc] = 0;
4839 *envc_ptr = envc;
4840 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004841
4842error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 Py_XDECREF(keys);
4844 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004845 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004846 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004847}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004848
Steve Dowercc16be82016-09-08 10:35:16 -07004849static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004850parse_arglist(PyObject* argv, Py_ssize_t *argc)
4851{
4852 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004853 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004854 if (argvlist == NULL) {
4855 PyErr_NoMemory();
4856 return NULL;
4857 }
4858 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004859 PyObject* item = PySequence_ITEM(argv, i);
4860 if (item == NULL)
4861 goto fail;
4862 if (!fsconvert_strdup(item, &argvlist[i])) {
4863 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004864 goto fail;
4865 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004866 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004867 }
4868 argvlist[*argc] = NULL;
4869 return argvlist;
4870fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004871 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004872 free_string_array(argvlist, *argc);
4873 return NULL;
4874}
Steve Dowercc16be82016-09-08 10:35:16 -07004875
Ross Lagerwall7807c352011-03-17 20:20:30 +02004876#endif
4877
Larry Hastings2f936352014-08-05 14:04:04 +10004878
Ross Lagerwall7807c352011-03-17 20:20:30 +02004879#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004880/*[clinic input]
4881os.execv
4882
Steve Dowercc16be82016-09-08 10:35:16 -07004883 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004884 Path of executable file.
4885 argv: object
4886 Tuple or list of strings.
4887 /
4888
4889Execute an executable path with arguments, replacing current process.
4890[clinic start generated code]*/
4891
Larry Hastings2f936352014-08-05 14:04:04 +10004892static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004893os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4894/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004895{
Steve Dowercc16be82016-09-08 10:35:16 -07004896 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004897 Py_ssize_t argc;
4898
4899 /* execv has two arguments: (path, argv), where
4900 argv is a list or tuple of strings. */
4901
Ross Lagerwall7807c352011-03-17 20:20:30 +02004902 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4903 PyErr_SetString(PyExc_TypeError,
4904 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004905 return NULL;
4906 }
4907 argc = PySequence_Size(argv);
4908 if (argc < 1) {
4909 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004910 return NULL;
4911 }
4912
4913 argvlist = parse_arglist(argv, &argc);
4914 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004915 return NULL;
4916 }
4917
Steve Dowercc16be82016-09-08 10:35:16 -07004918#ifdef HAVE_WEXECV
4919 _wexecv(path->wide, argvlist);
4920#else
4921 execv(path->narrow, argvlist);
4922#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004923
4924 /* If we get here it's definitely an error */
4925
4926 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004927 return posix_error();
4928}
4929
Larry Hastings2f936352014-08-05 14:04:04 +10004930
4931/*[clinic input]
4932os.execve
4933
4934 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4935 Path of executable file.
4936 argv: object
4937 Tuple or list of strings.
4938 env: object
4939 Dictionary of strings mapping to strings.
4940
4941Execute an executable path with arguments, replacing current process.
4942[clinic start generated code]*/
4943
Larry Hastings2f936352014-08-05 14:04:04 +10004944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004945os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4946/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004947{
Steve Dowercc16be82016-09-08 10:35:16 -07004948 EXECV_CHAR **argvlist = NULL;
4949 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004950 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004951
Victor Stinner8c62be82010-05-06 00:08:46 +00004952 /* execve has three arguments: (path, argv, env), where
4953 argv is a list or tuple of strings and env is a dictionary
4954 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004955
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004958 "execve: argv must be a tuple or list");
4959 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004961 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 if (!PyMapping_Check(env)) {
4963 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004964 "execve: environment must be a mapping object");
4965 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004967
Ross Lagerwall7807c352011-03-17 20:20:30 +02004968 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004970 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004972
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 envlist = parse_envlist(env, &envc);
4974 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004975 goto fail;
4976
Larry Hastings9cf065c2012-06-22 16:30:09 -07004977#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10004978 if (path->fd > -1)
4979 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004980 else
4981#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004982#ifdef HAVE_WEXECV
4983 _wexecve(path->wide, argvlist, envlist);
4984#else
Larry Hastings2f936352014-08-05 14:04:04 +10004985 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07004986#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004987
4988 /* If we get here it's definitely an error */
4989
Larry Hastings2f936352014-08-05 14:04:04 +10004990 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004991
Steve Dowercc16be82016-09-08 10:35:16 -07004992 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004993 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004994 if (argvlist)
4995 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004996 return NULL;
4997}
Steve Dowercc16be82016-09-08 10:35:16 -07004998
Larry Hastings9cf065c2012-06-22 16:30:09 -07004999#endif /* HAVE_EXECV */
5000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005001
Steve Dowercc16be82016-09-08 10:35:16 -07005002#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10005003/*[clinic input]
5004os.spawnv
5005
5006 mode: int
5007 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005008 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005009 Path of executable file.
5010 argv: object
5011 Tuple or list of strings.
5012 /
5013
5014Execute the program specified by path in a new process.
5015[clinic start generated code]*/
5016
Larry Hastings2f936352014-08-05 14:04:04 +10005017static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005018os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
5019/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005020{
Steve Dowercc16be82016-09-08 10:35:16 -07005021 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005022 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005023 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005024 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005025 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005026
Victor Stinner8c62be82010-05-06 00:08:46 +00005027 /* spawnv has three arguments: (mode, path, argv), where
5028 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005029
Victor Stinner8c62be82010-05-06 00:08:46 +00005030 if (PyList_Check(argv)) {
5031 argc = PyList_Size(argv);
5032 getitem = PyList_GetItem;
5033 }
5034 else if (PyTuple_Check(argv)) {
5035 argc = PyTuple_Size(argv);
5036 getitem = PyTuple_GetItem;
5037 }
5038 else {
5039 PyErr_SetString(PyExc_TypeError,
5040 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005041 return NULL;
5042 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005043
Steve Dowercc16be82016-09-08 10:35:16 -07005044 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005045 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 return PyErr_NoMemory();
5047 }
5048 for (i = 0; i < argc; i++) {
5049 if (!fsconvert_strdup((*getitem)(argv, i),
5050 &argvlist[i])) {
5051 free_string_array(argvlist, i);
5052 PyErr_SetString(
5053 PyExc_TypeError,
5054 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005055 return NULL;
5056 }
5057 }
5058 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005059
Victor Stinner8c62be82010-05-06 00:08:46 +00005060 if (mode == _OLD_P_OVERLAY)
5061 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005062
Victor Stinner8c62be82010-05-06 00:08:46 +00005063 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005064#ifdef HAVE_WSPAWNV
5065 spawnval = _wspawnv(mode, path->wide, argvlist);
5066#else
5067 spawnval = _spawnv(mode, path->narrow, argvlist);
5068#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005069 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005070
Victor Stinner8c62be82010-05-06 00:08:46 +00005071 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005072
Victor Stinner8c62be82010-05-06 00:08:46 +00005073 if (spawnval == -1)
5074 return posix_error();
5075 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005076 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005077}
5078
5079
Larry Hastings2f936352014-08-05 14:04:04 +10005080/*[clinic input]
5081os.spawnve
5082
5083 mode: int
5084 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005085 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005086 Path of executable file.
5087 argv: object
5088 Tuple or list of strings.
5089 env: object
5090 Dictionary of strings mapping to strings.
5091 /
5092
5093Execute the program specified by path in a new process.
5094[clinic start generated code]*/
5095
Larry Hastings2f936352014-08-05 14:04:04 +10005096static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005097os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005098 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005099/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005100{
Steve Dowercc16be82016-09-08 10:35:16 -07005101 EXECV_CHAR **argvlist;
5102 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005104 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005105 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5107 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005108
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 /* spawnve has four arguments: (mode, path, argv, env), where
5110 argv is a list or tuple of strings and env is a dictionary
5111 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005112
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 if (PyList_Check(argv)) {
5114 argc = PyList_Size(argv);
5115 getitem = PyList_GetItem;
5116 }
5117 else if (PyTuple_Check(argv)) {
5118 argc = PyTuple_Size(argv);
5119 getitem = PyTuple_GetItem;
5120 }
5121 else {
5122 PyErr_SetString(PyExc_TypeError,
5123 "spawnve() arg 2 must be a tuple or list");
5124 goto fail_0;
5125 }
5126 if (!PyMapping_Check(env)) {
5127 PyErr_SetString(PyExc_TypeError,
5128 "spawnve() arg 3 must be a mapping object");
5129 goto fail_0;
5130 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005131
Steve Dowercc16be82016-09-08 10:35:16 -07005132 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 if (argvlist == NULL) {
5134 PyErr_NoMemory();
5135 goto fail_0;
5136 }
5137 for (i = 0; i < argc; i++) {
5138 if (!fsconvert_strdup((*getitem)(argv, i),
5139 &argvlist[i]))
5140 {
5141 lastarg = i;
5142 goto fail_1;
5143 }
5144 }
5145 lastarg = argc;
5146 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005147
Victor Stinner8c62be82010-05-06 00:08:46 +00005148 envlist = parse_envlist(env, &envc);
5149 if (envlist == NULL)
5150 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005151
Victor Stinner8c62be82010-05-06 00:08:46 +00005152 if (mode == _OLD_P_OVERLAY)
5153 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005154
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07005156#ifdef HAVE_WSPAWNV
5157 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5158#else
5159 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5160#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005161 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005162
Victor Stinner8c62be82010-05-06 00:08:46 +00005163 if (spawnval == -1)
5164 (void) posix_error();
5165 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005166 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005167
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 while (--envc >= 0)
5169 PyMem_DEL(envlist[envc]);
5170 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005171 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005173 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005175}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005176
Guido van Rossuma1065681999-01-25 23:20:23 +00005177#endif /* HAVE_SPAWNV */
5178
5179
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005180#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005181/*[clinic input]
5182os.fork1
5183
5184Fork a child process with a single multiplexed (i.e., not bound) thread.
5185
5186Return 0 to child process and PID of child to parent process.
5187[clinic start generated code]*/
5188
Larry Hastings2f936352014-08-05 14:04:04 +10005189static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005190os_fork1_impl(PyObject *module)
5191/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005192{
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 pid_t pid;
5194 int result = 0;
5195 _PyImport_AcquireLock();
5196 pid = fork1();
5197 if (pid == 0) {
5198 /* child: this clobbers and resets the import lock. */
5199 PyOS_AfterFork();
5200 } else {
5201 /* parent: release the import lock. */
5202 result = _PyImport_ReleaseLock();
5203 }
5204 if (pid == -1)
5205 return posix_error();
5206 if (result < 0) {
5207 /* Don't clobber the OSError if the fork failed. */
5208 PyErr_SetString(PyExc_RuntimeError,
5209 "not holding the import lock");
5210 return NULL;
5211 }
5212 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005213}
Larry Hastings2f936352014-08-05 14:04:04 +10005214#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005215
5216
Guido van Rossumad0ee831995-03-01 10:34:45 +00005217#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005218/*[clinic input]
5219os.fork
5220
5221Fork a child process.
5222
5223Return 0 to child process and PID of child to parent process.
5224[clinic start generated code]*/
5225
Larry Hastings2f936352014-08-05 14:04:04 +10005226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005227os_fork_impl(PyObject *module)
5228/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005229{
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 pid_t pid;
5231 int result = 0;
5232 _PyImport_AcquireLock();
5233 pid = fork();
5234 if (pid == 0) {
5235 /* child: this clobbers and resets the import lock. */
5236 PyOS_AfterFork();
5237 } else {
5238 /* parent: release the import lock. */
5239 result = _PyImport_ReleaseLock();
5240 }
5241 if (pid == -1)
5242 return posix_error();
5243 if (result < 0) {
5244 /* Don't clobber the OSError if the fork failed. */
5245 PyErr_SetString(PyExc_RuntimeError,
5246 "not holding the import lock");
5247 return NULL;
5248 }
5249 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005250}
Larry Hastings2f936352014-08-05 14:04:04 +10005251#endif /* HAVE_FORK */
5252
Guido van Rossum85e3b011991-06-03 12:42:10 +00005253
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005254#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005255#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005256/*[clinic input]
5257os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005258
Larry Hastings2f936352014-08-05 14:04:04 +10005259 policy: int
5260
5261Get the maximum scheduling priority for policy.
5262[clinic start generated code]*/
5263
Larry Hastings2f936352014-08-05 14:04:04 +10005264static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005265os_sched_get_priority_max_impl(PyObject *module, int policy)
5266/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005267{
5268 int max;
5269
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005270 max = sched_get_priority_max(policy);
5271 if (max < 0)
5272 return posix_error();
5273 return PyLong_FromLong(max);
5274}
5275
Larry Hastings2f936352014-08-05 14:04:04 +10005276
5277/*[clinic input]
5278os.sched_get_priority_min
5279
5280 policy: int
5281
5282Get the minimum scheduling priority for policy.
5283[clinic start generated code]*/
5284
Larry Hastings2f936352014-08-05 14:04:04 +10005285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005286os_sched_get_priority_min_impl(PyObject *module, int policy)
5287/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005288{
5289 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005290 if (min < 0)
5291 return posix_error();
5292 return PyLong_FromLong(min);
5293}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005294#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5295
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005296
Larry Hastings2f936352014-08-05 14:04:04 +10005297#ifdef HAVE_SCHED_SETSCHEDULER
5298/*[clinic input]
5299os.sched_getscheduler
5300 pid: pid_t
5301 /
5302
5303Get the scheduling policy for the process identifiedy by pid.
5304
5305Passing 0 for pid returns the scheduling policy for the calling process.
5306[clinic start generated code]*/
5307
Larry Hastings2f936352014-08-05 14:04:04 +10005308static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005309os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5310/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005311{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005312 int policy;
5313
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005314 policy = sched_getscheduler(pid);
5315 if (policy < 0)
5316 return posix_error();
5317 return PyLong_FromLong(policy);
5318}
Larry Hastings2f936352014-08-05 14:04:04 +10005319#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005320
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005321
5322#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005323/*[clinic input]
5324class os.sched_param "PyObject *" "&SchedParamType"
5325
5326@classmethod
5327os.sched_param.__new__
5328
5329 sched_priority: object
5330 A scheduling parameter.
5331
5332Current has only one field: sched_priority");
5333[clinic start generated code]*/
5334
Larry Hastings2f936352014-08-05 14:04:04 +10005335static PyObject *
5336os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005337/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005338{
5339 PyObject *res;
5340
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005341 res = PyStructSequence_New(type);
5342 if (!res)
5343 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005344 Py_INCREF(sched_priority);
5345 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005346 return res;
5347}
5348
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005349
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005350PyDoc_VAR(os_sched_param__doc__);
5351
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005352static PyStructSequence_Field sched_param_fields[] = {
5353 {"sched_priority", "the scheduling priority"},
5354 {0}
5355};
5356
5357static PyStructSequence_Desc sched_param_desc = {
5358 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005359 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005360 sched_param_fields,
5361 1
5362};
5363
5364static int
5365convert_sched_param(PyObject *param, struct sched_param *res)
5366{
5367 long priority;
5368
5369 if (Py_TYPE(param) != &SchedParamType) {
5370 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5371 return 0;
5372 }
5373 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5374 if (priority == -1 && PyErr_Occurred())
5375 return 0;
5376 if (priority > INT_MAX || priority < INT_MIN) {
5377 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5378 return 0;
5379 }
5380 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5381 return 1;
5382}
Larry Hastings2f936352014-08-05 14:04:04 +10005383#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005384
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005385
5386#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005387/*[clinic input]
5388os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005389
Larry Hastings2f936352014-08-05 14:04:04 +10005390 pid: pid_t
5391 policy: int
5392 param: sched_param
5393 /
5394
5395Set the scheduling policy for the process identified by pid.
5396
5397If pid is 0, the calling process is changed.
5398param is an instance of sched_param.
5399[clinic start generated code]*/
5400
Larry Hastings2f936352014-08-05 14:04:04 +10005401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005402os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005403 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005404/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005405{
Jesus Cea9c822272011-09-10 01:40:52 +02005406 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005407 ** sched_setscheduler() returns 0 in Linux, but the previous
5408 ** scheduling policy under Solaris/Illumos, and others.
5409 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005410 */
Larry Hastings2f936352014-08-05 14:04:04 +10005411 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005412 return posix_error();
5413 Py_RETURN_NONE;
5414}
Larry Hastings2f936352014-08-05 14:04:04 +10005415#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005416
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005417
5418#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005419/*[clinic input]
5420os.sched_getparam
5421 pid: pid_t
5422 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005423
Larry Hastings2f936352014-08-05 14:04:04 +10005424Returns scheduling parameters for the process identified by pid.
5425
5426If pid is 0, returns parameters for the calling process.
5427Return value is an instance of sched_param.
5428[clinic start generated code]*/
5429
Larry Hastings2f936352014-08-05 14:04:04 +10005430static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005431os_sched_getparam_impl(PyObject *module, pid_t pid)
5432/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005433{
5434 struct sched_param param;
5435 PyObject *result;
5436 PyObject *priority;
5437
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005438 if (sched_getparam(pid, &param))
5439 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005440 result = PyStructSequence_New(&SchedParamType);
5441 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005442 return NULL;
5443 priority = PyLong_FromLong(param.sched_priority);
5444 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005445 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005446 return NULL;
5447 }
Larry Hastings2f936352014-08-05 14:04:04 +10005448 PyStructSequence_SET_ITEM(result, 0, priority);
5449 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005450}
5451
Larry Hastings2f936352014-08-05 14:04:04 +10005452
5453/*[clinic input]
5454os.sched_setparam
5455 pid: pid_t
5456 param: sched_param
5457 /
5458
5459Set scheduling parameters for the process identified by pid.
5460
5461If pid is 0, sets parameters for the calling process.
5462param should be an instance of sched_param.
5463[clinic start generated code]*/
5464
Larry Hastings2f936352014-08-05 14:04:04 +10005465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005466os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005467 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005468/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005469{
5470 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005471 return posix_error();
5472 Py_RETURN_NONE;
5473}
Larry Hastings2f936352014-08-05 14:04:04 +10005474#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005476
5477#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005478/*[clinic input]
5479os.sched_rr_get_interval -> double
5480 pid: pid_t
5481 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005482
Larry Hastings2f936352014-08-05 14:04:04 +10005483Return the round-robin quantum for the process identified by pid, in seconds.
5484
5485Value returned is a float.
5486[clinic start generated code]*/
5487
Larry Hastings2f936352014-08-05 14:04:04 +10005488static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005489os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5490/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005491{
5492 struct timespec interval;
5493 if (sched_rr_get_interval(pid, &interval)) {
5494 posix_error();
5495 return -1.0;
5496 }
5497 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5498}
5499#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005500
Larry Hastings2f936352014-08-05 14:04:04 +10005501
5502/*[clinic input]
5503os.sched_yield
5504
5505Voluntarily relinquish the CPU.
5506[clinic start generated code]*/
5507
Larry Hastings2f936352014-08-05 14:04:04 +10005508static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005509os_sched_yield_impl(PyObject *module)
5510/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005511{
5512 if (sched_yield())
5513 return posix_error();
5514 Py_RETURN_NONE;
5515}
5516
Benjamin Peterson2740af82011-08-02 17:41:34 -05005517#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005518/* The minimum number of CPUs allocated in a cpu_set_t */
5519static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005520
Larry Hastings2f936352014-08-05 14:04:04 +10005521/*[clinic input]
5522os.sched_setaffinity
5523 pid: pid_t
5524 mask : object
5525 /
5526
5527Set the CPU affinity of the process identified by pid to mask.
5528
5529mask should be an iterable of integers identifying CPUs.
5530[clinic start generated code]*/
5531
Larry Hastings2f936352014-08-05 14:04:04 +10005532static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005533os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5534/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005535{
Antoine Pitrou84869872012-08-04 16:16:35 +02005536 int ncpus;
5537 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005538 cpu_set_t *cpu_set = NULL;
5539 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005540
Larry Hastings2f936352014-08-05 14:04:04 +10005541 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005542 if (iterator == NULL)
5543 return NULL;
5544
5545 ncpus = NCPUS_START;
5546 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005547 cpu_set = CPU_ALLOC(ncpus);
5548 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005549 PyErr_NoMemory();
5550 goto error;
5551 }
Larry Hastings2f936352014-08-05 14:04:04 +10005552 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005553
5554 while ((item = PyIter_Next(iterator))) {
5555 long cpu;
5556 if (!PyLong_Check(item)) {
5557 PyErr_Format(PyExc_TypeError,
5558 "expected an iterator of ints, "
5559 "but iterator yielded %R",
5560 Py_TYPE(item));
5561 Py_DECREF(item);
5562 goto error;
5563 }
5564 cpu = PyLong_AsLong(item);
5565 Py_DECREF(item);
5566 if (cpu < 0) {
5567 if (!PyErr_Occurred())
5568 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5569 goto error;
5570 }
5571 if (cpu > INT_MAX - 1) {
5572 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5573 goto error;
5574 }
5575 if (cpu >= ncpus) {
5576 /* Grow CPU mask to fit the CPU number */
5577 int newncpus = ncpus;
5578 cpu_set_t *newmask;
5579 size_t newsetsize;
5580 while (newncpus <= cpu) {
5581 if (newncpus > INT_MAX / 2)
5582 newncpus = cpu + 1;
5583 else
5584 newncpus = newncpus * 2;
5585 }
5586 newmask = CPU_ALLOC(newncpus);
5587 if (newmask == NULL) {
5588 PyErr_NoMemory();
5589 goto error;
5590 }
5591 newsetsize = CPU_ALLOC_SIZE(newncpus);
5592 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005593 memcpy(newmask, cpu_set, setsize);
5594 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005595 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005596 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005597 ncpus = newncpus;
5598 }
Larry Hastings2f936352014-08-05 14:04:04 +10005599 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005600 }
5601 Py_CLEAR(iterator);
5602
Larry Hastings2f936352014-08-05 14:04:04 +10005603 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005604 posix_error();
5605 goto error;
5606 }
Larry Hastings2f936352014-08-05 14:04:04 +10005607 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005608 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005609
5610error:
Larry Hastings2f936352014-08-05 14:04:04 +10005611 if (cpu_set)
5612 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005613 Py_XDECREF(iterator);
5614 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615}
5616
Larry Hastings2f936352014-08-05 14:04:04 +10005617
5618/*[clinic input]
5619os.sched_getaffinity
5620 pid: pid_t
5621 /
5622
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005623Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005624
5625The affinity is returned as a set of CPU identifiers.
5626[clinic start generated code]*/
5627
Larry Hastings2f936352014-08-05 14:04:04 +10005628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005629os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005630/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005631{
Antoine Pitrou84869872012-08-04 16:16:35 +02005632 int cpu, ncpus, count;
5633 size_t setsize;
5634 cpu_set_t *mask = NULL;
5635 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005636
Antoine Pitrou84869872012-08-04 16:16:35 +02005637 ncpus = NCPUS_START;
5638 while (1) {
5639 setsize = CPU_ALLOC_SIZE(ncpus);
5640 mask = CPU_ALLOC(ncpus);
5641 if (mask == NULL)
5642 return PyErr_NoMemory();
5643 if (sched_getaffinity(pid, setsize, mask) == 0)
5644 break;
5645 CPU_FREE(mask);
5646 if (errno != EINVAL)
5647 return posix_error();
5648 if (ncpus > INT_MAX / 2) {
5649 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5650 "a large enough CPU set");
5651 return NULL;
5652 }
5653 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005654 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005655
5656 res = PySet_New(NULL);
5657 if (res == NULL)
5658 goto error;
5659 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5660 if (CPU_ISSET_S(cpu, setsize, mask)) {
5661 PyObject *cpu_num = PyLong_FromLong(cpu);
5662 --count;
5663 if (cpu_num == NULL)
5664 goto error;
5665 if (PySet_Add(res, cpu_num)) {
5666 Py_DECREF(cpu_num);
5667 goto error;
5668 }
5669 Py_DECREF(cpu_num);
5670 }
5671 }
5672 CPU_FREE(mask);
5673 return res;
5674
5675error:
5676 if (mask)
5677 CPU_FREE(mask);
5678 Py_XDECREF(res);
5679 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005680}
5681
Benjamin Peterson2740af82011-08-02 17:41:34 -05005682#endif /* HAVE_SCHED_SETAFFINITY */
5683
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005684#endif /* HAVE_SCHED_H */
5685
Larry Hastings2f936352014-08-05 14:04:04 +10005686
Neal Norwitzb59798b2003-03-21 01:43:31 +00005687/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005688/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5689#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005690#define DEV_PTY_FILE "/dev/ptc"
5691#define HAVE_DEV_PTMX
5692#else
5693#define DEV_PTY_FILE "/dev/ptmx"
5694#endif
5695
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005696#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005697#ifdef HAVE_PTY_H
5698#include <pty.h>
5699#else
5700#ifdef HAVE_LIBUTIL_H
5701#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005702#else
5703#ifdef HAVE_UTIL_H
5704#include <util.h>
5705#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005706#endif /* HAVE_LIBUTIL_H */
5707#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005708#ifdef HAVE_STROPTS_H
5709#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005710#endif
5711#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005712
Larry Hastings2f936352014-08-05 14:04:04 +10005713
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005714#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005715/*[clinic input]
5716os.openpty
5717
5718Open a pseudo-terminal.
5719
5720Return a tuple of (master_fd, slave_fd) containing open file descriptors
5721for both the master and slave ends.
5722[clinic start generated code]*/
5723
Larry Hastings2f936352014-08-05 14:04:04 +10005724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005725os_openpty_impl(PyObject *module)
5726/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005727{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005728 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005729#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005730 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005731#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005732#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005733 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005734#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005735 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005736#endif
5737#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005738
Thomas Wouters70c21a12000-07-14 14:28:33 +00005739#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005740 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005741 goto posix_error;
5742
5743 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5744 goto error;
5745 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5746 goto error;
5747
Neal Norwitzb59798b2003-03-21 01:43:31 +00005748#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5750 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005751 goto posix_error;
5752 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5753 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005754
Victor Stinnerdaf45552013-08-28 00:53:59 +02005755 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005756 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005757 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005758
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005759#else
Victor Stinner000de532013-11-25 23:19:58 +01005760 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005761 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005762 goto posix_error;
5763
Victor Stinner8c62be82010-05-06 00:08:46 +00005764 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005765
Victor Stinner8c62be82010-05-06 00:08:46 +00005766 /* change permission of slave */
5767 if (grantpt(master_fd) < 0) {
5768 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005769 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005770 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005771
Victor Stinner8c62be82010-05-06 00:08:46 +00005772 /* unlock slave */
5773 if (unlockpt(master_fd) < 0) {
5774 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005775 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005776 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005777
Victor Stinner8c62be82010-05-06 00:08:46 +00005778 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005779
Victor Stinner8c62be82010-05-06 00:08:46 +00005780 slave_name = ptsname(master_fd); /* get name of slave */
5781 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005782 goto posix_error;
5783
5784 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005785 if (slave_fd == -1)
5786 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005787
5788 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5789 goto posix_error;
5790
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005791#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005792 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5793 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005794#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005795 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005796#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005797#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005798#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005799
Victor Stinner8c62be82010-05-06 00:08:46 +00005800 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005801
Victor Stinnerdaf45552013-08-28 00:53:59 +02005802posix_error:
5803 posix_error();
5804error:
5805 if (master_fd != -1)
5806 close(master_fd);
5807 if (slave_fd != -1)
5808 close(slave_fd);
5809 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005810}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005811#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005812
Larry Hastings2f936352014-08-05 14:04:04 +10005813
Fred Drake8cef4cf2000-06-28 16:40:38 +00005814#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005815/*[clinic input]
5816os.forkpty
5817
5818Fork a new process with a new pseudo-terminal as controlling tty.
5819
5820Returns a tuple of (pid, master_fd).
5821Like fork(), return pid of 0 to the child process,
5822and pid of child to the parent process.
5823To both, return fd of newly opened pseudo-terminal.
5824[clinic start generated code]*/
5825
Larry Hastings2f936352014-08-05 14:04:04 +10005826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005827os_forkpty_impl(PyObject *module)
5828/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005829{
Victor Stinner8c62be82010-05-06 00:08:46 +00005830 int master_fd = -1, result = 0;
5831 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005832
Victor Stinner8c62be82010-05-06 00:08:46 +00005833 _PyImport_AcquireLock();
5834 pid = forkpty(&master_fd, NULL, NULL, NULL);
5835 if (pid == 0) {
5836 /* child: this clobbers and resets the import lock. */
5837 PyOS_AfterFork();
5838 } else {
5839 /* parent: release the import lock. */
5840 result = _PyImport_ReleaseLock();
5841 }
5842 if (pid == -1)
5843 return posix_error();
5844 if (result < 0) {
5845 /* Don't clobber the OSError if the fork failed. */
5846 PyErr_SetString(PyExc_RuntimeError,
5847 "not holding the import lock");
5848 return NULL;
5849 }
5850 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005851}
Larry Hastings2f936352014-08-05 14:04:04 +10005852#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005853
Ross Lagerwall7807c352011-03-17 20:20:30 +02005854
Guido van Rossumad0ee831995-03-01 10:34:45 +00005855#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005856/*[clinic input]
5857os.getegid
5858
5859Return the current process's effective group id.
5860[clinic start generated code]*/
5861
Larry Hastings2f936352014-08-05 14:04:04 +10005862static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005863os_getegid_impl(PyObject *module)
5864/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005865{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005866 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005867}
Larry Hastings2f936352014-08-05 14:04:04 +10005868#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005869
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005870
Guido van Rossumad0ee831995-03-01 10:34:45 +00005871#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005872/*[clinic input]
5873os.geteuid
5874
5875Return the current process's effective user id.
5876[clinic start generated code]*/
5877
Larry Hastings2f936352014-08-05 14:04:04 +10005878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005879os_geteuid_impl(PyObject *module)
5880/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005881{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005882 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005883}
Larry Hastings2f936352014-08-05 14:04:04 +10005884#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005885
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005886
Guido van Rossumad0ee831995-03-01 10:34:45 +00005887#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005888/*[clinic input]
5889os.getgid
5890
5891Return the current process's group id.
5892[clinic start generated code]*/
5893
Larry Hastings2f936352014-08-05 14:04:04 +10005894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005895os_getgid_impl(PyObject *module)
5896/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005897{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005898 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005899}
Larry Hastings2f936352014-08-05 14:04:04 +10005900#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005901
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005902
Larry Hastings2f936352014-08-05 14:04:04 +10005903/*[clinic input]
5904os.getpid
5905
5906Return the current process id.
5907[clinic start generated code]*/
5908
Larry Hastings2f936352014-08-05 14:04:04 +10005909static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005910os_getpid_impl(PyObject *module)
5911/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005912{
Victor Stinner8c62be82010-05-06 00:08:46 +00005913 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005914}
5915
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005916#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005917
5918/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005919PyDoc_STRVAR(posix_getgrouplist__doc__,
5920"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5921Returns a list of groups to which a user belongs.\n\n\
5922 user: username to lookup\n\
5923 group: base group id of the user");
5924
5925static PyObject *
5926posix_getgrouplist(PyObject *self, PyObject *args)
5927{
5928#ifdef NGROUPS_MAX
5929#define MAX_GROUPS NGROUPS_MAX
5930#else
5931 /* defined to be 16 on Solaris7, so this should be a small number */
5932#define MAX_GROUPS 64
5933#endif
5934
5935 const char *user;
5936 int i, ngroups;
5937 PyObject *list;
5938#ifdef __APPLE__
5939 int *groups, basegid;
5940#else
5941 gid_t *groups, basegid;
5942#endif
5943 ngroups = MAX_GROUPS;
5944
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005945#ifdef __APPLE__
5946 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005947 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005948#else
5949 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5950 _Py_Gid_Converter, &basegid))
5951 return NULL;
5952#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005953
5954#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005955 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005956#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005957 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005958#endif
5959 if (groups == NULL)
5960 return PyErr_NoMemory();
5961
5962 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5963 PyMem_Del(groups);
5964 return posix_error();
5965 }
5966
5967 list = PyList_New(ngroups);
5968 if (list == NULL) {
5969 PyMem_Del(groups);
5970 return NULL;
5971 }
5972
5973 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005974#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005975 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005976#else
5977 PyObject *o = _PyLong_FromGid(groups[i]);
5978#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005979 if (o == NULL) {
5980 Py_DECREF(list);
5981 PyMem_Del(groups);
5982 return NULL;
5983 }
5984 PyList_SET_ITEM(list, i, o);
5985 }
5986
5987 PyMem_Del(groups);
5988
5989 return list;
5990}
Larry Hastings2f936352014-08-05 14:04:04 +10005991#endif /* HAVE_GETGROUPLIST */
5992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005993
Fred Drakec9680921999-12-13 16:37:25 +00005994#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10005995/*[clinic input]
5996os.getgroups
5997
5998Return list of supplemental group IDs for the process.
5999[clinic start generated code]*/
6000
Larry Hastings2f936352014-08-05 14:04:04 +10006001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006002os_getgroups_impl(PyObject *module)
6003/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006004{
6005 PyObject *result = NULL;
6006
Fred Drakec9680921999-12-13 16:37:25 +00006007#ifdef NGROUPS_MAX
6008#define MAX_GROUPS NGROUPS_MAX
6009#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006010 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006011#define MAX_GROUPS 64
6012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006013 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006014
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006015 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006016 * This is a helper variable to store the intermediate result when
6017 * that happens.
6018 *
6019 * To keep the code readable the OSX behaviour is unconditional,
6020 * according to the POSIX spec this should be safe on all unix-y
6021 * systems.
6022 */
6023 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006024 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006025
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006026#ifdef __APPLE__
6027 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6028 * there are more groups than can fit in grouplist. Therefore, on OS X
6029 * always first call getgroups with length 0 to get the actual number
6030 * of groups.
6031 */
6032 n = getgroups(0, NULL);
6033 if (n < 0) {
6034 return posix_error();
6035 } else if (n <= MAX_GROUPS) {
6036 /* groups will fit in existing array */
6037 alt_grouplist = grouplist;
6038 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006039 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006040 if (alt_grouplist == NULL) {
6041 errno = EINVAL;
6042 return posix_error();
6043 }
6044 }
6045
6046 n = getgroups(n, alt_grouplist);
6047 if (n == -1) {
6048 if (alt_grouplist != grouplist) {
6049 PyMem_Free(alt_grouplist);
6050 }
6051 return posix_error();
6052 }
6053#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006055 if (n < 0) {
6056 if (errno == EINVAL) {
6057 n = getgroups(0, NULL);
6058 if (n == -1) {
6059 return posix_error();
6060 }
6061 if (n == 0) {
6062 /* Avoid malloc(0) */
6063 alt_grouplist = grouplist;
6064 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006065 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006066 if (alt_grouplist == NULL) {
6067 errno = EINVAL;
6068 return posix_error();
6069 }
6070 n = getgroups(n, alt_grouplist);
6071 if (n == -1) {
6072 PyMem_Free(alt_grouplist);
6073 return posix_error();
6074 }
6075 }
6076 } else {
6077 return posix_error();
6078 }
6079 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006080#endif
6081
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006082 result = PyList_New(n);
6083 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006084 int i;
6085 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006086 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006087 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006088 Py_DECREF(result);
6089 result = NULL;
6090 break;
Fred Drakec9680921999-12-13 16:37:25 +00006091 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006092 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006093 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006094 }
6095
6096 if (alt_grouplist != grouplist) {
6097 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006098 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006099
Fred Drakec9680921999-12-13 16:37:25 +00006100 return result;
6101}
Larry Hastings2f936352014-08-05 14:04:04 +10006102#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006103
Antoine Pitroub7572f02009-12-02 20:46:48 +00006104#ifdef HAVE_INITGROUPS
6105PyDoc_STRVAR(posix_initgroups__doc__,
6106"initgroups(username, gid) -> None\n\n\
6107Call the system initgroups() to initialize the group access list with all of\n\
6108the groups of which the specified username is a member, plus the specified\n\
6109group id.");
6110
Larry Hastings2f936352014-08-05 14:04:04 +10006111/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006112static PyObject *
6113posix_initgroups(PyObject *self, PyObject *args)
6114{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006115 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006116 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006117 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006118#ifdef __APPLE__
6119 int gid;
6120#else
6121 gid_t gid;
6122#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006123
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006124#ifdef __APPLE__
6125 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6126 PyUnicode_FSConverter, &oname,
6127 &gid))
6128#else
6129 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6130 PyUnicode_FSConverter, &oname,
6131 _Py_Gid_Converter, &gid))
6132#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006134 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006135
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006136 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006137 Py_DECREF(oname);
6138 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006140
Victor Stinner8c62be82010-05-06 00:08:46 +00006141 Py_INCREF(Py_None);
6142 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006143}
Larry Hastings2f936352014-08-05 14:04:04 +10006144#endif /* HAVE_INITGROUPS */
6145
Antoine Pitroub7572f02009-12-02 20:46:48 +00006146
Martin v. Löwis606edc12002-06-13 21:09:11 +00006147#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006148/*[clinic input]
6149os.getpgid
6150
6151 pid: pid_t
6152
6153Call the system call getpgid(), and return the result.
6154[clinic start generated code]*/
6155
Larry Hastings2f936352014-08-05 14:04:04 +10006156static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006157os_getpgid_impl(PyObject *module, pid_t pid)
6158/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006159{
6160 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006161 if (pgid < 0)
6162 return posix_error();
6163 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006164}
6165#endif /* HAVE_GETPGID */
6166
6167
Guido van Rossumb6775db1994-08-01 11:34:53 +00006168#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006169/*[clinic input]
6170os.getpgrp
6171
6172Return the current process group id.
6173[clinic start generated code]*/
6174
Larry Hastings2f936352014-08-05 14:04:04 +10006175static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006176os_getpgrp_impl(PyObject *module)
6177/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006178{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006179#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006180 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006181#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006182 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006183#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006184}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006185#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006187
Guido van Rossumb6775db1994-08-01 11:34:53 +00006188#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006189/*[clinic input]
6190os.setpgrp
6191
6192Make the current process the leader of its process group.
6193[clinic start generated code]*/
6194
Larry Hastings2f936352014-08-05 14:04:04 +10006195static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006196os_setpgrp_impl(PyObject *module)
6197/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006198{
Guido van Rossum64933891994-10-20 21:56:42 +00006199#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006200 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006201#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006202 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006203#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 return posix_error();
6205 Py_INCREF(Py_None);
6206 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006207}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006208#endif /* HAVE_SETPGRP */
6209
Guido van Rossumad0ee831995-03-01 10:34:45 +00006210#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006211
6212#ifdef MS_WINDOWS
6213#include <tlhelp32.h>
6214
6215static PyObject*
6216win32_getppid()
6217{
6218 HANDLE snapshot;
6219 pid_t mypid;
6220 PyObject* result = NULL;
6221 BOOL have_record;
6222 PROCESSENTRY32 pe;
6223
6224 mypid = getpid(); /* This function never fails */
6225
6226 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6227 if (snapshot == INVALID_HANDLE_VALUE)
6228 return PyErr_SetFromWindowsErr(GetLastError());
6229
6230 pe.dwSize = sizeof(pe);
6231 have_record = Process32First(snapshot, &pe);
6232 while (have_record) {
6233 if (mypid == (pid_t)pe.th32ProcessID) {
6234 /* We could cache the ulong value in a static variable. */
6235 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6236 break;
6237 }
6238
6239 have_record = Process32Next(snapshot, &pe);
6240 }
6241
6242 /* If our loop exits and our pid was not found (result will be NULL)
6243 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6244 * error anyway, so let's raise it. */
6245 if (!result)
6246 result = PyErr_SetFromWindowsErr(GetLastError());
6247
6248 CloseHandle(snapshot);
6249
6250 return result;
6251}
6252#endif /*MS_WINDOWS*/
6253
Larry Hastings2f936352014-08-05 14:04:04 +10006254
6255/*[clinic input]
6256os.getppid
6257
6258Return the parent's process id.
6259
6260If the parent process has already exited, Windows machines will still
6261return its id; others systems will return the id of the 'init' process (1).
6262[clinic start generated code]*/
6263
Larry Hastings2f936352014-08-05 14:04:04 +10006264static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006265os_getppid_impl(PyObject *module)
6266/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006267{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006268#ifdef MS_WINDOWS
6269 return win32_getppid();
6270#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006271 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006272#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006273}
6274#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006275
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006276
Fred Drake12c6e2d1999-12-14 21:25:03 +00006277#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006278/*[clinic input]
6279os.getlogin
6280
6281Return the actual login name.
6282[clinic start generated code]*/
6283
Larry Hastings2f936352014-08-05 14:04:04 +10006284static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006285os_getlogin_impl(PyObject *module)
6286/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006287{
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006289#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006290 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006291 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006292
6293 if (GetUserNameW(user_name, &num_chars)) {
6294 /* num_chars is the number of unicode chars plus null terminator */
6295 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006296 }
6297 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006298 result = PyErr_SetFromWindowsErr(GetLastError());
6299#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 char *name;
6301 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006302
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 errno = 0;
6304 name = getlogin();
6305 if (name == NULL) {
6306 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006307 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006308 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006309 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 }
6311 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006312 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006314#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006315 return result;
6316}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006317#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006318
Larry Hastings2f936352014-08-05 14:04:04 +10006319
Guido van Rossumad0ee831995-03-01 10:34:45 +00006320#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006321/*[clinic input]
6322os.getuid
6323
6324Return the current process's user id.
6325[clinic start generated code]*/
6326
Larry Hastings2f936352014-08-05 14:04:04 +10006327static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006328os_getuid_impl(PyObject *module)
6329/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006330{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006331 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006332}
Larry Hastings2f936352014-08-05 14:04:04 +10006333#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006334
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006335
Brian Curtineb24d742010-04-12 17:16:38 +00006336#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006337#define HAVE_KILL
6338#endif /* MS_WINDOWS */
6339
6340#ifdef HAVE_KILL
6341/*[clinic input]
6342os.kill
6343
6344 pid: pid_t
6345 signal: Py_ssize_t
6346 /
6347
6348Kill a process with a signal.
6349[clinic start generated code]*/
6350
Larry Hastings2f936352014-08-05 14:04:04 +10006351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006352os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6353/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006354#ifndef MS_WINDOWS
6355{
6356 if (kill(pid, (int)signal) == -1)
6357 return posix_error();
6358 Py_RETURN_NONE;
6359}
6360#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006361{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006362 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006363 DWORD sig = (DWORD)signal;
6364 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006366
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 /* Console processes which share a common console can be sent CTRL+C or
6368 CTRL+BREAK events, provided they handle said events. */
6369 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006370 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006371 err = GetLastError();
6372 PyErr_SetFromWindowsErr(err);
6373 }
6374 else
6375 Py_RETURN_NONE;
6376 }
Brian Curtineb24d742010-04-12 17:16:38 +00006377
Victor Stinner8c62be82010-05-06 00:08:46 +00006378 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6379 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006380 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006381 if (handle == NULL) {
6382 err = GetLastError();
6383 return PyErr_SetFromWindowsErr(err);
6384 }
Brian Curtineb24d742010-04-12 17:16:38 +00006385
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 if (TerminateProcess(handle, sig) == 0) {
6387 err = GetLastError();
6388 result = PyErr_SetFromWindowsErr(err);
6389 } else {
6390 Py_INCREF(Py_None);
6391 result = Py_None;
6392 }
Brian Curtineb24d742010-04-12 17:16:38 +00006393
Victor Stinner8c62be82010-05-06 00:08:46 +00006394 CloseHandle(handle);
6395 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006396}
Larry Hastings2f936352014-08-05 14:04:04 +10006397#endif /* !MS_WINDOWS */
6398#endif /* HAVE_KILL */
6399
6400
6401#ifdef HAVE_KILLPG
6402/*[clinic input]
6403os.killpg
6404
6405 pgid: pid_t
6406 signal: int
6407 /
6408
6409Kill a process group with a signal.
6410[clinic start generated code]*/
6411
Larry Hastings2f936352014-08-05 14:04:04 +10006412static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006413os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6414/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006415{
6416 /* XXX some man pages make the `pgid` parameter an int, others
6417 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6418 take the same type. Moreover, pid_t is always at least as wide as
6419 int (else compilation of this module fails), which is safe. */
6420 if (killpg(pgid, signal) == -1)
6421 return posix_error();
6422 Py_RETURN_NONE;
6423}
6424#endif /* HAVE_KILLPG */
6425
Brian Curtineb24d742010-04-12 17:16:38 +00006426
Guido van Rossumc0125471996-06-28 18:55:32 +00006427#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006428#ifdef HAVE_SYS_LOCK_H
6429#include <sys/lock.h>
6430#endif
6431
Larry Hastings2f936352014-08-05 14:04:04 +10006432/*[clinic input]
6433os.plock
6434 op: int
6435 /
6436
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006437Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006438[clinic start generated code]*/
6439
Larry Hastings2f936352014-08-05 14:04:04 +10006440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006441os_plock_impl(PyObject *module, int op)
6442/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006443{
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 if (plock(op) == -1)
6445 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006446 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006447}
Larry Hastings2f936352014-08-05 14:04:04 +10006448#endif /* HAVE_PLOCK */
6449
Guido van Rossumc0125471996-06-28 18:55:32 +00006450
Guido van Rossumb6775db1994-08-01 11:34:53 +00006451#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006452/*[clinic input]
6453os.setuid
6454
6455 uid: uid_t
6456 /
6457
6458Set the current process's user id.
6459[clinic start generated code]*/
6460
Larry Hastings2f936352014-08-05 14:04:04 +10006461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006462os_setuid_impl(PyObject *module, uid_t uid)
6463/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006464{
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 if (setuid(uid) < 0)
6466 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006467 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006468}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006469#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006472#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006473/*[clinic input]
6474os.seteuid
6475
6476 euid: uid_t
6477 /
6478
6479Set the current process's effective user id.
6480[clinic start generated code]*/
6481
Larry Hastings2f936352014-08-05 14:04:04 +10006482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006483os_seteuid_impl(PyObject *module, uid_t euid)
6484/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006485{
6486 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006488 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006489}
6490#endif /* HAVE_SETEUID */
6491
Larry Hastings2f936352014-08-05 14:04:04 +10006492
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006493#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006494/*[clinic input]
6495os.setegid
6496
6497 egid: gid_t
6498 /
6499
6500Set the current process's effective group id.
6501[clinic start generated code]*/
6502
Larry Hastings2f936352014-08-05 14:04:04 +10006503static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006504os_setegid_impl(PyObject *module, gid_t egid)
6505/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006506{
6507 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006509 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006510}
6511#endif /* HAVE_SETEGID */
6512
Larry Hastings2f936352014-08-05 14:04:04 +10006513
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006514#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006515/*[clinic input]
6516os.setreuid
6517
6518 ruid: uid_t
6519 euid: uid_t
6520 /
6521
6522Set the current process's real and effective user ids.
6523[clinic start generated code]*/
6524
Larry Hastings2f936352014-08-05 14:04:04 +10006525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006526os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6527/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006528{
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 if (setreuid(ruid, euid) < 0) {
6530 return posix_error();
6531 } else {
6532 Py_INCREF(Py_None);
6533 return Py_None;
6534 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006535}
6536#endif /* HAVE_SETREUID */
6537
Larry Hastings2f936352014-08-05 14:04:04 +10006538
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006539#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006540/*[clinic input]
6541os.setregid
6542
6543 rgid: gid_t
6544 egid: gid_t
6545 /
6546
6547Set the current process's real and effective group ids.
6548[clinic start generated code]*/
6549
Larry Hastings2f936352014-08-05 14:04:04 +10006550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006551os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6552/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006553{
6554 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006555 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006556 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006557}
6558#endif /* HAVE_SETREGID */
6559
Larry Hastings2f936352014-08-05 14:04:04 +10006560
Guido van Rossumb6775db1994-08-01 11:34:53 +00006561#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006562/*[clinic input]
6563os.setgid
6564 gid: gid_t
6565 /
6566
6567Set the current process's group id.
6568[clinic start generated code]*/
6569
Larry Hastings2f936352014-08-05 14:04:04 +10006570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006571os_setgid_impl(PyObject *module, gid_t gid)
6572/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006573{
Victor Stinner8c62be82010-05-06 00:08:46 +00006574 if (setgid(gid) < 0)
6575 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006576 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006577}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006578#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006579
Larry Hastings2f936352014-08-05 14:04:04 +10006580
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006581#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006582/*[clinic input]
6583os.setgroups
6584
6585 groups: object
6586 /
6587
6588Set the groups of the current process to list.
6589[clinic start generated code]*/
6590
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006591static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006592os_setgroups(PyObject *module, PyObject *groups)
6593/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006594{
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 int i, len;
6596 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006597
Victor Stinner8c62be82010-05-06 00:08:46 +00006598 if (!PySequence_Check(groups)) {
6599 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6600 return NULL;
6601 }
6602 len = PySequence_Size(groups);
6603 if (len > MAX_GROUPS) {
6604 PyErr_SetString(PyExc_ValueError, "too many groups");
6605 return NULL;
6606 }
6607 for(i = 0; i < len; i++) {
6608 PyObject *elem;
6609 elem = PySequence_GetItem(groups, i);
6610 if (!elem)
6611 return NULL;
6612 if (!PyLong_Check(elem)) {
6613 PyErr_SetString(PyExc_TypeError,
6614 "groups must be integers");
6615 Py_DECREF(elem);
6616 return NULL;
6617 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006618 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006619 Py_DECREF(elem);
6620 return NULL;
6621 }
6622 }
6623 Py_DECREF(elem);
6624 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006625
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 if (setgroups(len, grouplist) < 0)
6627 return posix_error();
6628 Py_INCREF(Py_None);
6629 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006630}
6631#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006632
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006633#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6634static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006635wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006636{
Victor Stinner8c62be82010-05-06 00:08:46 +00006637 PyObject *result;
6638 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006639 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006640
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 if (pid == -1)
6642 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006643
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 if (struct_rusage == NULL) {
6645 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6646 if (m == NULL)
6647 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006648 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 Py_DECREF(m);
6650 if (struct_rusage == NULL)
6651 return NULL;
6652 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006653
Victor Stinner8c62be82010-05-06 00:08:46 +00006654 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6655 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6656 if (!result)
6657 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006658
6659#ifndef doubletime
6660#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6661#endif
6662
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006664 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006666 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006667#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006668 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6669 SET_INT(result, 2, ru->ru_maxrss);
6670 SET_INT(result, 3, ru->ru_ixrss);
6671 SET_INT(result, 4, ru->ru_idrss);
6672 SET_INT(result, 5, ru->ru_isrss);
6673 SET_INT(result, 6, ru->ru_minflt);
6674 SET_INT(result, 7, ru->ru_majflt);
6675 SET_INT(result, 8, ru->ru_nswap);
6676 SET_INT(result, 9, ru->ru_inblock);
6677 SET_INT(result, 10, ru->ru_oublock);
6678 SET_INT(result, 11, ru->ru_msgsnd);
6679 SET_INT(result, 12, ru->ru_msgrcv);
6680 SET_INT(result, 13, ru->ru_nsignals);
6681 SET_INT(result, 14, ru->ru_nvcsw);
6682 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006683#undef SET_INT
6684
Victor Stinner8c62be82010-05-06 00:08:46 +00006685 if (PyErr_Occurred()) {
6686 Py_DECREF(result);
6687 return NULL;
6688 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006689
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006691}
6692#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6693
Larry Hastings2f936352014-08-05 14:04:04 +10006694
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006695#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006696/*[clinic input]
6697os.wait3
6698
6699 options: int
6700Wait for completion of a child process.
6701
6702Returns a tuple of information about the child process:
6703 (pid, status, rusage)
6704[clinic start generated code]*/
6705
Larry Hastings2f936352014-08-05 14:04:04 +10006706static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006707os_wait3_impl(PyObject *module, int options)
6708/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006709{
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006712 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 WAIT_TYPE status;
6714 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006715
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006716 do {
6717 Py_BEGIN_ALLOW_THREADS
6718 pid = wait3(&status, options, &ru);
6719 Py_END_ALLOW_THREADS
6720 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6721 if (pid < 0)
6722 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006723
Victor Stinner4195b5c2012-02-08 23:03:19 +01006724 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006725}
6726#endif /* HAVE_WAIT3 */
6727
Larry Hastings2f936352014-08-05 14:04:04 +10006728
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006729#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006730/*[clinic input]
6731
6732os.wait4
6733
6734 pid: pid_t
6735 options: int
6736
6737Wait for completion of a specific child process.
6738
6739Returns a tuple of information about the child process:
6740 (pid, status, rusage)
6741[clinic start generated code]*/
6742
Larry Hastings2f936352014-08-05 14:04:04 +10006743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006744os_wait4_impl(PyObject *module, pid_t pid, int options)
6745/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006746{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006747 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006749 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 WAIT_TYPE status;
6751 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006752
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006753 do {
6754 Py_BEGIN_ALLOW_THREADS
6755 res = wait4(pid, &status, options, &ru);
6756 Py_END_ALLOW_THREADS
6757 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6758 if (res < 0)
6759 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006760
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006761 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006762}
6763#endif /* HAVE_WAIT4 */
6764
Larry Hastings2f936352014-08-05 14:04:04 +10006765
Ross Lagerwall7807c352011-03-17 20:20:30 +02006766#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006767/*[clinic input]
6768os.waitid
6769
6770 idtype: idtype_t
6771 Must be one of be P_PID, P_PGID or P_ALL.
6772 id: id_t
6773 The id to wait on.
6774 options: int
6775 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6776 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6777 /
6778
6779Returns the result of waiting for a process or processes.
6780
6781Returns either waitid_result or None if WNOHANG is specified and there are
6782no children in a waitable state.
6783[clinic start generated code]*/
6784
Larry Hastings2f936352014-08-05 14:04:04 +10006785static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006786os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6787/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006788{
6789 PyObject *result;
6790 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006791 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006792 siginfo_t si;
6793 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006794
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006795 do {
6796 Py_BEGIN_ALLOW_THREADS
6797 res = waitid(idtype, id, &si, options);
6798 Py_END_ALLOW_THREADS
6799 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6800 if (res < 0)
6801 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006802
6803 if (si.si_pid == 0)
6804 Py_RETURN_NONE;
6805
6806 result = PyStructSequence_New(&WaitidResultType);
6807 if (!result)
6808 return NULL;
6809
6810 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006811 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006812 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6813 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6814 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6815 if (PyErr_Occurred()) {
6816 Py_DECREF(result);
6817 return NULL;
6818 }
6819
6820 return result;
6821}
Larry Hastings2f936352014-08-05 14:04:04 +10006822#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006823
Larry Hastings2f936352014-08-05 14:04:04 +10006824
6825#if defined(HAVE_WAITPID)
6826/*[clinic input]
6827os.waitpid
6828 pid: pid_t
6829 options: int
6830 /
6831
6832Wait for completion of a given child process.
6833
6834Returns a tuple of information regarding the child process:
6835 (pid, status)
6836
6837The options argument is ignored on Windows.
6838[clinic start generated code]*/
6839
Larry Hastings2f936352014-08-05 14:04:04 +10006840static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006841os_waitpid_impl(PyObject *module, pid_t pid, int options)
6842/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006843{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006844 pid_t res;
6845 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 WAIT_TYPE status;
6847 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006848
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006849 do {
6850 Py_BEGIN_ALLOW_THREADS
6851 res = waitpid(pid, &status, options);
6852 Py_END_ALLOW_THREADS
6853 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6854 if (res < 0)
6855 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006856
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006857 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006858}
Tim Petersab034fa2002-02-01 11:27:43 +00006859#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006860/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006861/*[clinic input]
6862os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006863 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006864 options: int
6865 /
6866
6867Wait for completion of a given process.
6868
6869Returns a tuple of information regarding the process:
6870 (pid, status << 8)
6871
6872The options argument is ignored on Windows.
6873[clinic start generated code]*/
6874
Larry Hastings2f936352014-08-05 14:04:04 +10006875static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006876os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006877/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006878{
6879 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006880 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006881 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006882
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006883 do {
6884 Py_BEGIN_ALLOW_THREADS
6885 res = _cwait(&status, pid, options);
6886 Py_END_ALLOW_THREADS
6887 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006888 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006889 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006890
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006892 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006893}
Larry Hastings2f936352014-08-05 14:04:04 +10006894#endif
6895
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006896
Guido van Rossumad0ee831995-03-01 10:34:45 +00006897#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006898/*[clinic input]
6899os.wait
6900
6901Wait for completion of a child process.
6902
6903Returns a tuple of information about the child process:
6904 (pid, status)
6905[clinic start generated code]*/
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006908os_wait_impl(PyObject *module)
6909/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006910{
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 WAIT_TYPE status;
6914 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006915
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006916 do {
6917 Py_BEGIN_ALLOW_THREADS
6918 pid = wait(&status);
6919 Py_END_ALLOW_THREADS
6920 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6921 if (pid < 0)
6922 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006923
Victor Stinner8c62be82010-05-06 00:08:46 +00006924 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006925}
Larry Hastings2f936352014-08-05 14:04:04 +10006926#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006927
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006928
Larry Hastings9cf065c2012-06-22 16:30:09 -07006929#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6930PyDoc_STRVAR(readlink__doc__,
6931"readlink(path, *, dir_fd=None) -> path\n\n\
6932Return a string representing the path to which the symbolic link points.\n\
6933\n\
6934If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6935 and path should be relative; path will then be relative to that directory.\n\
6936dir_fd may not be implemented on your platform.\n\
6937 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006938#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006939
Guido van Rossumb6775db1994-08-01 11:34:53 +00006940#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006941
Larry Hastings2f936352014-08-05 14:04:04 +10006942/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006943static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006944posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006945{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006946 path_t path;
6947 int dir_fd = DEFAULT_DIR_FD;
6948 char buffer[MAXPATHLEN];
6949 ssize_t length;
6950 PyObject *return_value = NULL;
6951 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006952
Larry Hastings9cf065c2012-06-22 16:30:09 -07006953 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006954 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006955 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6956 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10006957 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00006958 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006959
Victor Stinner8c62be82010-05-06 00:08:46 +00006960 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006961#ifdef HAVE_READLINKAT
6962 if (dir_fd != DEFAULT_DIR_FD)
6963 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006964 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006965#endif
6966 length = readlink(path.narrow, buffer, sizeof(buffer));
6967 Py_END_ALLOW_THREADS
6968
6969 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006970 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006971 goto exit;
6972 }
6973
6974 if (PyUnicode_Check(path.object))
6975 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6976 else
6977 return_value = PyBytes_FromStringAndSize(buffer, length);
6978exit:
6979 path_cleanup(&path);
6980 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006981}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006982
Guido van Rossumb6775db1994-08-01 11:34:53 +00006983#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006984
Larry Hastings2f936352014-08-05 14:04:04 +10006985#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6986
6987static PyObject *
6988win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
6989{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006990 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10006991 DWORD n_bytes_returned;
6992 DWORD io_result;
6993 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006994 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10006995 HANDLE reparse_point_handle;
6996
Martin Panter70214ad2016-08-04 02:38:59 +00006997 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6998 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006999 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007000
7001 static char *keywords[] = {"path", "dir_fd", NULL};
7002
7003 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7004 &po,
7005 dir_fd_unavailable, &dir_fd
7006 ))
7007 return NULL;
7008
7009 path = PyUnicode_AsUnicode(po);
7010 if (path == NULL)
7011 return NULL;
7012
7013 /* First get a handle to the reparse point */
7014 Py_BEGIN_ALLOW_THREADS
7015 reparse_point_handle = CreateFileW(
7016 path,
7017 0,
7018 0,
7019 0,
7020 OPEN_EXISTING,
7021 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7022 0);
7023 Py_END_ALLOW_THREADS
7024
7025 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7026 return win32_error_object("readlink", po);
7027
7028 Py_BEGIN_ALLOW_THREADS
7029 /* New call DeviceIoControl to read the reparse point */
7030 io_result = DeviceIoControl(
7031 reparse_point_handle,
7032 FSCTL_GET_REPARSE_POINT,
7033 0, 0, /* in buffer */
7034 target_buffer, sizeof(target_buffer),
7035 &n_bytes_returned,
7036 0 /* we're not using OVERLAPPED_IO */
7037 );
7038 CloseHandle(reparse_point_handle);
7039 Py_END_ALLOW_THREADS
7040
7041 if (io_result==0)
7042 return win32_error_object("readlink", po);
7043
7044 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7045 {
7046 PyErr_SetString(PyExc_ValueError,
7047 "not a symbolic link");
7048 return NULL;
7049 }
7050 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7051 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7052
7053 result = PyUnicode_FromWideChar(print_name,
7054 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7055 return result;
7056}
7057
7058#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7059
7060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Larry Hastings9cf065c2012-06-22 16:30:09 -07007062#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063
7064#if defined(MS_WINDOWS)
7065
7066/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007067static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007068
Larry Hastings9cf065c2012-06-22 16:30:09 -07007069static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007070check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007071{
7072 HINSTANCE hKernel32;
7073 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007074 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007075 return 1;
7076 hKernel32 = GetModuleHandleW(L"KERNEL32");
7077 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7078 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007079 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007080}
7081
Victor Stinner31b3b922013-06-05 01:49:17 +02007082/* Remove the last portion of the path */
7083static void
7084_dirnameW(WCHAR *path)
7085{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007086 WCHAR *ptr;
7087
7088 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007089 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007090 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007091 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007092 }
7093 *ptr = 0;
7094}
7095
Victor Stinner31b3b922013-06-05 01:49:17 +02007096/* Is this path absolute? */
7097static int
7098_is_absW(const WCHAR *path)
7099{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007100 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7101
7102}
7103
Victor Stinner31b3b922013-06-05 01:49:17 +02007104/* join root and rest with a backslash */
7105static void
7106_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7107{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007108 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007109
Victor Stinner31b3b922013-06-05 01:49:17 +02007110 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007111 wcscpy(dest_path, rest);
7112 return;
7113 }
7114
7115 root_len = wcslen(root);
7116
7117 wcscpy(dest_path, root);
7118 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007119 dest_path[root_len] = L'\\';
7120 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007121 }
7122 wcscpy(dest_path+root_len, rest);
7123}
7124
Victor Stinner31b3b922013-06-05 01:49:17 +02007125/* Return True if the path at src relative to dest is a directory */
7126static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007127_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007128{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007129 WIN32_FILE_ATTRIBUTE_DATA src_info;
7130 WCHAR dest_parent[MAX_PATH];
7131 WCHAR src_resolved[MAX_PATH] = L"";
7132
7133 /* dest_parent = os.path.dirname(dest) */
7134 wcscpy(dest_parent, dest);
7135 _dirnameW(dest_parent);
7136 /* src_resolved = os.path.join(dest_parent, src) */
7137 _joinW(src_resolved, dest_parent, src);
7138 return (
7139 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7140 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7141 );
7142}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007144
Larry Hastings2f936352014-08-05 14:04:04 +10007145
7146/*[clinic input]
7147os.symlink
7148 src: path_t
7149 dst: path_t
7150 target_is_directory: bool = False
7151 *
7152 dir_fd: dir_fd(requires='symlinkat')=None
7153
7154# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7155
7156Create a symbolic link pointing to src named dst.
7157
7158target_is_directory is required on Windows if the target is to be
7159 interpreted as a directory. (On Windows, symlink requires
7160 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7161 target_is_directory is ignored on non-Windows platforms.
7162
7163If dir_fd is not None, it should be a file descriptor open to a directory,
7164 and path should be relative; path will then be relative to that directory.
7165dir_fd may not be implemented on your platform.
7166 If it is unavailable, using it will raise a NotImplementedError.
7167
7168[clinic start generated code]*/
7169
Larry Hastings2f936352014-08-05 14:04:04 +10007170static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007171os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007172 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007173/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007174{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007175#ifdef MS_WINDOWS
7176 DWORD result;
7177#else
7178 int result;
7179#endif
7180
Larry Hastings9cf065c2012-06-22 16:30:09 -07007181#ifdef MS_WINDOWS
7182 if (!check_CreateSymbolicLink()) {
7183 PyErr_SetString(PyExc_NotImplementedError,
7184 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007185 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007186 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007187 if (!win32_can_symlink) {
7188 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007189 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007190 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007191#endif
7192
Larry Hastings2f936352014-08-05 14:04:04 +10007193 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007194 PyErr_SetString(PyExc_ValueError,
7195 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007196 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197 }
7198
7199#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007200
Larry Hastings9cf065c2012-06-22 16:30:09 -07007201 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007202 /* if src is a directory, ensure target_is_directory==1 */
7203 target_is_directory |= _check_dirW(src->wide, dst->wide);
7204 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7205 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007206 Py_END_ALLOW_THREADS
7207
Larry Hastings2f936352014-08-05 14:04:04 +10007208 if (!result)
7209 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007210
7211#else
7212
7213 Py_BEGIN_ALLOW_THREADS
7214#if HAVE_SYMLINKAT
7215 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007216 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007217 else
7218#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007219 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007220 Py_END_ALLOW_THREADS
7221
Larry Hastings2f936352014-08-05 14:04:04 +10007222 if (result)
7223 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007224#endif
7225
Larry Hastings2f936352014-08-05 14:04:04 +10007226 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007227}
7228#endif /* HAVE_SYMLINK */
7229
Larry Hastings9cf065c2012-06-22 16:30:09 -07007230
Brian Curtind40e6f72010-07-08 21:39:08 +00007231
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007232
Larry Hastings605a62d2012-06-24 04:33:36 -07007233static PyStructSequence_Field times_result_fields[] = {
7234 {"user", "user time"},
7235 {"system", "system time"},
7236 {"children_user", "user time of children"},
7237 {"children_system", "system time of children"},
7238 {"elapsed", "elapsed time since an arbitrary point in the past"},
7239 {NULL}
7240};
7241
7242PyDoc_STRVAR(times_result__doc__,
7243"times_result: Result from os.times().\n\n\
7244This object may be accessed either as a tuple of\n\
7245 (user, system, children_user, children_system, elapsed),\n\
7246or via the attributes user, system, children_user, children_system,\n\
7247and elapsed.\n\
7248\n\
7249See os.times for more information.");
7250
7251static PyStructSequence_Desc times_result_desc = {
7252 "times_result", /* name */
7253 times_result__doc__, /* doc */
7254 times_result_fields,
7255 5
7256};
7257
7258static PyTypeObject TimesResultType;
7259
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007260#ifdef MS_WINDOWS
7261#define HAVE_TIMES /* mandatory, for the method table */
7262#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007263
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007264#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007265
7266static PyObject *
7267build_times_result(double user, double system,
7268 double children_user, double children_system,
7269 double elapsed)
7270{
7271 PyObject *value = PyStructSequence_New(&TimesResultType);
7272 if (value == NULL)
7273 return NULL;
7274
7275#define SET(i, field) \
7276 { \
7277 PyObject *o = PyFloat_FromDouble(field); \
7278 if (!o) { \
7279 Py_DECREF(value); \
7280 return NULL; \
7281 } \
7282 PyStructSequence_SET_ITEM(value, i, o); \
7283 } \
7284
7285 SET(0, user);
7286 SET(1, system);
7287 SET(2, children_user);
7288 SET(3, children_system);
7289 SET(4, elapsed);
7290
7291#undef SET
7292
7293 return value;
7294}
7295
Larry Hastings605a62d2012-06-24 04:33:36 -07007296
Larry Hastings2f936352014-08-05 14:04:04 +10007297#ifndef MS_WINDOWS
7298#define NEED_TICKS_PER_SECOND
7299static long ticks_per_second = -1;
7300#endif /* MS_WINDOWS */
7301
7302/*[clinic input]
7303os.times
7304
7305Return a collection containing process timing information.
7306
7307The object returned behaves like a named tuple with these fields:
7308 (utime, stime, cutime, cstime, elapsed_time)
7309All fields are floating point numbers.
7310[clinic start generated code]*/
7311
Larry Hastings2f936352014-08-05 14:04:04 +10007312static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007313os_times_impl(PyObject *module)
7314/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007315#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007316{
Victor Stinner8c62be82010-05-06 00:08:46 +00007317 FILETIME create, exit, kernel, user;
7318 HANDLE hProc;
7319 hProc = GetCurrentProcess();
7320 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7321 /* The fields of a FILETIME structure are the hi and lo part
7322 of a 64-bit value expressed in 100 nanosecond units.
7323 1e7 is one second in such units; 1e-7 the inverse.
7324 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7325 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007326 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007327 (double)(user.dwHighDateTime*429.4967296 +
7328 user.dwLowDateTime*1e-7),
7329 (double)(kernel.dwHighDateTime*429.4967296 +
7330 kernel.dwLowDateTime*1e-7),
7331 (double)0,
7332 (double)0,
7333 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007334}
Larry Hastings2f936352014-08-05 14:04:04 +10007335#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007336{
Larry Hastings2f936352014-08-05 14:04:04 +10007337
7338
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007339 struct tms t;
7340 clock_t c;
7341 errno = 0;
7342 c = times(&t);
7343 if (c == (clock_t) -1)
7344 return posix_error();
7345 return build_times_result(
7346 (double)t.tms_utime / ticks_per_second,
7347 (double)t.tms_stime / ticks_per_second,
7348 (double)t.tms_cutime / ticks_per_second,
7349 (double)t.tms_cstime / ticks_per_second,
7350 (double)c / ticks_per_second);
7351}
Larry Hastings2f936352014-08-05 14:04:04 +10007352#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007353#endif /* HAVE_TIMES */
7354
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007355
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007356#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007357/*[clinic input]
7358os.getsid
7359
7360 pid: pid_t
7361 /
7362
7363Call the system call getsid(pid) and return the result.
7364[clinic start generated code]*/
7365
Larry Hastings2f936352014-08-05 14:04:04 +10007366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007367os_getsid_impl(PyObject *module, pid_t pid)
7368/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007369{
Victor Stinner8c62be82010-05-06 00:08:46 +00007370 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007371 sid = getsid(pid);
7372 if (sid < 0)
7373 return posix_error();
7374 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007375}
7376#endif /* HAVE_GETSID */
7377
7378
Guido van Rossumb6775db1994-08-01 11:34:53 +00007379#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007380/*[clinic input]
7381os.setsid
7382
7383Call the system call setsid().
7384[clinic start generated code]*/
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007387os_setsid_impl(PyObject *module)
7388/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007389{
Victor Stinner8c62be82010-05-06 00:08:46 +00007390 if (setsid() < 0)
7391 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007392 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007393}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007394#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007395
Larry Hastings2f936352014-08-05 14:04:04 +10007396
Guido van Rossumb6775db1994-08-01 11:34:53 +00007397#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007398/*[clinic input]
7399os.setpgid
7400
7401 pid: pid_t
7402 pgrp: pid_t
7403 /
7404
7405Call the system call setpgid(pid, pgrp).
7406[clinic start generated code]*/
7407
Larry Hastings2f936352014-08-05 14:04:04 +10007408static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007409os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7410/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007411{
Victor Stinner8c62be82010-05-06 00:08:46 +00007412 if (setpgid(pid, pgrp) < 0)
7413 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007414 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007415}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007416#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007418
Guido van Rossumb6775db1994-08-01 11:34:53 +00007419#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007420/*[clinic input]
7421os.tcgetpgrp
7422
7423 fd: int
7424 /
7425
7426Return the process group associated with the terminal specified by fd.
7427[clinic start generated code]*/
7428
Larry Hastings2f936352014-08-05 14:04:04 +10007429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007430os_tcgetpgrp_impl(PyObject *module, int fd)
7431/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007432{
7433 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007434 if (pgid < 0)
7435 return posix_error();
7436 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007437}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007438#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007440
Guido van Rossumb6775db1994-08-01 11:34:53 +00007441#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007442/*[clinic input]
7443os.tcsetpgrp
7444
7445 fd: int
7446 pgid: pid_t
7447 /
7448
7449Set the process group associated with the terminal specified by fd.
7450[clinic start generated code]*/
7451
Larry Hastings2f936352014-08-05 14:04:04 +10007452static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007453os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7454/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007455{
Victor Stinner8c62be82010-05-06 00:08:46 +00007456 if (tcsetpgrp(fd, pgid) < 0)
7457 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007458 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007459}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007460#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007461
Guido van Rossum687dd131993-05-17 08:34:16 +00007462/* Functions acting on file descriptors */
7463
Victor Stinnerdaf45552013-08-28 00:53:59 +02007464#ifdef O_CLOEXEC
7465extern int _Py_open_cloexec_works;
7466#endif
7467
Larry Hastings2f936352014-08-05 14:04:04 +10007468
7469/*[clinic input]
7470os.open -> int
7471 path: path_t
7472 flags: int
7473 mode: int = 0o777
7474 *
7475 dir_fd: dir_fd(requires='openat') = None
7476
7477# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7478
7479Open a file for low level IO. Returns a file descriptor (integer).
7480
7481If dir_fd is not None, it should be a file descriptor open to a directory,
7482 and path should be relative; path will then be relative to that directory.
7483dir_fd may not be implemented on your platform.
7484 If it is unavailable, using it will raise a NotImplementedError.
7485[clinic start generated code]*/
7486
Larry Hastings2f936352014-08-05 14:04:04 +10007487static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007488os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7489/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007490{
7491 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007492 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007493
Victor Stinnerdaf45552013-08-28 00:53:59 +02007494#ifdef O_CLOEXEC
7495 int *atomic_flag_works = &_Py_open_cloexec_works;
7496#elif !defined(MS_WINDOWS)
7497 int *atomic_flag_works = NULL;
7498#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007499
Victor Stinnerdaf45552013-08-28 00:53:59 +02007500#ifdef MS_WINDOWS
7501 flags |= O_NOINHERIT;
7502#elif defined(O_CLOEXEC)
7503 flags |= O_CLOEXEC;
7504#endif
7505
Steve Dower8fc89802015-04-12 00:26:27 -04007506 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007507 do {
7508 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007509#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007510 fd = _wopen(path->wide, flags, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007511#endif
7512#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007513 if (dir_fd != DEFAULT_DIR_FD)
7514 fd = openat(dir_fd, path->narrow, flags, mode);
7515 else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007516 fd = open(path->narrow, flags, mode);
Steve Dowercc16be82016-09-08 10:35:16 -07007517#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007518 Py_END_ALLOW_THREADS
7519 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007520 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007521
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007522 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007523 if (!async_err)
7524 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007525 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007526 }
7527
Victor Stinnerdaf45552013-08-28 00:53:59 +02007528#ifndef MS_WINDOWS
7529 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7530 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007531 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007532 }
7533#endif
7534
Larry Hastings2f936352014-08-05 14:04:04 +10007535 return fd;
7536}
7537
7538
7539/*[clinic input]
7540os.close
7541
7542 fd: int
7543
7544Close a file descriptor.
7545[clinic start generated code]*/
7546
Barry Warsaw53699e91996-12-10 23:23:01 +00007547static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007548os_close_impl(PyObject *module, int fd)
7549/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007550{
Larry Hastings2f936352014-08-05 14:04:04 +10007551 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007552 if (!_PyVerify_fd(fd))
7553 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007554 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7555 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7556 * for more details.
7557 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007558 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007559 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007560 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007561 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 Py_END_ALLOW_THREADS
7563 if (res < 0)
7564 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007565 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007566}
7567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007568
Larry Hastings2f936352014-08-05 14:04:04 +10007569/*[clinic input]
7570os.closerange
7571
7572 fd_low: int
7573 fd_high: int
7574 /
7575
7576Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7577[clinic start generated code]*/
7578
Larry Hastings2f936352014-08-05 14:04:04 +10007579static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007580os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7581/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007582{
7583 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007585 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007586 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007587 if (_PyVerify_fd(i))
7588 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007589 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007590 Py_END_ALLOW_THREADS
7591 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007592}
7593
7594
Larry Hastings2f936352014-08-05 14:04:04 +10007595/*[clinic input]
7596os.dup -> int
7597
7598 fd: int
7599 /
7600
7601Return a duplicate of a file descriptor.
7602[clinic start generated code]*/
7603
Larry Hastings2f936352014-08-05 14:04:04 +10007604static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007605os_dup_impl(PyObject *module, int fd)
7606/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007607{
7608 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007609}
7610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007611
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.dup2
7614 fd: int
7615 fd2: int
7616 inheritable: bool=True
7617
7618Duplicate file descriptor.
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007622os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7623/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007624{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007625 int res;
7626#if defined(HAVE_DUP3) && \
7627 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7628 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7629 int dup3_works = -1;
7630#endif
7631
Victor Stinner8c62be82010-05-06 00:08:46 +00007632 if (!_PyVerify_fd_dup2(fd, fd2))
7633 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007634
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007635 /* dup2() can fail with EINTR if the target FD is already open, because it
7636 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7637 * upon close(), and therefore below.
7638 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007639#ifdef MS_WINDOWS
7640 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007641 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007642 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007643 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007644 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 if (res < 0)
7646 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007647
7648 /* Character files like console cannot be make non-inheritable */
7649 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7650 close(fd2);
7651 return NULL;
7652 }
7653
7654#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7655 Py_BEGIN_ALLOW_THREADS
7656 if (!inheritable)
7657 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7658 else
7659 res = dup2(fd, fd2);
7660 Py_END_ALLOW_THREADS
7661 if (res < 0)
7662 return posix_error();
7663
7664#else
7665
7666#ifdef HAVE_DUP3
7667 if (!inheritable && dup3_works != 0) {
7668 Py_BEGIN_ALLOW_THREADS
7669 res = dup3(fd, fd2, O_CLOEXEC);
7670 Py_END_ALLOW_THREADS
7671 if (res < 0) {
7672 if (dup3_works == -1)
7673 dup3_works = (errno != ENOSYS);
7674 if (dup3_works)
7675 return posix_error();
7676 }
7677 }
7678
7679 if (inheritable || dup3_works == 0)
7680 {
7681#endif
7682 Py_BEGIN_ALLOW_THREADS
7683 res = dup2(fd, fd2);
7684 Py_END_ALLOW_THREADS
7685 if (res < 0)
7686 return posix_error();
7687
7688 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7689 close(fd2);
7690 return NULL;
7691 }
7692#ifdef HAVE_DUP3
7693 }
7694#endif
7695
7696#endif
7697
Larry Hastings2f936352014-08-05 14:04:04 +10007698 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007699}
7700
Larry Hastings2f936352014-08-05 14:04:04 +10007701
Ross Lagerwall7807c352011-03-17 20:20:30 +02007702#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007703/*[clinic input]
7704os.lockf
7705
7706 fd: int
7707 An open file descriptor.
7708 command: int
7709 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7710 length: Py_off_t
7711 The number of bytes to lock, starting at the current position.
7712 /
7713
7714Apply, test or remove a POSIX lock on an open file descriptor.
7715
7716[clinic start generated code]*/
7717
Larry Hastings2f936352014-08-05 14:04:04 +10007718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007719os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7720/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007721{
7722 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007723
7724 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007725 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007726 Py_END_ALLOW_THREADS
7727
7728 if (res < 0)
7729 return posix_error();
7730
7731 Py_RETURN_NONE;
7732}
Larry Hastings2f936352014-08-05 14:04:04 +10007733#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007734
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007735
Larry Hastings2f936352014-08-05 14:04:04 +10007736/*[clinic input]
7737os.lseek -> Py_off_t
7738
7739 fd: int
7740 position: Py_off_t
7741 how: int
7742 /
7743
7744Set the position of a file descriptor. Return the new position.
7745
7746Return the new cursor position in number of bytes
7747relative to the beginning of the file.
7748[clinic start generated code]*/
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007751os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7752/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007753{
7754 Py_off_t result;
7755
7756 if (!_PyVerify_fd(fd)) {
7757 posix_error();
7758 return -1;
7759 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007760#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007761 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7762 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007763 case 0: how = SEEK_SET; break;
7764 case 1: how = SEEK_CUR; break;
7765 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007766 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007767#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007768
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007770 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007771
Larry Hastings2f936352014-08-05 14:04:04 +10007772 if (!_PyVerify_fd(fd)) {
7773 posix_error();
7774 return -1;
7775 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007776 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007777 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007778#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007779 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007780#else
Larry Hastings2f936352014-08-05 14:04:04 +10007781 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007782#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007783 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007785 if (result < 0)
7786 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007787
Larry Hastings2f936352014-08-05 14:04:04 +10007788 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007789}
7790
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007791
Larry Hastings2f936352014-08-05 14:04:04 +10007792/*[clinic input]
7793os.read
7794 fd: int
7795 length: Py_ssize_t
7796 /
7797
7798Read from a file descriptor. Returns a bytes object.
7799[clinic start generated code]*/
7800
Larry Hastings2f936352014-08-05 14:04:04 +10007801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007802os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7803/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007804{
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 Py_ssize_t n;
7806 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007807
7808 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 errno = EINVAL;
7810 return posix_error();
7811 }
Larry Hastings2f936352014-08-05 14:04:04 +10007812
7813#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007814 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007815 if (length > INT_MAX)
7816 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007817#endif
7818
7819 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 if (buffer == NULL)
7821 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007822
Victor Stinner66aab0c2015-03-19 22:53:20 +01007823 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7824 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007826 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007827 }
Larry Hastings2f936352014-08-05 14:04:04 +10007828
7829 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007830 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007831
Victor Stinner8c62be82010-05-06 00:08:46 +00007832 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007833}
7834
Ross Lagerwall7807c352011-03-17 20:20:30 +02007835#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7836 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007837static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007838iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7839{
7840 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007841 Py_ssize_t blen, total = 0;
7842
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007843 *iov = PyMem_New(struct iovec, cnt);
7844 if (*iov == NULL) {
7845 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007846 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007847 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007848
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007849 *buf = PyMem_New(Py_buffer, cnt);
7850 if (*buf == NULL) {
7851 PyMem_Del(*iov);
7852 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007853 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007854 }
7855
7856 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007857 PyObject *item = PySequence_GetItem(seq, i);
7858 if (item == NULL)
7859 goto fail;
7860 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7861 Py_DECREF(item);
7862 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007863 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007864 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007865 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007866 blen = (*buf)[i].len;
7867 (*iov)[i].iov_len = blen;
7868 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007869 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007870 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007871
7872fail:
7873 PyMem_Del(*iov);
7874 for (j = 0; j < i; j++) {
7875 PyBuffer_Release(&(*buf)[j]);
7876 }
7877 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007878 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007879}
7880
7881static void
7882iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7883{
7884 int i;
7885 PyMem_Del(iov);
7886 for (i = 0; i < cnt; i++) {
7887 PyBuffer_Release(&buf[i]);
7888 }
7889 PyMem_Del(buf);
7890}
7891#endif
7892
Larry Hastings2f936352014-08-05 14:04:04 +10007893
Ross Lagerwall7807c352011-03-17 20:20:30 +02007894#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007895/*[clinic input]
7896os.readv -> Py_ssize_t
7897
7898 fd: int
7899 buffers: object
7900 /
7901
7902Read from a file descriptor fd into an iterable of buffers.
7903
7904The buffers should be mutable buffers accepting bytes.
7905readv will transfer data into each buffer until it is full
7906and then move on to the next buffer in the sequence to hold
7907the rest of the data.
7908
7909readv returns the total number of bytes read,
7910which may be less than the total capacity of all the buffers.
7911[clinic start generated code]*/
7912
Larry Hastings2f936352014-08-05 14:04:04 +10007913static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007914os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7915/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007916{
7917 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007918 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007919 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007920 struct iovec *iov;
7921 Py_buffer *buf;
7922
Larry Hastings2f936352014-08-05 14:04:04 +10007923 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007924 PyErr_SetString(PyExc_TypeError,
7925 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007926 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007927 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007928
Larry Hastings2f936352014-08-05 14:04:04 +10007929 cnt = PySequence_Size(buffers);
7930
7931 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7932 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007934 do {
7935 Py_BEGIN_ALLOW_THREADS
7936 n = readv(fd, iov, cnt);
7937 Py_END_ALLOW_THREADS
7938 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007939
7940 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007941 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007942 if (!async_err)
7943 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007944 return -1;
7945 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007946
Larry Hastings2f936352014-08-05 14:04:04 +10007947 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007948}
Larry Hastings2f936352014-08-05 14:04:04 +10007949#endif /* HAVE_READV */
7950
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951
7952#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007953/*[clinic input]
7954# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7955os.pread
7956
7957 fd: int
7958 length: int
7959 offset: Py_off_t
7960 /
7961
7962Read a number of bytes from a file descriptor starting at a particular offset.
7963
7964Read length bytes from file descriptor fd, starting at offset bytes from
7965the beginning of the file. The file offset remains unchanged.
7966[clinic start generated code]*/
7967
Larry Hastings2f936352014-08-05 14:04:04 +10007968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007969os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
7970/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007971{
Ross Lagerwall7807c352011-03-17 20:20:30 +02007972 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007973 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007974 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007975
Larry Hastings2f936352014-08-05 14:04:04 +10007976 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007977 errno = EINVAL;
7978 return posix_error();
7979 }
Larry Hastings2f936352014-08-05 14:04:04 +10007980 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007981 if (buffer == NULL)
7982 return NULL;
7983 if (!_PyVerify_fd(fd)) {
7984 Py_DECREF(buffer);
7985 return posix_error();
7986 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007987
7988 do {
7989 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007990 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007991 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04007992 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007993 Py_END_ALLOW_THREADS
7994 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7995
Ross Lagerwall7807c352011-03-17 20:20:30 +02007996 if (n < 0) {
7997 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007998 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007999 }
Larry Hastings2f936352014-08-05 14:04:04 +10008000 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008001 _PyBytes_Resize(&buffer, n);
8002 return buffer;
8003}
Larry Hastings2f936352014-08-05 14:04:04 +10008004#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008005
Larry Hastings2f936352014-08-05 14:04:04 +10008006
8007/*[clinic input]
8008os.write -> Py_ssize_t
8009
8010 fd: int
8011 data: Py_buffer
8012 /
8013
8014Write a bytes object to a file descriptor.
8015[clinic start generated code]*/
8016
Larry Hastings2f936352014-08-05 14:04:04 +10008017static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008018os_write_impl(PyObject *module, int fd, Py_buffer *data)
8019/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008020{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008021 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008022}
8023
8024#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008025PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008026"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008027sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008028 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008029Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008030
Larry Hastings2f936352014-08-05 14:04:04 +10008031/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032static PyObject *
8033posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8034{
8035 int in, out;
8036 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008037 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008038 off_t offset;
8039
8040#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8041#ifndef __APPLE__
8042 Py_ssize_t len;
8043#endif
8044 PyObject *headers = NULL, *trailers = NULL;
8045 Py_buffer *hbuf, *tbuf;
8046 off_t sbytes;
8047 struct sf_hdtr sf;
8048 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008049 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008050 static char *keywords[] = {"out", "in",
8051 "offset", "count",
8052 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008054 sf.headers = NULL;
8055 sf.trailers = NULL;
8056
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057#ifdef __APPLE__
8058 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008059 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008060#else
8061 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008062 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063#endif
8064 &headers, &trailers, &flags))
8065 return NULL;
8066 if (headers != NULL) {
8067 if (!PySequence_Check(headers)) {
8068 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008069 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 return NULL;
8071 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008072 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008074 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008075 (i = iov_setup(&(sf.headers), &hbuf,
8076 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078#ifdef __APPLE__
8079 sbytes += i;
8080#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081 }
8082 }
8083 if (trailers != NULL) {
8084 if (!PySequence_Check(trailers)) {
8085 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008086 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008087 return NULL;
8088 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008089 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008091 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008092 (i = iov_setup(&(sf.trailers), &tbuf,
8093 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008094 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008095#ifdef __APPLE__
8096 sbytes += i;
8097#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008098 }
8099 }
8100
Steve Dower8fc89802015-04-12 00:26:27 -04008101 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008102 do {
8103 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008105 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008107 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008108#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008109 Py_END_ALLOW_THREADS
8110 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008111 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008112
8113 if (sf.headers != NULL)
8114 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8115 if (sf.trailers != NULL)
8116 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8117
8118 if (ret < 0) {
8119 if ((errno == EAGAIN) || (errno == EBUSY)) {
8120 if (sbytes != 0) {
8121 // some data has been sent
8122 goto done;
8123 }
8124 else {
8125 // no data has been sent; upper application is supposed
8126 // to retry on EAGAIN or EBUSY
8127 return posix_error();
8128 }
8129 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008130 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008131 }
8132 goto done;
8133
8134done:
8135 #if !defined(HAVE_LARGEFILE_SUPPORT)
8136 return Py_BuildValue("l", sbytes);
8137 #else
8138 return Py_BuildValue("L", sbytes);
8139 #endif
8140
8141#else
8142 Py_ssize_t count;
8143 PyObject *offobj;
8144 static char *keywords[] = {"out", "in",
8145 "offset", "count", NULL};
8146 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8147 keywords, &out, &in, &offobj, &count))
8148 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008149#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008150 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008151 do {
8152 Py_BEGIN_ALLOW_THREADS
8153 ret = sendfile(out, in, NULL, count);
8154 Py_END_ALLOW_THREADS
8155 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008156 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008157 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008158 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008159 }
8160#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008161 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008162 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008163
8164 do {
8165 Py_BEGIN_ALLOW_THREADS
8166 ret = sendfile(out, in, &offset, count);
8167 Py_END_ALLOW_THREADS
8168 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008169 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008170 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008171 return Py_BuildValue("n", ret);
8172#endif
8173}
Larry Hastings2f936352014-08-05 14:04:04 +10008174#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008175
Larry Hastings2f936352014-08-05 14:04:04 +10008176
8177/*[clinic input]
8178os.fstat
8179
8180 fd : int
8181
8182Perform a stat system call on the given file descriptor.
8183
8184Like stat(), but for an open file descriptor.
8185Equivalent to os.stat(fd).
8186[clinic start generated code]*/
8187
Larry Hastings2f936352014-08-05 14:04:04 +10008188static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008189os_fstat_impl(PyObject *module, int fd)
8190/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008191{
Victor Stinner8c62be82010-05-06 00:08:46 +00008192 STRUCT_STAT st;
8193 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008194 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008195
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008196 do {
8197 Py_BEGIN_ALLOW_THREADS
8198 res = FSTAT(fd, &st);
8199 Py_END_ALLOW_THREADS
8200 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008201 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008202#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008203 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008204#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008205 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008206#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008207 }
Tim Peters5aa91602002-01-30 05:46:57 +00008208
Victor Stinner4195b5c2012-02-08 23:03:19 +01008209 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008210}
8211
Larry Hastings2f936352014-08-05 14:04:04 +10008212
8213/*[clinic input]
8214os.isatty -> bool
8215 fd: int
8216 /
8217
8218Return True if the fd is connected to a terminal.
8219
8220Return True if the file descriptor is an open file descriptor
8221connected to the slave end of a terminal.
8222[clinic start generated code]*/
8223
Larry Hastings2f936352014-08-05 14:04:04 +10008224static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008225os_isatty_impl(PyObject *module, int fd)
8226/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008227{
Steve Dower8fc89802015-04-12 00:26:27 -04008228 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008229 if (!_PyVerify_fd(fd))
8230 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008231 _Py_BEGIN_SUPPRESS_IPH
8232 return_value = isatty(fd);
8233 _Py_END_SUPPRESS_IPH
8234 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008235}
8236
8237
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008238#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008239/*[clinic input]
8240os.pipe
8241
8242Create a pipe.
8243
8244Returns a tuple of two file descriptors:
8245 (read_fd, write_fd)
8246[clinic start generated code]*/
8247
Larry Hastings2f936352014-08-05 14:04:04 +10008248static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008249os_pipe_impl(PyObject *module)
8250/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008251{
Victor Stinner8c62be82010-05-06 00:08:46 +00008252 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008253#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008254 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008255 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008256 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008257#else
8258 int res;
8259#endif
8260
8261#ifdef MS_WINDOWS
8262 attr.nLength = sizeof(attr);
8263 attr.lpSecurityDescriptor = NULL;
8264 attr.bInheritHandle = FALSE;
8265
8266 Py_BEGIN_ALLOW_THREADS
8267 ok = CreatePipe(&read, &write, &attr, 0);
8268 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008269 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8270 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008271 if (fds[0] == -1 || fds[1] == -1) {
8272 CloseHandle(read);
8273 CloseHandle(write);
8274 ok = 0;
8275 }
8276 }
8277 Py_END_ALLOW_THREADS
8278
Victor Stinner8c62be82010-05-06 00:08:46 +00008279 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008280 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008281#else
8282
8283#ifdef HAVE_PIPE2
8284 Py_BEGIN_ALLOW_THREADS
8285 res = pipe2(fds, O_CLOEXEC);
8286 Py_END_ALLOW_THREADS
8287
8288 if (res != 0 && errno == ENOSYS)
8289 {
8290#endif
8291 Py_BEGIN_ALLOW_THREADS
8292 res = pipe(fds);
8293 Py_END_ALLOW_THREADS
8294
8295 if (res == 0) {
8296 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8297 close(fds[0]);
8298 close(fds[1]);
8299 return NULL;
8300 }
8301 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8302 close(fds[0]);
8303 close(fds[1]);
8304 return NULL;
8305 }
8306 }
8307#ifdef HAVE_PIPE2
8308 }
8309#endif
8310
8311 if (res != 0)
8312 return PyErr_SetFromErrno(PyExc_OSError);
8313#endif /* !MS_WINDOWS */
8314 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008315}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008316#endif /* HAVE_PIPE */
8317
Larry Hastings2f936352014-08-05 14:04:04 +10008318
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008319#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008320/*[clinic input]
8321os.pipe2
8322
8323 flags: int
8324 /
8325
8326Create a pipe with flags set atomically.
8327
8328Returns a tuple of two file descriptors:
8329 (read_fd, write_fd)
8330
8331flags can be constructed by ORing together one or more of these values:
8332O_NONBLOCK, O_CLOEXEC.
8333[clinic start generated code]*/
8334
Larry Hastings2f936352014-08-05 14:04:04 +10008335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008336os_pipe2_impl(PyObject *module, int flags)
8337/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008338{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008339 int fds[2];
8340 int res;
8341
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008342 res = pipe2(fds, flags);
8343 if (res != 0)
8344 return posix_error();
8345 return Py_BuildValue("(ii)", fds[0], fds[1]);
8346}
8347#endif /* HAVE_PIPE2 */
8348
Larry Hastings2f936352014-08-05 14:04:04 +10008349
Ross Lagerwall7807c352011-03-17 20:20:30 +02008350#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008351/*[clinic input]
8352os.writev -> Py_ssize_t
8353 fd: int
8354 buffers: object
8355 /
8356
8357Iterate over buffers, and write the contents of each to a file descriptor.
8358
8359Returns the total number of bytes written.
8360buffers must be a sequence of bytes-like objects.
8361[clinic start generated code]*/
8362
Larry Hastings2f936352014-08-05 14:04:04 +10008363static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008364os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8365/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008366{
8367 int cnt;
8368 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008369 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008370 struct iovec *iov;
8371 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008372
8373 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008374 PyErr_SetString(PyExc_TypeError,
8375 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008376 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008377 }
Larry Hastings2f936352014-08-05 14:04:04 +10008378 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008379
Larry Hastings2f936352014-08-05 14:04:04 +10008380 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8381 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008382 }
8383
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008384 do {
8385 Py_BEGIN_ALLOW_THREADS
8386 result = writev(fd, iov, cnt);
8387 Py_END_ALLOW_THREADS
8388 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008389
8390 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008391 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008392 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008393
Georg Brandl306336b2012-06-24 12:55:33 +02008394 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008395}
Larry Hastings2f936352014-08-05 14:04:04 +10008396#endif /* HAVE_WRITEV */
8397
8398
8399#ifdef HAVE_PWRITE
8400/*[clinic input]
8401os.pwrite -> Py_ssize_t
8402
8403 fd: int
8404 buffer: Py_buffer
8405 offset: Py_off_t
8406 /
8407
8408Write bytes to a file descriptor starting at a particular offset.
8409
8410Write buffer to fd, starting at offset bytes from the beginning of
8411the file. Returns the number of bytes writte. Does not change the
8412current file offset.
8413[clinic start generated code]*/
8414
Larry Hastings2f936352014-08-05 14:04:04 +10008415static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008416os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8417/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008418{
8419 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008420 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008421
8422 if (!_PyVerify_fd(fd)) {
8423 posix_error();
8424 return -1;
8425 }
8426
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008427 do {
8428 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008429 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008430 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008431 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008432 Py_END_ALLOW_THREADS
8433 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008434
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008435 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008436 posix_error();
8437 return size;
8438}
8439#endif /* HAVE_PWRITE */
8440
8441
8442#ifdef HAVE_MKFIFO
8443/*[clinic input]
8444os.mkfifo
8445
8446 path: path_t
8447 mode: int=0o666
8448 *
8449 dir_fd: dir_fd(requires='mkfifoat')=None
8450
8451Create a "fifo" (a POSIX named pipe).
8452
8453If dir_fd is not None, it should be a file descriptor open to a directory,
8454 and path should be relative; path will then be relative to that directory.
8455dir_fd may not be implemented on your platform.
8456 If it is unavailable, using it will raise a NotImplementedError.
8457[clinic start generated code]*/
8458
Larry Hastings2f936352014-08-05 14:04:04 +10008459static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008460os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8461/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
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_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008469 if (dir_fd != DEFAULT_DIR_FD)
8470 result = mkfifoat(dir_fd, path->narrow, mode);
8471 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008472#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008473 result = mkfifo(path->narrow, mode);
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 /* HAVE_MKFIFO */
8483
8484
8485#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8486/*[clinic input]
8487os.mknod
8488
8489 path: path_t
8490 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008491 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008492 *
8493 dir_fd: dir_fd(requires='mknodat')=None
8494
8495Create a node in the file system.
8496
8497Create a node in the file system (file, device special file or named pipe)
8498at path. mode specifies both the permissions to use and the
8499type of node to be created, being combined (bitwise OR) with one of
8500S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8501device defines the newly created device special file (probably using
8502os.makedev()). Otherwise device is ignored.
8503
8504If dir_fd is not None, it should be a file descriptor open to a directory,
8505 and path should be relative; path will then be relative to that directory.
8506dir_fd may not be implemented on your platform.
8507 If it is unavailable, using it will raise a NotImplementedError.
8508[clinic start generated code]*/
8509
Larry Hastings2f936352014-08-05 14:04:04 +10008510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008511os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008512 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008513/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008514{
8515 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008516 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008517
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008518 do {
8519 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008520#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008521 if (dir_fd != DEFAULT_DIR_FD)
8522 result = mknodat(dir_fd, path->narrow, mode, device);
8523 else
Larry Hastings2f936352014-08-05 14:04:04 +10008524#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008525 result = mknod(path->narrow, mode, device);
8526 Py_END_ALLOW_THREADS
8527 } while (result != 0 && errno == EINTR &&
8528 !(async_err = PyErr_CheckSignals()));
8529 if (result != 0)
8530 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008531
8532 Py_RETURN_NONE;
8533}
8534#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8535
8536
8537#ifdef HAVE_DEVICE_MACROS
8538/*[clinic input]
8539os.major -> unsigned_int
8540
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008541 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008542 /
8543
8544Extracts a device major number from a raw device number.
8545[clinic start generated code]*/
8546
Larry Hastings2f936352014-08-05 14:04:04 +10008547static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008548os_major_impl(PyObject *module, dev_t device)
8549/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008550{
8551 return major(device);
8552}
8553
8554
8555/*[clinic input]
8556os.minor -> unsigned_int
8557
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008558 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008559 /
8560
8561Extracts a device minor number from a raw device number.
8562[clinic start generated code]*/
8563
Larry Hastings2f936352014-08-05 14:04:04 +10008564static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008565os_minor_impl(PyObject *module, dev_t device)
8566/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008567{
8568 return minor(device);
8569}
8570
8571
8572/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008573os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008574
8575 major: int
8576 minor: int
8577 /
8578
8579Composes a raw device number from the major and minor device numbers.
8580[clinic start generated code]*/
8581
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008582static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008583os_makedev_impl(PyObject *module, int major, int minor)
8584/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008585{
8586 return makedev(major, minor);
8587}
8588#endif /* HAVE_DEVICE_MACROS */
8589
8590
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008591#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008592/*[clinic input]
8593os.ftruncate
8594
8595 fd: int
8596 length: Py_off_t
8597 /
8598
8599Truncate a file, specified by file descriptor, to a specific length.
8600[clinic start generated code]*/
8601
Larry Hastings2f936352014-08-05 14:04:04 +10008602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008603os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8604/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008605{
8606 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008607 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008608
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008609 if (!_PyVerify_fd(fd))
8610 return posix_error();
8611
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008612 do {
8613 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008614 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008615#ifdef MS_WINDOWS
8616 result = _chsize_s(fd, length);
8617#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008618 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008619#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008620 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008621 Py_END_ALLOW_THREADS
8622 } while (result != 0 && errno == EINTR &&
8623 !(async_err = PyErr_CheckSignals()));
8624 if (result != 0)
8625 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008626 Py_RETURN_NONE;
8627}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008628#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008629
8630
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008631#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008632/*[clinic input]
8633os.truncate
8634 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8635 length: Py_off_t
8636
8637Truncate a file, specified by path, to a specific length.
8638
8639On some platforms, path may also be specified as an open file descriptor.
8640 If this functionality is unavailable, using it raises an exception.
8641[clinic start generated code]*/
8642
Larry Hastings2f936352014-08-05 14:04:04 +10008643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008644os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8645/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008646{
8647 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008648#ifdef MS_WINDOWS
8649 int fd;
8650#endif
8651
8652 if (path->fd != -1)
8653 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008654
8655 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008656 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008657#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008658 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008659 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008660 result = -1;
8661 else {
8662 result = _chsize_s(fd, length);
8663 close(fd);
8664 if (result < 0)
8665 errno = result;
8666 }
8667#else
8668 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008669#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008670 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008671 Py_END_ALLOW_THREADS
8672 if (result < 0)
8673 return path_error(path);
8674
8675 Py_RETURN_NONE;
8676}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008677#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008678
Ross Lagerwall7807c352011-03-17 20:20:30 +02008679
Victor Stinnerd6b17692014-09-30 12:20:05 +02008680/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8681 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8682 defined, which is the case in Python on AIX. AIX bug report:
8683 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8684#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8685# define POSIX_FADVISE_AIX_BUG
8686#endif
8687
Victor Stinnerec39e262014-09-30 12:35:58 +02008688
Victor Stinnerd6b17692014-09-30 12:20:05 +02008689#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008690/*[clinic input]
8691os.posix_fallocate
8692
8693 fd: int
8694 offset: Py_off_t
8695 length: Py_off_t
8696 /
8697
8698Ensure a file has allocated at least a particular number of bytes on disk.
8699
8700Ensure that the file specified by fd encompasses a range of bytes
8701starting at offset bytes from the beginning and continuing for length bytes.
8702[clinic start generated code]*/
8703
Larry Hastings2f936352014-08-05 14:04:04 +10008704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008705os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008706 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008707/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008708{
8709 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008710 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008711
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008712 do {
8713 Py_BEGIN_ALLOW_THREADS
8714 result = posix_fallocate(fd, offset, length);
8715 Py_END_ALLOW_THREADS
8716 } while (result != 0 && errno == EINTR &&
8717 !(async_err = PyErr_CheckSignals()));
8718 if (result != 0)
8719 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008720 Py_RETURN_NONE;
8721}
Victor Stinnerec39e262014-09-30 12:35:58 +02008722#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008723
Ross Lagerwall7807c352011-03-17 20:20:30 +02008724
Victor Stinnerd6b17692014-09-30 12:20:05 +02008725#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008726/*[clinic input]
8727os.posix_fadvise
8728
8729 fd: int
8730 offset: Py_off_t
8731 length: Py_off_t
8732 advice: int
8733 /
8734
8735Announce an intention to access data in a specific pattern.
8736
8737Announce an intention to access data in a specific pattern, thus allowing
8738the kernel to make optimizations.
8739The advice applies to the region of the file specified by fd starting at
8740offset and continuing for length bytes.
8741advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8742POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8743POSIX_FADV_DONTNEED.
8744[clinic start generated code]*/
8745
Larry Hastings2f936352014-08-05 14:04:04 +10008746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008747os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008748 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008749/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008750{
8751 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008752 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008753
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008754 do {
8755 Py_BEGIN_ALLOW_THREADS
8756 result = posix_fadvise(fd, offset, length, advice);
8757 Py_END_ALLOW_THREADS
8758 } while (result != 0 && errno == EINTR &&
8759 !(async_err = PyErr_CheckSignals()));
8760 if (result != 0)
8761 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008762 Py_RETURN_NONE;
8763}
Victor Stinnerec39e262014-09-30 12:35:58 +02008764#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008765
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008766#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008767
Fred Drake762e2061999-08-26 17:23:54 +00008768/* Save putenv() parameters as values here, so we can collect them when they
8769 * get re-set with another call for the same key. */
8770static PyObject *posix_putenv_garbage;
8771
Larry Hastings2f936352014-08-05 14:04:04 +10008772static void
8773posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008774{
Larry Hastings2f936352014-08-05 14:04:04 +10008775 /* Install the first arg and newstr in posix_putenv_garbage;
8776 * this will cause previous value to be collected. This has to
8777 * happen after the real putenv() call because the old value
8778 * was still accessible until then. */
8779 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8780 /* really not much we can do; just leak */
8781 PyErr_Clear();
8782 else
8783 Py_DECREF(value);
8784}
8785
8786
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008787#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008788/*[clinic input]
8789os.putenv
8790
8791 name: unicode
8792 value: unicode
8793 /
8794
8795Change or add an environment variable.
8796[clinic start generated code]*/
8797
Larry Hastings2f936352014-08-05 14:04:04 +10008798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008799os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8800/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008801{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008802 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008803
8804 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8805 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008806 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008807 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008808 }
Larry Hastings2f936352014-08-05 14:04:04 +10008809 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008810 PyErr_Format(PyExc_ValueError,
8811 "the environment variable is longer than %u characters",
8812 _MAX_ENV);
8813 goto error;
8814 }
8815
Larry Hastings2f936352014-08-05 14:04:04 +10008816 env = PyUnicode_AsUnicode(unicode);
8817 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008818 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008819 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008820 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008821 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008822 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008823
Larry Hastings2f936352014-08-05 14:04:04 +10008824 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008825 Py_RETURN_NONE;
8826
8827error:
Larry Hastings2f936352014-08-05 14:04:04 +10008828 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008829 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008830}
Larry Hastings2f936352014-08-05 14:04:04 +10008831#else /* MS_WINDOWS */
8832/*[clinic input]
8833os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008834
Larry Hastings2f936352014-08-05 14:04:04 +10008835 name: FSConverter
8836 value: FSConverter
8837 /
8838
8839Change or add an environment variable.
8840[clinic start generated code]*/
8841
Larry Hastings2f936352014-08-05 14:04:04 +10008842static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008843os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8844/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008845{
8846 PyObject *bytes = NULL;
8847 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008848 const char *name_string = PyBytes_AsString(name);
8849 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008850
8851 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8852 if (bytes == NULL) {
8853 PyErr_NoMemory();
8854 return NULL;
8855 }
8856
8857 env = PyBytes_AS_STRING(bytes);
8858 if (putenv(env)) {
8859 Py_DECREF(bytes);
8860 return posix_error();
8861 }
8862
8863 posix_putenv_garbage_setitem(name, bytes);
8864 Py_RETURN_NONE;
8865}
8866#endif /* MS_WINDOWS */
8867#endif /* HAVE_PUTENV */
8868
8869
8870#ifdef HAVE_UNSETENV
8871/*[clinic input]
8872os.unsetenv
8873 name: FSConverter
8874 /
8875
8876Delete an environment variable.
8877[clinic start generated code]*/
8878
Larry Hastings2f936352014-08-05 14:04:04 +10008879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008880os_unsetenv_impl(PyObject *module, PyObject *name)
8881/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008882{
Victor Stinner984890f2011-11-24 13:53:38 +01008883#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008884 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008885#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008886
Victor Stinner984890f2011-11-24 13:53:38 +01008887#ifdef HAVE_BROKEN_UNSETENV
8888 unsetenv(PyBytes_AS_STRING(name));
8889#else
Victor Stinner65170952011-11-22 22:16:17 +01008890 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008891 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008892 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008893#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008894
Victor Stinner8c62be82010-05-06 00:08:46 +00008895 /* Remove the key from posix_putenv_garbage;
8896 * this will cause it to be collected. This has to
8897 * happen after the real unsetenv() call because the
8898 * old value was still accessible until then.
8899 */
Victor Stinner65170952011-11-22 22:16:17 +01008900 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008901 /* really not much we can do; just leak */
8902 PyErr_Clear();
8903 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008904 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008905}
Larry Hastings2f936352014-08-05 14:04:04 +10008906#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008907
Larry Hastings2f936352014-08-05 14:04:04 +10008908
8909/*[clinic input]
8910os.strerror
8911
8912 code: int
8913 /
8914
8915Translate an error code to a message string.
8916[clinic start generated code]*/
8917
Larry Hastings2f936352014-08-05 14:04:04 +10008918static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008919os_strerror_impl(PyObject *module, int code)
8920/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008921{
8922 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008923 if (message == NULL) {
8924 PyErr_SetString(PyExc_ValueError,
8925 "strerror() argument out of range");
8926 return NULL;
8927 }
Victor Stinner1b579672011-12-17 05:47:23 +01008928 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008929}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008930
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008931
Guido van Rossumc9641791998-08-04 15:26:23 +00008932#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008933#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008934/*[clinic input]
8935os.WCOREDUMP -> bool
8936
8937 status: int
8938 /
8939
8940Return True if the process returning status was dumped to a core file.
8941[clinic start generated code]*/
8942
Larry Hastings2f936352014-08-05 14:04:04 +10008943static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008944os_WCOREDUMP_impl(PyObject *module, int status)
8945/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008946{
8947 WAIT_TYPE wait_status;
8948 WAIT_STATUS_INT(wait_status) = status;
8949 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008950}
8951#endif /* WCOREDUMP */
8952
Larry Hastings2f936352014-08-05 14:04:04 +10008953
Fred Drake106c1a02002-04-23 15:58:02 +00008954#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008955/*[clinic input]
8956os.WIFCONTINUED -> bool
8957
8958 status: int
8959
8960Return True if a particular process was continued from a job control stop.
8961
8962Return True if the process returning status was continued from a
8963job control stop.
8964[clinic start generated code]*/
8965
Larry Hastings2f936352014-08-05 14:04:04 +10008966static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008967os_WIFCONTINUED_impl(PyObject *module, int status)
8968/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008969{
8970 WAIT_TYPE wait_status;
8971 WAIT_STATUS_INT(wait_status) = status;
8972 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008973}
8974#endif /* WIFCONTINUED */
8975
Larry Hastings2f936352014-08-05 14:04:04 +10008976
Guido van Rossumc9641791998-08-04 15:26:23 +00008977#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10008978/*[clinic input]
8979os.WIFSTOPPED -> bool
8980
8981 status: int
8982
8983Return True if the process returning status was stopped.
8984[clinic start generated code]*/
8985
Larry Hastings2f936352014-08-05 14:04:04 +10008986static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008987os_WIFSTOPPED_impl(PyObject *module, int status)
8988/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008989{
8990 WAIT_TYPE wait_status;
8991 WAIT_STATUS_INT(wait_status) = status;
8992 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008993}
8994#endif /* WIFSTOPPED */
8995
Larry Hastings2f936352014-08-05 14:04:04 +10008996
Guido van Rossumc9641791998-08-04 15:26:23 +00008997#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10008998/*[clinic input]
8999os.WIFSIGNALED -> bool
9000
9001 status: int
9002
9003Return True if the process returning status was terminated by a signal.
9004[clinic start generated code]*/
9005
Larry Hastings2f936352014-08-05 14:04:04 +10009006static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009007os_WIFSIGNALED_impl(PyObject *module, int status)
9008/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009009{
9010 WAIT_TYPE wait_status;
9011 WAIT_STATUS_INT(wait_status) = status;
9012 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009013}
9014#endif /* WIFSIGNALED */
9015
Larry Hastings2f936352014-08-05 14:04:04 +10009016
Guido van Rossumc9641791998-08-04 15:26:23 +00009017#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009018/*[clinic input]
9019os.WIFEXITED -> bool
9020
9021 status: int
9022
9023Return True if the process returning status exited via the exit() system call.
9024[clinic start generated code]*/
9025
Larry Hastings2f936352014-08-05 14:04:04 +10009026static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009027os_WIFEXITED_impl(PyObject *module, int status)
9028/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009029{
9030 WAIT_TYPE wait_status;
9031 WAIT_STATUS_INT(wait_status) = status;
9032 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009033}
9034#endif /* WIFEXITED */
9035
Larry Hastings2f936352014-08-05 14:04:04 +10009036
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009037#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009038/*[clinic input]
9039os.WEXITSTATUS -> int
9040
9041 status: int
9042
9043Return the process return code from status.
9044[clinic start generated code]*/
9045
Larry Hastings2f936352014-08-05 14:04:04 +10009046static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009047os_WEXITSTATUS_impl(PyObject *module, int status)
9048/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009049{
9050 WAIT_TYPE wait_status;
9051 WAIT_STATUS_INT(wait_status) = status;
9052 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009053}
9054#endif /* WEXITSTATUS */
9055
Larry Hastings2f936352014-08-05 14:04:04 +10009056
Guido van Rossumc9641791998-08-04 15:26:23 +00009057#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009058/*[clinic input]
9059os.WTERMSIG -> int
9060
9061 status: int
9062
9063Return the signal that terminated the process that provided the status value.
9064[clinic start generated code]*/
9065
Larry Hastings2f936352014-08-05 14:04:04 +10009066static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009067os_WTERMSIG_impl(PyObject *module, int status)
9068/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009069{
9070 WAIT_TYPE wait_status;
9071 WAIT_STATUS_INT(wait_status) = status;
9072 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009073}
9074#endif /* WTERMSIG */
9075
Larry Hastings2f936352014-08-05 14:04:04 +10009076
Guido van Rossumc9641791998-08-04 15:26:23 +00009077#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009078/*[clinic input]
9079os.WSTOPSIG -> int
9080
9081 status: int
9082
9083Return the signal that stopped the process that provided the status value.
9084[clinic start generated code]*/
9085
Larry Hastings2f936352014-08-05 14:04:04 +10009086static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009087os_WSTOPSIG_impl(PyObject *module, int status)
9088/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009089{
9090 WAIT_TYPE wait_status;
9091 WAIT_STATUS_INT(wait_status) = status;
9092 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009093}
9094#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009095#endif /* HAVE_SYS_WAIT_H */
9096
9097
Thomas Wouters477c8d52006-05-27 19:21:47 +00009098#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009099#ifdef _SCO_DS
9100/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9101 needed definitions in sys/statvfs.h */
9102#define _SVID3
9103#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009104#include <sys/statvfs.h>
9105
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009106static PyObject*
9107_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009108 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9109 if (v == NULL)
9110 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009111
9112#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9114 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9115 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9116 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9117 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9118 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9119 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9120 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9121 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9122 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009123#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9125 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9126 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009127 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009129 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009131 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009133 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009135 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009137 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009138 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9139 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009140#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009141 if (PyErr_Occurred()) {
9142 Py_DECREF(v);
9143 return NULL;
9144 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009145
Victor Stinner8c62be82010-05-06 00:08:46 +00009146 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009147}
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149
9150/*[clinic input]
9151os.fstatvfs
9152 fd: int
9153 /
9154
9155Perform an fstatvfs system call on the given fd.
9156
9157Equivalent to statvfs(fd).
9158[clinic start generated code]*/
9159
Larry Hastings2f936352014-08-05 14:04:04 +10009160static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009161os_fstatvfs_impl(PyObject *module, int fd)
9162/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009163{
9164 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009165 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009166 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009167
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009168 do {
9169 Py_BEGIN_ALLOW_THREADS
9170 result = fstatvfs(fd, &st);
9171 Py_END_ALLOW_THREADS
9172 } while (result != 0 && errno == EINTR &&
9173 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009174 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009175 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009176
Victor Stinner8c62be82010-05-06 00:08:46 +00009177 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009178}
Larry Hastings2f936352014-08-05 14:04:04 +10009179#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009180
9181
Thomas Wouters477c8d52006-05-27 19:21:47 +00009182#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009183#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009184/*[clinic input]
9185os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009186
Larry Hastings2f936352014-08-05 14:04:04 +10009187 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9188
9189Perform a statvfs system call on the given path.
9190
9191path may always be specified as a string.
9192On some platforms, path may also be specified as an open file descriptor.
9193 If this functionality is unavailable, using it raises an exception.
9194[clinic start generated code]*/
9195
Larry Hastings2f936352014-08-05 14:04:04 +10009196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009197os_statvfs_impl(PyObject *module, path_t *path)
9198/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009199{
9200 int result;
9201 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009202
9203 Py_BEGIN_ALLOW_THREADS
9204#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009205 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009206#ifdef __APPLE__
9207 /* handle weak-linking on Mac OS X 10.3 */
9208 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009209 fd_specified("statvfs", path->fd);
9210 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009211 }
9212#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009213 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009214 }
9215 else
9216#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009217 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009218 Py_END_ALLOW_THREADS
9219
9220 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009221 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009222 }
9223
Larry Hastings2f936352014-08-05 14:04:04 +10009224 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009225}
Larry Hastings2f936352014-08-05 14:04:04 +10009226#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9227
Guido van Rossum94f6f721999-01-06 18:42:14 +00009228
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009229#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009230/*[clinic input]
9231os._getdiskusage
9232
9233 path: Py_UNICODE
9234
9235Return disk usage statistics about the given path as a (total, free) tuple.
9236[clinic start generated code]*/
9237
Larry Hastings2f936352014-08-05 14:04:04 +10009238static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009239os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9240/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009241{
9242 BOOL retval;
9243 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009244
9245 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009246 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009247 Py_END_ALLOW_THREADS
9248 if (retval == 0)
9249 return PyErr_SetFromWindowsErr(0);
9250
9251 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9252}
Larry Hastings2f936352014-08-05 14:04:04 +10009253#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009254
9255
Fred Drakec9680921999-12-13 16:37:25 +00009256/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9257 * It maps strings representing configuration variable names to
9258 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009259 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009260 * rarely-used constants. There are three separate tables that use
9261 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009262 *
9263 * This code is always included, even if none of the interfaces that
9264 * need it are included. The #if hackery needed to avoid it would be
9265 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009266 */
9267struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009268 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009269 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009270};
9271
Fred Drake12c6e2d1999-12-14 21:25:03 +00009272static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009273conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009274 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009275{
Christian Heimes217cfd12007-12-02 14:31:20 +00009276 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009277 int value = _PyLong_AsInt(arg);
9278 if (value == -1 && PyErr_Occurred())
9279 return 0;
9280 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009281 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009282 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009283 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009284 /* look up the value in the table using a binary search */
9285 size_t lo = 0;
9286 size_t mid;
9287 size_t hi = tablesize;
9288 int cmp;
9289 const char *confname;
9290 if (!PyUnicode_Check(arg)) {
9291 PyErr_SetString(PyExc_TypeError,
9292 "configuration names must be strings or integers");
9293 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009294 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009295 confname = _PyUnicode_AsString(arg);
9296 if (confname == NULL)
9297 return 0;
9298 while (lo < hi) {
9299 mid = (lo + hi) / 2;
9300 cmp = strcmp(confname, table[mid].name);
9301 if (cmp < 0)
9302 hi = mid;
9303 else if (cmp > 0)
9304 lo = mid + 1;
9305 else {
9306 *valuep = table[mid].value;
9307 return 1;
9308 }
9309 }
9310 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9311 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009312 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009313}
9314
9315
9316#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9317static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009318#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009319 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009320#endif
9321#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009323#endif
Fred Drakec9680921999-12-13 16:37:25 +00009324#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009325 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009326#endif
9327#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009329#endif
9330#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009332#endif
9333#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009335#endif
9336#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009337 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009338#endif
9339#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009341#endif
9342#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009344#endif
9345#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009347#endif
9348#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009349 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009350#endif
9351#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009353#endif
9354#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009356#endif
9357#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009358 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009359#endif
9360#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009361 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009362#endif
9363#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009365#endif
9366#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009368#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009369#ifdef _PC_ACL_ENABLED
9370 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9371#endif
9372#ifdef _PC_MIN_HOLE_SIZE
9373 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9374#endif
9375#ifdef _PC_ALLOC_SIZE_MIN
9376 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9377#endif
9378#ifdef _PC_REC_INCR_XFER_SIZE
9379 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9380#endif
9381#ifdef _PC_REC_MAX_XFER_SIZE
9382 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9383#endif
9384#ifdef _PC_REC_MIN_XFER_SIZE
9385 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9386#endif
9387#ifdef _PC_REC_XFER_ALIGN
9388 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9389#endif
9390#ifdef _PC_SYMLINK_MAX
9391 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9392#endif
9393#ifdef _PC_XATTR_ENABLED
9394 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9395#endif
9396#ifdef _PC_XATTR_EXISTS
9397 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9398#endif
9399#ifdef _PC_TIMESTAMP_RESOLUTION
9400 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9401#endif
Fred Drakec9680921999-12-13 16:37:25 +00009402};
9403
Fred Drakec9680921999-12-13 16:37:25 +00009404static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009405conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009406{
9407 return conv_confname(arg, valuep, posix_constants_pathconf,
9408 sizeof(posix_constants_pathconf)
9409 / sizeof(struct constdef));
9410}
9411#endif
9412
Larry Hastings2f936352014-08-05 14:04:04 +10009413
Fred Drakec9680921999-12-13 16:37:25 +00009414#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009415/*[clinic input]
9416os.fpathconf -> long
9417
9418 fd: int
9419 name: path_confname
9420 /
9421
9422Return the configuration limit name for the file descriptor fd.
9423
9424If there is no limit, return -1.
9425[clinic start generated code]*/
9426
Larry Hastings2f936352014-08-05 14:04:04 +10009427static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009428os_fpathconf_impl(PyObject *module, int fd, int name)
9429/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009430{
9431 long limit;
9432
9433 errno = 0;
9434 limit = fpathconf(fd, name);
9435 if (limit == -1 && errno != 0)
9436 posix_error();
9437
9438 return limit;
9439}
9440#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009441
9442
9443#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009444/*[clinic input]
9445os.pathconf -> long
9446 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9447 name: path_confname
9448
9449Return the configuration limit name for the file or directory path.
9450
9451If there is no limit, return -1.
9452On some platforms, path may also be specified as an open file descriptor.
9453 If this functionality is unavailable, using it raises an exception.
9454[clinic start generated code]*/
9455
Larry Hastings2f936352014-08-05 14:04:04 +10009456static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009457os_pathconf_impl(PyObject *module, path_t *path, int name)
9458/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009459{
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009461
Victor Stinner8c62be82010-05-06 00:08:46 +00009462 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009463#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009464 if (path->fd != -1)
9465 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009466 else
9467#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009468 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 if (limit == -1 && errno != 0) {
9470 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009471 /* could be a path or name problem */
9472 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009473 else
Larry Hastings2f936352014-08-05 14:04:04 +10009474 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 }
Larry Hastings2f936352014-08-05 14:04:04 +10009476
9477 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009478}
Larry Hastings2f936352014-08-05 14:04:04 +10009479#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009480
9481#ifdef HAVE_CONFSTR
9482static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009483#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009485#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009486#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009488#endif
9489#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009491#endif
Fred Draked86ed291999-12-15 15:34:33 +00009492#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009494#endif
9495#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009497#endif
9498#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009500#endif
9501#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009503#endif
Fred Drakec9680921999-12-13 16:37:25 +00009504#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009506#endif
9507#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009509#endif
9510#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
9513#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009515#endif
9516#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
9525#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009527#endif
Fred Draked86ed291999-12-15 15:34:33 +00009528#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009530#endif
Fred Drakec9680921999-12-13 16:37:25 +00009531#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009533#endif
Fred Draked86ed291999-12-15 15:34:33 +00009534#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
9537#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009539#endif
9540#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009542#endif
9543#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009545#endif
Fred Drakec9680921999-12-13 16:37:25 +00009546#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
Fred Draked86ed291999-12-15 15:34:33 +00009594#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009596#endif
9597#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009599#endif
9600#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009601 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009602#endif
9603#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009604 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009605#endif
9606#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009607 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009608#endif
9609#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009610 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009611#endif
9612#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009613 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009614#endif
9615#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009617#endif
9618#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009619 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009620#endif
9621#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009622 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009623#endif
9624#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009625 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009626#endif
9627#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009628 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009629#endif
9630#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009631 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009632#endif
Fred Drakec9680921999-12-13 16:37:25 +00009633};
9634
9635static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009636conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009637{
9638 return conv_confname(arg, valuep, posix_constants_confstr,
9639 sizeof(posix_constants_confstr)
9640 / sizeof(struct constdef));
9641}
9642
Larry Hastings2f936352014-08-05 14:04:04 +10009643
9644/*[clinic input]
9645os.confstr
9646
9647 name: confstr_confname
9648 /
9649
9650Return a string-valued system configuration variable.
9651[clinic start generated code]*/
9652
Larry Hastings2f936352014-08-05 14:04:04 +10009653static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009654os_confstr_impl(PyObject *module, int name)
9655/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009656{
9657 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009658 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009659 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009660
Victor Stinnercb043522010-09-10 23:49:04 +00009661 errno = 0;
9662 len = confstr(name, buffer, sizeof(buffer));
9663 if (len == 0) {
9664 if (errno) {
9665 posix_error();
9666 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009667 }
9668 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009669 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009670 }
9671 }
Victor Stinnercb043522010-09-10 23:49:04 +00009672
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009673 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009674 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009675 char *buf = PyMem_Malloc(len);
9676 if (buf == NULL)
9677 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009678 len2 = confstr(name, buf, len);
9679 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009680 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009681 PyMem_Free(buf);
9682 }
9683 else
9684 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009685 return result;
9686}
Larry Hastings2f936352014-08-05 14:04:04 +10009687#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009688
9689
9690#ifdef HAVE_SYSCONF
9691static struct constdef posix_constants_sysconf[] = {
9692#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
9695#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009697#endif
9698#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
9713#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009715#endif
9716#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
Fred Draked86ed291999-12-15 15:34:33 +00009722#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
9725#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
Fred Drakec9680921999-12-13 16:37:25 +00009728#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
Fred Drakec9680921999-12-13 16:37:25 +00009731#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
Fred Draked86ed291999-12-15 15:34:33 +00009746#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009748#endif
Fred Drakec9680921999-12-13 16:37:25 +00009749#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
Fred Draked86ed291999-12-15 15:34:33 +00009764#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009766#endif
Fred Drakec9680921999-12-13 16:37:25 +00009767#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
Fred Draked86ed291999-12-15 15:34:33 +00009836#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
Fred Drakec9680921999-12-13 16:37:25 +00009839#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
Fred Draked86ed291999-12-15 15:34:33 +00009848#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009850#endif
Fred Drakec9680921999-12-13 16:37:25 +00009851#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
Fred Draked86ed291999-12-15 15:34:33 +00009854#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009856#endif
9857#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009859#endif
Fred Drakec9680921999-12-13 16:37:25 +00009860#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
Fred Draked86ed291999-12-15 15:34:33 +00009872#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009874#endif
Fred Drakec9680921999-12-13 16:37:25 +00009875#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
9884#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009886#endif
9887#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009889#endif
9890#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
Fred Draked86ed291999-12-15 15:34:33 +00009896#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009898#endif
Fred Drakec9680921999-12-13 16:37:25 +00009899#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
Fred Draked86ed291999-12-15 15:34:33 +00009905#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009907#endif
Fred Drakec9680921999-12-13 16:37:25 +00009908#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
Fred Draked86ed291999-12-15 15:34:33 +00009935#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009937#endif
9938#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009940#endif
Fred Drakec9680921999-12-13 16:37:25 +00009941#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
Fred Draked86ed291999-12-15 15:34:33 +000010046#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010048#endif
Fred Drakec9680921999-12-13 16:37:25 +000010049#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184};
10185
10186static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010187conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010188{
10189 return conv_confname(arg, valuep, posix_constants_sysconf,
10190 sizeof(posix_constants_sysconf)
10191 / sizeof(struct constdef));
10192}
10193
Larry Hastings2f936352014-08-05 14:04:04 +100010194
10195/*[clinic input]
10196os.sysconf -> long
10197 name: sysconf_confname
10198 /
10199
10200Return an integer-valued system configuration variable.
10201[clinic start generated code]*/
10202
Larry Hastings2f936352014-08-05 14:04:04 +100010203static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010204os_sysconf_impl(PyObject *module, int name)
10205/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010206{
10207 long value;
10208
10209 errno = 0;
10210 value = sysconf(name);
10211 if (value == -1 && errno != 0)
10212 posix_error();
10213 return value;
10214}
10215#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010216
10217
Fred Drakebec628d1999-12-15 18:31:10 +000010218/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010219 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010220 * the exported dictionaries that are used to publish information about the
10221 * names available on the host platform.
10222 *
10223 * Sorting the table at runtime ensures that the table is properly ordered
10224 * when used, even for platforms we're not able to test on. It also makes
10225 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010226 */
Fred Drakebec628d1999-12-15 18:31:10 +000010227
10228static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010229cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010230{
10231 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010233 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010235
10236 return strcmp(c1->name, c2->name);
10237}
10238
10239static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010240setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010241 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010242{
Fred Drakebec628d1999-12-15 18:31:10 +000010243 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010244 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010245
10246 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10247 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010248 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010250
Barry Warsaw3155db32000-04-13 15:20:40 +000010251 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 PyObject *o = PyLong_FromLong(table[i].value);
10253 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10254 Py_XDECREF(o);
10255 Py_DECREF(d);
10256 return -1;
10257 }
10258 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010259 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010260 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010261}
10262
Fred Drakebec628d1999-12-15 18:31:10 +000010263/* Return -1 on failure, 0 on success. */
10264static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010265setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010266{
10267#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010268 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010269 sizeof(posix_constants_pathconf)
10270 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010271 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010272 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010273#endif
10274#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010275 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010276 sizeof(posix_constants_confstr)
10277 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010278 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010279 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010280#endif
10281#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010282 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010283 sizeof(posix_constants_sysconf)
10284 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010285 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010286 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010287#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010288 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010289}
Fred Draked86ed291999-12-15 15:34:33 +000010290
10291
Larry Hastings2f936352014-08-05 14:04:04 +100010292/*[clinic input]
10293os.abort
10294
10295Abort the interpreter immediately.
10296
10297This function 'dumps core' or otherwise fails in the hardest way possible
10298on the hosting operating system. This function never returns.
10299[clinic start generated code]*/
10300
Larry Hastings2f936352014-08-05 14:04:04 +100010301static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010302os_abort_impl(PyObject *module)
10303/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010304{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010305 abort();
10306 /*NOTREACHED*/
10307 Py_FatalError("abort() called from Python code didn't abort!");
10308 return NULL;
10309}
Fred Drakebec628d1999-12-15 18:31:10 +000010310
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010311#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010312/* Grab ShellExecute dynamically from shell32 */
10313static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010314static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10315 LPCWSTR, INT);
10316static int
10317check_ShellExecute()
10318{
10319 HINSTANCE hShell32;
10320
10321 /* only recheck */
10322 if (-1 == has_ShellExecute) {
10323 Py_BEGIN_ALLOW_THREADS
10324 hShell32 = LoadLibraryW(L"SHELL32");
10325 Py_END_ALLOW_THREADS
10326 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010327 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10328 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010329 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010330 } else {
10331 has_ShellExecute = 0;
10332 }
10333 }
10334 return has_ShellExecute;
10335}
10336
10337
Steve Dowercc16be82016-09-08 10:35:16 -070010338/*[clinic input]
10339os.startfile
10340 filepath: path_t
10341 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010342
Steve Dowercc16be82016-09-08 10:35:16 -070010343startfile(filepath [, operation])
10344
10345Start a file with its associated application.
10346
10347When "operation" is not specified or "open", this acts like
10348double-clicking the file in Explorer, or giving the file name as an
10349argument to the DOS "start" command: the file is opened with whatever
10350application (if any) its extension is associated.
10351When another "operation" is given, it specifies what should be done with
10352the file. A typical operation is "print".
10353
10354startfile returns as soon as the associated application is launched.
10355There is no option to wait for the application to close, and no way
10356to retrieve the application's exit status.
10357
10358The filepath is relative to the current directory. If you want to use
10359an absolute path, make sure the first character is not a slash ("/");
10360the underlying Win32 ShellExecute function doesn't work if it is.
10361[clinic start generated code]*/
10362
10363static PyObject *
10364os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10365/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10366{
10367 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010368
10369 if(!check_ShellExecute()) {
10370 /* If the OS doesn't have ShellExecute, return a
10371 NotImplementedError. */
10372 return PyErr_Format(PyExc_NotImplementedError,
10373 "startfile not available on this platform");
10374 }
10375
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010377 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010378 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 Py_END_ALLOW_THREADS
10380
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010382 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010383 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 }
Steve Dowercc16be82016-09-08 10:35:16 -070010385 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010386}
Larry Hastings2f936352014-08-05 14:04:04 +100010387#endif /* MS_WINDOWS */
10388
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010389
Martin v. Löwis438b5342002-12-27 10:16:42 +000010390#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010391/*[clinic input]
10392os.getloadavg
10393
10394Return average recent system load information.
10395
10396Return the number of processes in the system run queue averaged over
10397the last 1, 5, and 15 minutes as a tuple of three floats.
10398Raises OSError if the load average was unobtainable.
10399[clinic start generated code]*/
10400
Larry Hastings2f936352014-08-05 14:04:04 +100010401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010402os_getloadavg_impl(PyObject *module)
10403/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010404{
10405 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010406 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010407 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10408 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010409 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010410 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010411}
Larry Hastings2f936352014-08-05 14:04:04 +100010412#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010413
Larry Hastings2f936352014-08-05 14:04:04 +100010414
10415/*[clinic input]
10416os.device_encoding
10417 fd: int
10418
10419Return a string describing the encoding of a terminal's file descriptor.
10420
10421The file descriptor must be attached to a terminal.
10422If the device is not a terminal, return None.
10423[clinic start generated code]*/
10424
Larry Hastings2f936352014-08-05 14:04:04 +100010425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010426os_device_encoding_impl(PyObject *module, int fd)
10427/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010428{
Brett Cannonefb00c02012-02-29 18:31:31 -050010429 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010430}
10431
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010432
Larry Hastings2f936352014-08-05 14:04:04 +100010433#ifdef HAVE_SETRESUID
10434/*[clinic input]
10435os.setresuid
10436
10437 ruid: uid_t
10438 euid: uid_t
10439 suid: uid_t
10440 /
10441
10442Set the current process's real, effective, and saved user ids.
10443[clinic start generated code]*/
10444
Larry Hastings2f936352014-08-05 14:04:04 +100010445static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010446os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10447/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010448{
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 if (setresuid(ruid, euid, suid) < 0)
10450 return posix_error();
10451 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010452}
Larry Hastings2f936352014-08-05 14:04:04 +100010453#endif /* HAVE_SETRESUID */
10454
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010455
10456#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010457/*[clinic input]
10458os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010459
Larry Hastings2f936352014-08-05 14:04:04 +100010460 rgid: gid_t
10461 egid: gid_t
10462 sgid: gid_t
10463 /
10464
10465Set the current process's real, effective, and saved group ids.
10466[clinic start generated code]*/
10467
Larry Hastings2f936352014-08-05 14:04:04 +100010468static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010469os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10470/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010471{
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 if (setresgid(rgid, egid, sgid) < 0)
10473 return posix_error();
10474 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010475}
Larry Hastings2f936352014-08-05 14:04:04 +100010476#endif /* HAVE_SETRESGID */
10477
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010478
10479#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010480/*[clinic input]
10481os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010482
Larry Hastings2f936352014-08-05 14:04:04 +100010483Return a tuple of the current process's real, effective, and saved user ids.
10484[clinic start generated code]*/
10485
Larry Hastings2f936352014-08-05 14:04:04 +100010486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010487os_getresuid_impl(PyObject *module)
10488/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010489{
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010491 if (getresuid(&ruid, &euid, &suid) < 0)
10492 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010493 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10494 _PyLong_FromUid(euid),
10495 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010496}
Larry Hastings2f936352014-08-05 14:04:04 +100010497#endif /* HAVE_GETRESUID */
10498
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010499
10500#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010501/*[clinic input]
10502os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010503
Larry Hastings2f936352014-08-05 14:04:04 +100010504Return a tuple of the current process's real, effective, and saved group ids.
10505[clinic start generated code]*/
10506
Larry Hastings2f936352014-08-05 14:04:04 +100010507static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010508os_getresgid_impl(PyObject *module)
10509/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010510{
10511 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 if (getresgid(&rgid, &egid, &sgid) < 0)
10513 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010514 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10515 _PyLong_FromGid(egid),
10516 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010517}
Larry Hastings2f936352014-08-05 14:04:04 +100010518#endif /* HAVE_GETRESGID */
10519
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010520
Benjamin Peterson9428d532011-09-14 11:45:52 -040010521#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010522/*[clinic input]
10523os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010524
Larry Hastings2f936352014-08-05 14:04:04 +100010525 path: path_t(allow_fd=True)
10526 attribute: path_t
10527 *
10528 follow_symlinks: bool = True
10529
10530Return the value of extended attribute attribute on path.
10531
10532path may be either a string or an open file descriptor.
10533If follow_symlinks is False, and the last element of the path is a symbolic
10534 link, getxattr will examine the symbolic link itself instead of the file
10535 the link points to.
10536
10537[clinic start generated code]*/
10538
Larry Hastings2f936352014-08-05 14:04:04 +100010539static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010540os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010541 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010542/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010543{
10544 Py_ssize_t i;
10545 PyObject *buffer = NULL;
10546
10547 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10548 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010549
Larry Hastings9cf065c2012-06-22 16:30:09 -070010550 for (i = 0; ; i++) {
10551 void *ptr;
10552 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010553 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010554 Py_ssize_t buffer_size = buffer_sizes[i];
10555 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010556 path_error(path);
10557 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010558 }
10559 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10560 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010561 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010562 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010563
Larry Hastings9cf065c2012-06-22 16:30:09 -070010564 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010565 if (path->fd >= 0)
10566 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010567 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010568 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010569 else
Larry Hastings2f936352014-08-05 14:04:04 +100010570 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010571 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010572
Larry Hastings9cf065c2012-06-22 16:30:09 -070010573 if (result < 0) {
10574 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010575 if (errno == ERANGE)
10576 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010577 path_error(path);
10578 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010579 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010580
Larry Hastings9cf065c2012-06-22 16:30:09 -070010581 if (result != buffer_size) {
10582 /* Can only shrink. */
10583 _PyBytes_Resize(&buffer, result);
10584 }
10585 break;
10586 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010587
Larry Hastings9cf065c2012-06-22 16:30:09 -070010588 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010589}
10590
Larry Hastings2f936352014-08-05 14:04:04 +100010591
10592/*[clinic input]
10593os.setxattr
10594
10595 path: path_t(allow_fd=True)
10596 attribute: path_t
10597 value: Py_buffer
10598 flags: int = 0
10599 *
10600 follow_symlinks: bool = True
10601
10602Set extended attribute attribute on path to value.
10603
10604path may be either a string or an open file descriptor.
10605If follow_symlinks is False, and the last element of the path is a symbolic
10606 link, setxattr will modify the symbolic link itself instead of the file
10607 the link points to.
10608
10609[clinic start generated code]*/
10610
Benjamin Peterson799bd802011-08-31 22:15:17 -040010611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010612os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010613 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010614/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010615{
Larry Hastings2f936352014-08-05 14:04:04 +100010616 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010617
Larry Hastings2f936352014-08-05 14:04:04 +100010618 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010619 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010620
Benjamin Peterson799bd802011-08-31 22:15:17 -040010621 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010622 if (path->fd > -1)
10623 result = fsetxattr(path->fd, attribute->narrow,
10624 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010625 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010626 result = setxattr(path->narrow, attribute->narrow,
10627 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010628 else
Larry Hastings2f936352014-08-05 14:04:04 +100010629 result = lsetxattr(path->narrow, attribute->narrow,
10630 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010631 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010632
Larry Hastings9cf065c2012-06-22 16:30:09 -070010633 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010634 path_error(path);
10635 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010636 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010637
Larry Hastings2f936352014-08-05 14:04:04 +100010638 Py_RETURN_NONE;
10639}
10640
10641
10642/*[clinic input]
10643os.removexattr
10644
10645 path: path_t(allow_fd=True)
10646 attribute: path_t
10647 *
10648 follow_symlinks: bool = True
10649
10650Remove extended attribute attribute on path.
10651
10652path may be either a string or an open file descriptor.
10653If follow_symlinks is False, and the last element of the path is a symbolic
10654 link, removexattr will modify the symbolic link itself instead of the file
10655 the link points to.
10656
10657[clinic start generated code]*/
10658
Larry Hastings2f936352014-08-05 14:04:04 +100010659static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010660os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010661 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010662/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010663{
10664 ssize_t result;
10665
10666 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10667 return NULL;
10668
10669 Py_BEGIN_ALLOW_THREADS;
10670 if (path->fd > -1)
10671 result = fremovexattr(path->fd, attribute->narrow);
10672 else if (follow_symlinks)
10673 result = removexattr(path->narrow, attribute->narrow);
10674 else
10675 result = lremovexattr(path->narrow, attribute->narrow);
10676 Py_END_ALLOW_THREADS;
10677
10678 if (result) {
10679 return path_error(path);
10680 }
10681
10682 Py_RETURN_NONE;
10683}
10684
10685
10686/*[clinic input]
10687os.listxattr
10688
10689 path: path_t(allow_fd=True, nullable=True) = None
10690 *
10691 follow_symlinks: bool = True
10692
10693Return a list of extended attributes on path.
10694
10695path may be either None, a string, or an open file descriptor.
10696if path is None, listxattr will examine the current directory.
10697If follow_symlinks is False, and the last element of the path is a symbolic
10698 link, listxattr will examine the symbolic link itself instead of the file
10699 the link points to.
10700[clinic start generated code]*/
10701
Larry Hastings2f936352014-08-05 14:04:04 +100010702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010703os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10704/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010705{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010706 Py_ssize_t i;
10707 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010708 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010709 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010710
Larry Hastings2f936352014-08-05 14:04:04 +100010711 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010712 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010713
Larry Hastings2f936352014-08-05 14:04:04 +100010714 name = path->narrow ? path->narrow : ".";
10715
Larry Hastings9cf065c2012-06-22 16:30:09 -070010716 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010717 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010718 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010719 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010720 Py_ssize_t buffer_size = buffer_sizes[i];
10721 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010722 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010723 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010724 break;
10725 }
10726 buffer = PyMem_MALLOC(buffer_size);
10727 if (!buffer) {
10728 PyErr_NoMemory();
10729 break;
10730 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010731
Larry Hastings9cf065c2012-06-22 16:30:09 -070010732 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010733 if (path->fd > -1)
10734 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010735 else if (follow_symlinks)
10736 length = listxattr(name, buffer, buffer_size);
10737 else
10738 length = llistxattr(name, buffer, buffer_size);
10739 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010740
Larry Hastings9cf065c2012-06-22 16:30:09 -070010741 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010742 if (errno == ERANGE) {
10743 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010744 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010745 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010746 }
Larry Hastings2f936352014-08-05 14:04:04 +100010747 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010748 break;
10749 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010750
Larry Hastings9cf065c2012-06-22 16:30:09 -070010751 result = PyList_New(0);
10752 if (!result) {
10753 goto exit;
10754 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010755
Larry Hastings9cf065c2012-06-22 16:30:09 -070010756 end = buffer + length;
10757 for (trace = start = buffer; trace != end; trace++) {
10758 if (!*trace) {
10759 int error;
10760 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10761 trace - start);
10762 if (!attribute) {
10763 Py_DECREF(result);
10764 result = NULL;
10765 goto exit;
10766 }
10767 error = PyList_Append(result, attribute);
10768 Py_DECREF(attribute);
10769 if (error) {
10770 Py_DECREF(result);
10771 result = NULL;
10772 goto exit;
10773 }
10774 start = trace + 1;
10775 }
10776 }
10777 break;
10778 }
10779exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010780 if (buffer)
10781 PyMem_FREE(buffer);
10782 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010783}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010784#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010785
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010786
Larry Hastings2f936352014-08-05 14:04:04 +100010787/*[clinic input]
10788os.urandom
10789
10790 size: Py_ssize_t
10791 /
10792
10793Return a bytes object containing random bytes suitable for cryptographic use.
10794[clinic start generated code]*/
10795
Larry Hastings2f936352014-08-05 14:04:04 +100010796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010797os_urandom_impl(PyObject *module, Py_ssize_t size)
10798/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010799{
10800 PyObject *bytes;
10801 int result;
10802
Georg Brandl2fb477c2012-02-21 00:33:36 +010010803 if (size < 0)
10804 return PyErr_Format(PyExc_ValueError,
10805 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010806 bytes = PyBytes_FromStringAndSize(NULL, size);
10807 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010808 return NULL;
10809
Victor Stinnere66987e2016-09-06 16:33:52 -070010810 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010811 if (result == -1) {
10812 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010813 return NULL;
10814 }
Larry Hastings2f936352014-08-05 14:04:04 +100010815 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010816}
10817
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010818/* Terminal size querying */
10819
10820static PyTypeObject TerminalSizeType;
10821
10822PyDoc_STRVAR(TerminalSize_docstring,
10823 "A tuple of (columns, lines) for holding terminal window size");
10824
10825static PyStructSequence_Field TerminalSize_fields[] = {
10826 {"columns", "width of the terminal window in characters"},
10827 {"lines", "height of the terminal window in characters"},
10828 {NULL, NULL}
10829};
10830
10831static PyStructSequence_Desc TerminalSize_desc = {
10832 "os.terminal_size",
10833 TerminalSize_docstring,
10834 TerminalSize_fields,
10835 2,
10836};
10837
10838#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010839/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010840PyDoc_STRVAR(termsize__doc__,
10841 "Return the size of the terminal window as (columns, lines).\n" \
10842 "\n" \
10843 "The optional argument fd (default standard output) specifies\n" \
10844 "which file descriptor should be queried.\n" \
10845 "\n" \
10846 "If the file descriptor is not connected to a terminal, an OSError\n" \
10847 "is thrown.\n" \
10848 "\n" \
10849 "This function will only be defined if an implementation is\n" \
10850 "available for this system.\n" \
10851 "\n" \
10852 "shutil.get_terminal_size is the high-level function which should \n" \
10853 "normally be used, os.get_terminal_size is the low-level implementation.");
10854
10855static PyObject*
10856get_terminal_size(PyObject *self, PyObject *args)
10857{
10858 int columns, lines;
10859 PyObject *termsize;
10860
10861 int fd = fileno(stdout);
10862 /* Under some conditions stdout may not be connected and
10863 * fileno(stdout) may point to an invalid file descriptor. For example
10864 * GUI apps don't have valid standard streams by default.
10865 *
10866 * If this happens, and the optional fd argument is not present,
10867 * the ioctl below will fail returning EBADF. This is what we want.
10868 */
10869
10870 if (!PyArg_ParseTuple(args, "|i", &fd))
10871 return NULL;
10872
10873#ifdef TERMSIZE_USE_IOCTL
10874 {
10875 struct winsize w;
10876 if (ioctl(fd, TIOCGWINSZ, &w))
10877 return PyErr_SetFromErrno(PyExc_OSError);
10878 columns = w.ws_col;
10879 lines = w.ws_row;
10880 }
10881#endif /* TERMSIZE_USE_IOCTL */
10882
10883#ifdef TERMSIZE_USE_CONIO
10884 {
10885 DWORD nhandle;
10886 HANDLE handle;
10887 CONSOLE_SCREEN_BUFFER_INFO csbi;
10888 switch (fd) {
10889 case 0: nhandle = STD_INPUT_HANDLE;
10890 break;
10891 case 1: nhandle = STD_OUTPUT_HANDLE;
10892 break;
10893 case 2: nhandle = STD_ERROR_HANDLE;
10894 break;
10895 default:
10896 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10897 }
10898 handle = GetStdHandle(nhandle);
10899 if (handle == NULL)
10900 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10901 if (handle == INVALID_HANDLE_VALUE)
10902 return PyErr_SetFromWindowsErr(0);
10903
10904 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10905 return PyErr_SetFromWindowsErr(0);
10906
10907 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10908 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10909 }
10910#endif /* TERMSIZE_USE_CONIO */
10911
10912 termsize = PyStructSequence_New(&TerminalSizeType);
10913 if (termsize == NULL)
10914 return NULL;
10915 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10916 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10917 if (PyErr_Occurred()) {
10918 Py_DECREF(termsize);
10919 return NULL;
10920 }
10921 return termsize;
10922}
10923#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10924
Larry Hastings2f936352014-08-05 14:04:04 +100010925
10926/*[clinic input]
10927os.cpu_count
10928
Charles-François Natali80d62e62015-08-13 20:37:08 +010010929Return the number of CPUs in the system; return None if indeterminable.
10930
10931This number is not equivalent to the number of CPUs the current process can
10932use. The number of usable CPUs can be obtained with
10933``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010934[clinic start generated code]*/
10935
Larry Hastings2f936352014-08-05 14:04:04 +100010936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010937os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010938/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010939{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010940 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010941#ifdef MS_WINDOWS
10942 SYSTEM_INFO sysinfo;
10943 GetSystemInfo(&sysinfo);
10944 ncpu = sysinfo.dwNumberOfProcessors;
10945#elif defined(__hpux)
10946 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10947#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10948 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010949#elif defined(__DragonFly__) || \
10950 defined(__OpenBSD__) || \
10951 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010952 defined(__NetBSD__) || \
10953 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010954 int mib[2];
10955 size_t len = sizeof(ncpu);
10956 mib[0] = CTL_HW;
10957 mib[1] = HW_NCPU;
10958 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10959 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010960#endif
10961 if (ncpu >= 1)
10962 return PyLong_FromLong(ncpu);
10963 else
10964 Py_RETURN_NONE;
10965}
10966
Victor Stinnerdaf45552013-08-28 00:53:59 +020010967
Larry Hastings2f936352014-08-05 14:04:04 +100010968/*[clinic input]
10969os.get_inheritable -> bool
10970
10971 fd: int
10972 /
10973
10974Get the close-on-exe flag of the specified file descriptor.
10975[clinic start generated code]*/
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010978os_get_inheritable_impl(PyObject *module, int fd)
10979/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010980{
Steve Dower8fc89802015-04-12 00:26:27 -040010981 int return_value;
10982 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100010983 posix_error();
10984 return -1;
10985 }
10986
Steve Dower8fc89802015-04-12 00:26:27 -040010987 _Py_BEGIN_SUPPRESS_IPH
10988 return_value = _Py_get_inheritable(fd);
10989 _Py_END_SUPPRESS_IPH
10990 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010991}
10992
10993
10994/*[clinic input]
10995os.set_inheritable
10996 fd: int
10997 inheritable: int
10998 /
10999
11000Set the inheritable flag of the specified file descriptor.
11001[clinic start generated code]*/
11002
Larry Hastings2f936352014-08-05 14:04:04 +100011003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011004os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11005/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011006{
Steve Dower8fc89802015-04-12 00:26:27 -040011007 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011008 if (!_PyVerify_fd(fd))
11009 return posix_error();
11010
Steve Dower8fc89802015-04-12 00:26:27 -040011011 _Py_BEGIN_SUPPRESS_IPH
11012 result = _Py_set_inheritable(fd, inheritable, NULL);
11013 _Py_END_SUPPRESS_IPH
11014 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011015 return NULL;
11016 Py_RETURN_NONE;
11017}
11018
11019
11020#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011021/*[clinic input]
11022os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070011023 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011024 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011025
Larry Hastings2f936352014-08-05 14:04:04 +100011026Get the close-on-exe flag of the specified file descriptor.
11027[clinic start generated code]*/
11028
Larry Hastings2f936352014-08-05 14:04:04 +100011029static int
Benjamin Petersonca470632016-09-06 13:47:26 -070011030os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070011031/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011032{
11033 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011034
11035 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11036 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011037 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011038 }
11039
Larry Hastings2f936352014-08-05 14:04:04 +100011040 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011041}
11042
Victor Stinnerdaf45552013-08-28 00:53:59 +020011043
Larry Hastings2f936352014-08-05 14:04:04 +100011044/*[clinic input]
11045os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070011046 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100011047 inheritable: bool
11048 /
11049
11050Set the inheritable flag of the specified handle.
11051[clinic start generated code]*/
11052
Larry Hastings2f936352014-08-05 14:04:04 +100011053static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070011054os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011055 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070011056/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011057{
11058 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011059 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11060 PyErr_SetFromWindowsErr(0);
11061 return NULL;
11062 }
11063 Py_RETURN_NONE;
11064}
Larry Hastings2f936352014-08-05 14:04:04 +100011065#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011066
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011067#ifndef MS_WINDOWS
11068PyDoc_STRVAR(get_blocking__doc__,
11069 "get_blocking(fd) -> bool\n" \
11070 "\n" \
11071 "Get the blocking mode of the file descriptor:\n" \
11072 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11073
11074static PyObject*
11075posix_get_blocking(PyObject *self, PyObject *args)
11076{
11077 int fd;
11078 int blocking;
11079
11080 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11081 return NULL;
11082
11083 if (!_PyVerify_fd(fd))
11084 return posix_error();
11085
Steve Dower8fc89802015-04-12 00:26:27 -040011086 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011087 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011088 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011089 if (blocking < 0)
11090 return NULL;
11091 return PyBool_FromLong(blocking);
11092}
11093
11094PyDoc_STRVAR(set_blocking__doc__,
11095 "set_blocking(fd, blocking)\n" \
11096 "\n" \
11097 "Set the blocking mode of the specified file descriptor.\n" \
11098 "Set the O_NONBLOCK flag if blocking is False,\n" \
11099 "clear the O_NONBLOCK flag otherwise.");
11100
11101static PyObject*
11102posix_set_blocking(PyObject *self, PyObject *args)
11103{
Steve Dower8fc89802015-04-12 00:26:27 -040011104 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011105
11106 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11107 return NULL;
11108
11109 if (!_PyVerify_fd(fd))
11110 return posix_error();
11111
Steve Dower8fc89802015-04-12 00:26:27 -040011112 _Py_BEGIN_SUPPRESS_IPH
11113 result = _Py_set_blocking(fd, blocking);
11114 _Py_END_SUPPRESS_IPH
11115 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011116 return NULL;
11117 Py_RETURN_NONE;
11118}
11119#endif /* !MS_WINDOWS */
11120
11121
Victor Stinner6036e442015-03-08 01:58:04 +010011122PyDoc_STRVAR(posix_scandir__doc__,
11123"scandir(path='.') -> iterator of DirEntry objects for given path");
11124
11125static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11126
11127typedef struct {
11128 PyObject_HEAD
11129 PyObject *name;
11130 PyObject *path;
11131 PyObject *stat;
11132 PyObject *lstat;
11133#ifdef MS_WINDOWS
11134 struct _Py_stat_struct win32_lstat;
11135 __int64 win32_file_index;
11136 int got_file_index;
11137#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011138#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011139 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011140#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011141 ino_t d_ino;
11142#endif
11143} DirEntry;
11144
11145static void
11146DirEntry_dealloc(DirEntry *entry)
11147{
11148 Py_XDECREF(entry->name);
11149 Py_XDECREF(entry->path);
11150 Py_XDECREF(entry->stat);
11151 Py_XDECREF(entry->lstat);
11152 Py_TYPE(entry)->tp_free((PyObject *)entry);
11153}
11154
11155/* Forward reference */
11156static int
11157DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11158
11159/* Set exception and return -1 on error, 0 for False, 1 for True */
11160static int
11161DirEntry_is_symlink(DirEntry *self)
11162{
11163#ifdef MS_WINDOWS
11164 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011165#elif defined(HAVE_DIRENT_D_TYPE)
11166 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011167 if (self->d_type != DT_UNKNOWN)
11168 return self->d_type == DT_LNK;
11169 else
11170 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011171#else
11172 /* POSIX without d_type */
11173 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011174#endif
11175}
11176
11177static PyObject *
11178DirEntry_py_is_symlink(DirEntry *self)
11179{
11180 int result;
11181
11182 result = DirEntry_is_symlink(self);
11183 if (result == -1)
11184 return NULL;
11185 return PyBool_FromLong(result);
11186}
11187
11188static PyObject *
11189DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11190{
11191 int result;
11192 struct _Py_stat_struct st;
11193
11194#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011195 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011196
11197 path = PyUnicode_AsUnicode(self->path);
11198 if (!path)
11199 return NULL;
11200
11201 if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -070011202 result = win32_stat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011203 else
Steve Dowercc16be82016-09-08 10:35:16 -070011204 result = win32_lstat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011205
11206 if (result != 0) {
11207 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11208 0, self->path);
11209 }
11210#else /* POSIX */
11211 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011212 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011213
11214 if (!PyUnicode_FSConverter(self->path, &bytes))
11215 return NULL;
11216 path = PyBytes_AS_STRING(bytes);
11217
11218 if (follow_symlinks)
11219 result = STAT(path, &st);
11220 else
11221 result = LSTAT(path, &st);
11222 Py_DECREF(bytes);
11223
11224 if (result != 0)
11225 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11226#endif
11227
11228 return _pystat_fromstructstat(&st);
11229}
11230
11231static PyObject *
11232DirEntry_get_lstat(DirEntry *self)
11233{
11234 if (!self->lstat) {
11235#ifdef MS_WINDOWS
11236 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11237#else /* POSIX */
11238 self->lstat = DirEntry_fetch_stat(self, 0);
11239#endif
11240 }
11241 Py_XINCREF(self->lstat);
11242 return self->lstat;
11243}
11244
11245static PyObject *
11246DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11247{
11248 if (!follow_symlinks)
11249 return DirEntry_get_lstat(self);
11250
11251 if (!self->stat) {
11252 int result = DirEntry_is_symlink(self);
11253 if (result == -1)
11254 return NULL;
11255 else if (result)
11256 self->stat = DirEntry_fetch_stat(self, 1);
11257 else
11258 self->stat = DirEntry_get_lstat(self);
11259 }
11260
11261 Py_XINCREF(self->stat);
11262 return self->stat;
11263}
11264
11265static PyObject *
11266DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11267{
11268 int follow_symlinks = 1;
11269
11270 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11271 follow_symlinks_keywords, &follow_symlinks))
11272 return NULL;
11273
11274 return DirEntry_get_stat(self, follow_symlinks);
11275}
11276
11277/* Set exception and return -1 on error, 0 for False, 1 for True */
11278static int
11279DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11280{
11281 PyObject *stat = NULL;
11282 PyObject *st_mode = NULL;
11283 long mode;
11284 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011285#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011286 int is_symlink;
11287 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011288#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011289#ifdef MS_WINDOWS
11290 unsigned long dir_bits;
11291#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011292 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011293
11294#ifdef MS_WINDOWS
11295 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11296 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011297#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011298 is_symlink = self->d_type == DT_LNK;
11299 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11300#endif
11301
Victor Stinner35a97c02015-03-08 02:59:09 +010011302#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011303 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011304#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011305 stat = DirEntry_get_stat(self, follow_symlinks);
11306 if (!stat) {
11307 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11308 /* If file doesn't exist (anymore), then return False
11309 (i.e., say it's not a file/directory) */
11310 PyErr_Clear();
11311 return 0;
11312 }
11313 goto error;
11314 }
11315 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11316 if (!st_mode)
11317 goto error;
11318
11319 mode = PyLong_AsLong(st_mode);
11320 if (mode == -1 && PyErr_Occurred())
11321 goto error;
11322 Py_CLEAR(st_mode);
11323 Py_CLEAR(stat);
11324 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011325#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011326 }
11327 else if (is_symlink) {
11328 assert(mode_bits != S_IFLNK);
11329 result = 0;
11330 }
11331 else {
11332 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11333#ifdef MS_WINDOWS
11334 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11335 if (mode_bits == S_IFDIR)
11336 result = dir_bits != 0;
11337 else
11338 result = dir_bits == 0;
11339#else /* POSIX */
11340 if (mode_bits == S_IFDIR)
11341 result = self->d_type == DT_DIR;
11342 else
11343 result = self->d_type == DT_REG;
11344#endif
11345 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011346#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011347
11348 return result;
11349
11350error:
11351 Py_XDECREF(st_mode);
11352 Py_XDECREF(stat);
11353 return -1;
11354}
11355
11356static PyObject *
11357DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11358{
11359 int result;
11360
11361 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11362 if (result == -1)
11363 return NULL;
11364 return PyBool_FromLong(result);
11365}
11366
11367static PyObject *
11368DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11369{
11370 int follow_symlinks = 1;
11371
11372 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11373 follow_symlinks_keywords, &follow_symlinks))
11374 return NULL;
11375
11376 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11377}
11378
11379static PyObject *
11380DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11381{
11382 int follow_symlinks = 1;
11383
11384 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11385 follow_symlinks_keywords, &follow_symlinks))
11386 return NULL;
11387
11388 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11389}
11390
11391static PyObject *
11392DirEntry_inode(DirEntry *self)
11393{
11394#ifdef MS_WINDOWS
11395 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011396 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011397 struct _Py_stat_struct stat;
11398
11399 path = PyUnicode_AsUnicode(self->path);
11400 if (!path)
11401 return NULL;
11402
Steve Dowercc16be82016-09-08 10:35:16 -070011403 if (win32_lstat(path, &stat) != 0) {
Victor Stinner6036e442015-03-08 01:58:04 +010011404 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11405 0, self->path);
11406 }
11407
11408 self->win32_file_index = stat.st_ino;
11409 self->got_file_index = 1;
11410 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011411 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011412#else /* POSIX */
11413#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011414 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011415#else
11416 return PyLong_FromLong((long)self->d_ino);
11417#endif
11418#endif
11419}
11420
11421static PyObject *
11422DirEntry_repr(DirEntry *self)
11423{
11424 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11425}
11426
Brett Cannon96881cd2016-06-10 14:37:21 -070011427static PyObject *
11428DirEntry_fspath(DirEntry *self)
11429{
11430 Py_INCREF(self->path);
11431 return self->path;
11432}
11433
Victor Stinner6036e442015-03-08 01:58:04 +010011434static PyMemberDef DirEntry_members[] = {
11435 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11436 "the entry's base filename, relative to scandir() \"path\" argument"},
11437 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11438 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11439 {NULL}
11440};
11441
11442static PyMethodDef DirEntry_methods[] = {
11443 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11444 "return True if the entry is a directory; cached per entry"
11445 },
11446 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11447 "return True if the entry is a file; cached per entry"
11448 },
11449 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11450 "return True if the entry is a symbolic link; cached per entry"
11451 },
11452 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11453 "return stat_result object for the entry; cached per entry"
11454 },
11455 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11456 "return inode of the entry; cached per entry",
11457 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011458 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11459 "returns the path for the entry",
11460 },
Victor Stinner6036e442015-03-08 01:58:04 +010011461 {NULL}
11462};
11463
Benjamin Peterson5646de42015-04-12 17:56:34 -040011464static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011465 PyVarObject_HEAD_INIT(NULL, 0)
11466 MODNAME ".DirEntry", /* tp_name */
11467 sizeof(DirEntry), /* tp_basicsize */
11468 0, /* tp_itemsize */
11469 /* methods */
11470 (destructor)DirEntry_dealloc, /* tp_dealloc */
11471 0, /* tp_print */
11472 0, /* tp_getattr */
11473 0, /* tp_setattr */
11474 0, /* tp_compare */
11475 (reprfunc)DirEntry_repr, /* tp_repr */
11476 0, /* tp_as_number */
11477 0, /* tp_as_sequence */
11478 0, /* tp_as_mapping */
11479 0, /* tp_hash */
11480 0, /* tp_call */
11481 0, /* tp_str */
11482 0, /* tp_getattro */
11483 0, /* tp_setattro */
11484 0, /* tp_as_buffer */
11485 Py_TPFLAGS_DEFAULT, /* tp_flags */
11486 0, /* tp_doc */
11487 0, /* tp_traverse */
11488 0, /* tp_clear */
11489 0, /* tp_richcompare */
11490 0, /* tp_weaklistoffset */
11491 0, /* tp_iter */
11492 0, /* tp_iternext */
11493 DirEntry_methods, /* tp_methods */
11494 DirEntry_members, /* tp_members */
11495};
11496
11497#ifdef MS_WINDOWS
11498
11499static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011500join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011501{
11502 Py_ssize_t path_len;
11503 Py_ssize_t size;
11504 wchar_t *result;
11505 wchar_t ch;
11506
11507 if (!path_wide) { /* Default arg: "." */
11508 path_wide = L".";
11509 path_len = 1;
11510 }
11511 else {
11512 path_len = wcslen(path_wide);
11513 }
11514
11515 /* The +1's are for the path separator and the NUL */
11516 size = path_len + 1 + wcslen(filename) + 1;
11517 result = PyMem_New(wchar_t, size);
11518 if (!result) {
11519 PyErr_NoMemory();
11520 return NULL;
11521 }
11522 wcscpy(result, path_wide);
11523 if (path_len > 0) {
11524 ch = result[path_len - 1];
11525 if (ch != SEP && ch != ALTSEP && ch != L':')
11526 result[path_len++] = SEP;
11527 wcscpy(result + path_len, filename);
11528 }
11529 return result;
11530}
11531
11532static PyObject *
11533DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11534{
11535 DirEntry *entry;
11536 BY_HANDLE_FILE_INFORMATION file_info;
11537 ULONG reparse_tag;
11538 wchar_t *joined_path;
11539
11540 entry = PyObject_New(DirEntry, &DirEntryType);
11541 if (!entry)
11542 return NULL;
11543 entry->name = NULL;
11544 entry->path = NULL;
11545 entry->stat = NULL;
11546 entry->lstat = NULL;
11547 entry->got_file_index = 0;
11548
11549 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11550 if (!entry->name)
11551 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011552 if (path->narrow) {
11553 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11554 if (!entry->name)
11555 goto error;
11556 }
Victor Stinner6036e442015-03-08 01:58:04 +010011557
11558 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11559 if (!joined_path)
11560 goto error;
11561
11562 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11563 PyMem_Free(joined_path);
11564 if (!entry->path)
11565 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011566 if (path->narrow) {
11567 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11568 if (!entry->path)
11569 goto error;
11570 }
Victor Stinner6036e442015-03-08 01:58:04 +010011571
Steve Dowercc16be82016-09-08 10:35:16 -070011572 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011573 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11574
11575 return (PyObject *)entry;
11576
11577error:
11578 Py_DECREF(entry);
11579 return NULL;
11580}
11581
11582#else /* POSIX */
11583
11584static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011585join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011586{
11587 Py_ssize_t path_len;
11588 Py_ssize_t size;
11589 char *result;
11590
11591 if (!path_narrow) { /* Default arg: "." */
11592 path_narrow = ".";
11593 path_len = 1;
11594 }
11595 else {
11596 path_len = strlen(path_narrow);
11597 }
11598
11599 if (filename_len == -1)
11600 filename_len = strlen(filename);
11601
11602 /* The +1's are for the path separator and the NUL */
11603 size = path_len + 1 + filename_len + 1;
11604 result = PyMem_New(char, size);
11605 if (!result) {
11606 PyErr_NoMemory();
11607 return NULL;
11608 }
11609 strcpy(result, path_narrow);
11610 if (path_len > 0 && result[path_len - 1] != '/')
11611 result[path_len++] = '/';
11612 strcpy(result + path_len, filename);
11613 return result;
11614}
11615
11616static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011617DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011618 ino_t d_ino
11619#ifdef HAVE_DIRENT_D_TYPE
11620 , unsigned char d_type
11621#endif
11622 )
Victor Stinner6036e442015-03-08 01:58:04 +010011623{
11624 DirEntry *entry;
11625 char *joined_path;
11626
11627 entry = PyObject_New(DirEntry, &DirEntryType);
11628 if (!entry)
11629 return NULL;
11630 entry->name = NULL;
11631 entry->path = NULL;
11632 entry->stat = NULL;
11633 entry->lstat = NULL;
11634
11635 joined_path = join_path_filename(path->narrow, name, name_len);
11636 if (!joined_path)
11637 goto error;
11638
11639 if (!path->narrow || !PyBytes_Check(path->object)) {
11640 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11641 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11642 }
11643 else {
11644 entry->name = PyBytes_FromStringAndSize(name, name_len);
11645 entry->path = PyBytes_FromString(joined_path);
11646 }
11647 PyMem_Free(joined_path);
11648 if (!entry->name || !entry->path)
11649 goto error;
11650
Victor Stinner35a97c02015-03-08 02:59:09 +010011651#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011652 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011653#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011654 entry->d_ino = d_ino;
11655
11656 return (PyObject *)entry;
11657
11658error:
11659 Py_XDECREF(entry);
11660 return NULL;
11661}
11662
11663#endif
11664
11665
11666typedef struct {
11667 PyObject_HEAD
11668 path_t path;
11669#ifdef MS_WINDOWS
11670 HANDLE handle;
11671 WIN32_FIND_DATAW file_data;
11672 int first_time;
11673#else /* POSIX */
11674 DIR *dirp;
11675#endif
11676} ScandirIterator;
11677
11678#ifdef MS_WINDOWS
11679
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011680static int
11681ScandirIterator_is_closed(ScandirIterator *iterator)
11682{
11683 return iterator->handle == INVALID_HANDLE_VALUE;
11684}
11685
Victor Stinner6036e442015-03-08 01:58:04 +010011686static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011687ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011688{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011689 HANDLE handle = iterator->handle;
11690
11691 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011692 return;
11693
Victor Stinner6036e442015-03-08 01:58:04 +010011694 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011695 Py_BEGIN_ALLOW_THREADS
11696 FindClose(handle);
11697 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011698}
11699
11700static PyObject *
11701ScandirIterator_iternext(ScandirIterator *iterator)
11702{
11703 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11704 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011705 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011706
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011707 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011708 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011709 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011710
11711 while (1) {
11712 if (!iterator->first_time) {
11713 Py_BEGIN_ALLOW_THREADS
11714 success = FindNextFileW(iterator->handle, file_data);
11715 Py_END_ALLOW_THREADS
11716 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011717 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011718 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011719 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011720 break;
11721 }
11722 }
11723 iterator->first_time = 0;
11724
11725 /* Skip over . and .. */
11726 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011727 wcscmp(file_data->cFileName, L"..") != 0) {
11728 entry = DirEntry_from_find_data(&iterator->path, file_data);
11729 if (!entry)
11730 break;
11731 return entry;
11732 }
Victor Stinner6036e442015-03-08 01:58:04 +010011733
11734 /* Loop till we get a non-dot directory or finish iterating */
11735 }
11736
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011737 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011738 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011739 return NULL;
11740}
11741
11742#else /* POSIX */
11743
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011744static int
11745ScandirIterator_is_closed(ScandirIterator *iterator)
11746{
11747 return !iterator->dirp;
11748}
11749
Victor Stinner6036e442015-03-08 01:58:04 +010011750static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011751ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011752{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011753 DIR *dirp = iterator->dirp;
11754
11755 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011756 return;
11757
Victor Stinner6036e442015-03-08 01:58:04 +010011758 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011759 Py_BEGIN_ALLOW_THREADS
11760 closedir(dirp);
11761 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011762 return;
11763}
11764
11765static PyObject *
11766ScandirIterator_iternext(ScandirIterator *iterator)
11767{
11768 struct dirent *direntp;
11769 Py_ssize_t name_len;
11770 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011771 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011772
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011773 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011774 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011775 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011776
11777 while (1) {
11778 errno = 0;
11779 Py_BEGIN_ALLOW_THREADS
11780 direntp = readdir(iterator->dirp);
11781 Py_END_ALLOW_THREADS
11782
11783 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011784 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011785 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011786 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011787 break;
11788 }
11789
11790 /* Skip over . and .. */
11791 name_len = NAMLEN(direntp);
11792 is_dot = direntp->d_name[0] == '.' &&
11793 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11794 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011795 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011796 name_len, direntp->d_ino
11797#ifdef HAVE_DIRENT_D_TYPE
11798 , direntp->d_type
11799#endif
11800 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011801 if (!entry)
11802 break;
11803 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011804 }
11805
11806 /* Loop till we get a non-dot directory or finish iterating */
11807 }
11808
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011809 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011810 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011811 return NULL;
11812}
11813
11814#endif
11815
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011816static PyObject *
11817ScandirIterator_close(ScandirIterator *self, PyObject *args)
11818{
11819 ScandirIterator_closedir(self);
11820 Py_RETURN_NONE;
11821}
11822
11823static PyObject *
11824ScandirIterator_enter(PyObject *self, PyObject *args)
11825{
11826 Py_INCREF(self);
11827 return self;
11828}
11829
11830static PyObject *
11831ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11832{
11833 ScandirIterator_closedir(self);
11834 Py_RETURN_NONE;
11835}
11836
Victor Stinner6036e442015-03-08 01:58:04 +010011837static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011838ScandirIterator_finalize(ScandirIterator *iterator)
11839{
11840 PyObject *error_type, *error_value, *error_traceback;
11841
11842 /* Save the current exception, if any. */
11843 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11844
11845 if (!ScandirIterator_is_closed(iterator)) {
11846 ScandirIterator_closedir(iterator);
11847
11848 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11849 "unclosed scandir iterator %R", iterator)) {
11850 /* Spurious errors can appear at shutdown */
11851 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11852 PyErr_WriteUnraisable((PyObject *) iterator);
11853 }
11854 }
11855 }
11856
11857 Py_CLEAR(iterator->path.object);
11858 path_cleanup(&iterator->path);
11859
11860 /* Restore the saved exception. */
11861 PyErr_Restore(error_type, error_value, error_traceback);
11862}
11863
11864static void
Victor Stinner6036e442015-03-08 01:58:04 +010011865ScandirIterator_dealloc(ScandirIterator *iterator)
11866{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011867 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11868 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011869
Victor Stinner6036e442015-03-08 01:58:04 +010011870 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11871}
11872
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011873static PyMethodDef ScandirIterator_methods[] = {
11874 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11875 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11876 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11877 {NULL}
11878};
11879
Benjamin Peterson5646de42015-04-12 17:56:34 -040011880static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011881 PyVarObject_HEAD_INIT(NULL, 0)
11882 MODNAME ".ScandirIterator", /* tp_name */
11883 sizeof(ScandirIterator), /* tp_basicsize */
11884 0, /* tp_itemsize */
11885 /* methods */
11886 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11887 0, /* tp_print */
11888 0, /* tp_getattr */
11889 0, /* tp_setattr */
11890 0, /* tp_compare */
11891 0, /* tp_repr */
11892 0, /* tp_as_number */
11893 0, /* tp_as_sequence */
11894 0, /* tp_as_mapping */
11895 0, /* tp_hash */
11896 0, /* tp_call */
11897 0, /* tp_str */
11898 0, /* tp_getattro */
11899 0, /* tp_setattro */
11900 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011901 Py_TPFLAGS_DEFAULT
11902 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011903 0, /* tp_doc */
11904 0, /* tp_traverse */
11905 0, /* tp_clear */
11906 0, /* tp_richcompare */
11907 0, /* tp_weaklistoffset */
11908 PyObject_SelfIter, /* tp_iter */
11909 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011910 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011911 0, /* tp_members */
11912 0, /* tp_getset */
11913 0, /* tp_base */
11914 0, /* tp_dict */
11915 0, /* tp_descr_get */
11916 0, /* tp_descr_set */
11917 0, /* tp_dictoffset */
11918 0, /* tp_init */
11919 0, /* tp_alloc */
11920 0, /* tp_new */
11921 0, /* tp_free */
11922 0, /* tp_is_gc */
11923 0, /* tp_bases */
11924 0, /* tp_mro */
11925 0, /* tp_cache */
11926 0, /* tp_subclasses */
11927 0, /* tp_weaklist */
11928 0, /* tp_del */
11929 0, /* tp_version_tag */
11930 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011931};
11932
11933static PyObject *
11934posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11935{
11936 ScandirIterator *iterator;
11937 static char *keywords[] = {"path", NULL};
11938#ifdef MS_WINDOWS
11939 wchar_t *path_strW;
11940#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011941 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011942#endif
11943
11944 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11945 if (!iterator)
11946 return NULL;
11947 memset(&iterator->path, 0, sizeof(path_t));
11948 iterator->path.function_name = "scandir";
11949 iterator->path.nullable = 1;
11950
11951#ifdef MS_WINDOWS
11952 iterator->handle = INVALID_HANDLE_VALUE;
11953#else
11954 iterator->dirp = NULL;
11955#endif
11956
11957 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11958 path_converter, &iterator->path))
11959 goto error;
11960
11961 /* path_converter doesn't keep path.object around, so do it
11962 manually for the lifetime of the iterator here (the refcount
11963 is decremented in ScandirIterator_dealloc)
11964 */
11965 Py_XINCREF(iterator->path.object);
11966
11967#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011968 iterator->first_time = 1;
11969
11970 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11971 if (!path_strW)
11972 goto error;
11973
11974 Py_BEGIN_ALLOW_THREADS
11975 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11976 Py_END_ALLOW_THREADS
11977
11978 PyMem_Free(path_strW);
11979
11980 if (iterator->handle == INVALID_HANDLE_VALUE) {
11981 path_error(&iterator->path);
11982 goto error;
11983 }
11984#else /* POSIX */
11985 if (iterator->path.narrow)
11986 path = iterator->path.narrow;
11987 else
11988 path = ".";
11989
11990 errno = 0;
11991 Py_BEGIN_ALLOW_THREADS
11992 iterator->dirp = opendir(path);
11993 Py_END_ALLOW_THREADS
11994
11995 if (!iterator->dirp) {
11996 path_error(&iterator->path);
11997 goto error;
11998 }
11999#endif
12000
12001 return (PyObject *)iterator;
12002
12003error:
12004 Py_DECREF(iterator);
12005 return NULL;
12006}
12007
Ethan Furman410ef8e2016-06-04 12:06:26 -070012008/*
12009 Return the file system path representation of the object.
12010
12011 If the object is str or bytes, then allow it to pass through with
12012 an incremented refcount. If the object defines __fspath__(), then
12013 return the result of that method. All other types raise a TypeError.
12014*/
12015PyObject *
12016PyOS_FSPath(PyObject *path)
12017{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012018 /* For error message reasons, this function is manually inlined in
12019 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012020 _Py_IDENTIFIER(__fspath__);
12021 PyObject *func = NULL;
12022 PyObject *path_repr = NULL;
12023
12024 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12025 Py_INCREF(path);
12026 return path;
12027 }
12028
12029 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12030 if (NULL == func) {
12031 return PyErr_Format(PyExc_TypeError,
12032 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012033 "not %.200s",
12034 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012035 }
12036
12037 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12038 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012039 if (NULL == path_repr) {
12040 return NULL;
12041 }
12042
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012043 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12044 PyErr_Format(PyExc_TypeError,
12045 "expected %.200s.__fspath__() to return str or bytes, "
12046 "not %.200s", Py_TYPE(path)->tp_name,
12047 Py_TYPE(path_repr)->tp_name);
12048 Py_DECREF(path_repr);
12049 return NULL;
12050 }
12051
Ethan Furman410ef8e2016-06-04 12:06:26 -070012052 return path_repr;
12053}
12054
12055/*[clinic input]
12056os.fspath
12057
12058 path: object
12059
12060Return the file system path representation of the object.
12061
Brett Cannonb4f43e92016-06-09 14:32:08 -070012062If the object is str or bytes, then allow it to pass through as-is. If the
12063object defines __fspath__(), then return the result of that method. All other
12064types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012065[clinic start generated code]*/
12066
12067static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012068os_fspath_impl(PyObject *module, PyObject *path)
12069/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012070{
12071 return PyOS_FSPath(path);
12072}
Victor Stinner6036e442015-03-08 01:58:04 +010012073
Victor Stinner9b1f4742016-09-06 16:18:52 -070012074#ifdef HAVE_GETRANDOM_SYSCALL
12075/*[clinic input]
12076os.getrandom
12077
12078 size: Py_ssize_t
12079 flags: int=0
12080
12081Obtain a series of random bytes.
12082[clinic start generated code]*/
12083
12084static PyObject *
12085os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12086/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12087{
12088 char *buffer;
12089 Py_ssize_t n;
12090 PyObject *bytes;
12091
12092 if (size < 0) {
12093 errno = EINVAL;
12094 return posix_error();
12095 }
12096
12097 buffer = PyMem_Malloc(size);
12098 if (buffer == NULL) {
12099 PyErr_NoMemory();
12100 return NULL;
12101 }
12102
12103 while (1) {
12104 n = syscall(SYS_getrandom, buffer, size, flags);
12105 if (n < 0 && errno == EINTR) {
12106 if (PyErr_CheckSignals() < 0) {
12107 return NULL;
12108 }
12109 continue;
12110 }
12111 break;
12112 }
12113
12114 if (n < 0) {
12115 PyMem_Free(buffer);
12116 PyErr_SetFromErrno(PyExc_OSError);
12117 return NULL;
12118 }
12119
12120 bytes = PyBytes_FromStringAndSize(buffer, n);
12121 PyMem_Free(buffer);
12122
12123 return bytes;
12124}
12125#endif /* HAVE_GETRANDOM_SYSCALL */
12126
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012127#include "clinic/posixmodule.c.h"
12128
Larry Hastings7726ac92014-01-31 22:03:12 -080012129/*[clinic input]
12130dump buffer
12131[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012132/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012133
Larry Hastings31826802013-10-19 00:09:25 -070012134
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012135static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012136
12137 OS_STAT_METHODDEF
12138 OS_ACCESS_METHODDEF
12139 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012140 OS_CHDIR_METHODDEF
12141 OS_CHFLAGS_METHODDEF
12142 OS_CHMOD_METHODDEF
12143 OS_FCHMOD_METHODDEF
12144 OS_LCHMOD_METHODDEF
12145 OS_CHOWN_METHODDEF
12146 OS_FCHOWN_METHODDEF
12147 OS_LCHOWN_METHODDEF
12148 OS_LCHFLAGS_METHODDEF
12149 OS_CHROOT_METHODDEF
12150 OS_CTERMID_METHODDEF
12151 OS_GETCWD_METHODDEF
12152 OS_GETCWDB_METHODDEF
12153 OS_LINK_METHODDEF
12154 OS_LISTDIR_METHODDEF
12155 OS_LSTAT_METHODDEF
12156 OS_MKDIR_METHODDEF
12157 OS_NICE_METHODDEF
12158 OS_GETPRIORITY_METHODDEF
12159 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012160#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012161 {"readlink", (PyCFunction)posix_readlink,
12162 METH_VARARGS | METH_KEYWORDS,
12163 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012164#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012165#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012166 {"readlink", (PyCFunction)win_readlink,
12167 METH_VARARGS | METH_KEYWORDS,
12168 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012169#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012170 OS_RENAME_METHODDEF
12171 OS_REPLACE_METHODDEF
12172 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012173 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012174 OS_SYMLINK_METHODDEF
12175 OS_SYSTEM_METHODDEF
12176 OS_UMASK_METHODDEF
12177 OS_UNAME_METHODDEF
12178 OS_UNLINK_METHODDEF
12179 OS_REMOVE_METHODDEF
12180 OS_UTIME_METHODDEF
12181 OS_TIMES_METHODDEF
12182 OS__EXIT_METHODDEF
12183 OS_EXECV_METHODDEF
12184 OS_EXECVE_METHODDEF
12185 OS_SPAWNV_METHODDEF
12186 OS_SPAWNVE_METHODDEF
12187 OS_FORK1_METHODDEF
12188 OS_FORK_METHODDEF
12189 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12190 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12191 OS_SCHED_GETPARAM_METHODDEF
12192 OS_SCHED_GETSCHEDULER_METHODDEF
12193 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12194 OS_SCHED_SETPARAM_METHODDEF
12195 OS_SCHED_SETSCHEDULER_METHODDEF
12196 OS_SCHED_YIELD_METHODDEF
12197 OS_SCHED_SETAFFINITY_METHODDEF
12198 OS_SCHED_GETAFFINITY_METHODDEF
12199 OS_OPENPTY_METHODDEF
12200 OS_FORKPTY_METHODDEF
12201 OS_GETEGID_METHODDEF
12202 OS_GETEUID_METHODDEF
12203 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012204#ifdef HAVE_GETGROUPLIST
12205 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12206#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012207 OS_GETGROUPS_METHODDEF
12208 OS_GETPID_METHODDEF
12209 OS_GETPGRP_METHODDEF
12210 OS_GETPPID_METHODDEF
12211 OS_GETUID_METHODDEF
12212 OS_GETLOGIN_METHODDEF
12213 OS_KILL_METHODDEF
12214 OS_KILLPG_METHODDEF
12215 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012216#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012217 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012218#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012219 OS_SETUID_METHODDEF
12220 OS_SETEUID_METHODDEF
12221 OS_SETREUID_METHODDEF
12222 OS_SETGID_METHODDEF
12223 OS_SETEGID_METHODDEF
12224 OS_SETREGID_METHODDEF
12225 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012226#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012227 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012228#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012229 OS_GETPGID_METHODDEF
12230 OS_SETPGRP_METHODDEF
12231 OS_WAIT_METHODDEF
12232 OS_WAIT3_METHODDEF
12233 OS_WAIT4_METHODDEF
12234 OS_WAITID_METHODDEF
12235 OS_WAITPID_METHODDEF
12236 OS_GETSID_METHODDEF
12237 OS_SETSID_METHODDEF
12238 OS_SETPGID_METHODDEF
12239 OS_TCGETPGRP_METHODDEF
12240 OS_TCSETPGRP_METHODDEF
12241 OS_OPEN_METHODDEF
12242 OS_CLOSE_METHODDEF
12243 OS_CLOSERANGE_METHODDEF
12244 OS_DEVICE_ENCODING_METHODDEF
12245 OS_DUP_METHODDEF
12246 OS_DUP2_METHODDEF
12247 OS_LOCKF_METHODDEF
12248 OS_LSEEK_METHODDEF
12249 OS_READ_METHODDEF
12250 OS_READV_METHODDEF
12251 OS_PREAD_METHODDEF
12252 OS_WRITE_METHODDEF
12253 OS_WRITEV_METHODDEF
12254 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012255#ifdef HAVE_SENDFILE
12256 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12257 posix_sendfile__doc__},
12258#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012259 OS_FSTAT_METHODDEF
12260 OS_ISATTY_METHODDEF
12261 OS_PIPE_METHODDEF
12262 OS_PIPE2_METHODDEF
12263 OS_MKFIFO_METHODDEF
12264 OS_MKNOD_METHODDEF
12265 OS_MAJOR_METHODDEF
12266 OS_MINOR_METHODDEF
12267 OS_MAKEDEV_METHODDEF
12268 OS_FTRUNCATE_METHODDEF
12269 OS_TRUNCATE_METHODDEF
12270 OS_POSIX_FALLOCATE_METHODDEF
12271 OS_POSIX_FADVISE_METHODDEF
12272 OS_PUTENV_METHODDEF
12273 OS_UNSETENV_METHODDEF
12274 OS_STRERROR_METHODDEF
12275 OS_FCHDIR_METHODDEF
12276 OS_FSYNC_METHODDEF
12277 OS_SYNC_METHODDEF
12278 OS_FDATASYNC_METHODDEF
12279 OS_WCOREDUMP_METHODDEF
12280 OS_WIFCONTINUED_METHODDEF
12281 OS_WIFSTOPPED_METHODDEF
12282 OS_WIFSIGNALED_METHODDEF
12283 OS_WIFEXITED_METHODDEF
12284 OS_WEXITSTATUS_METHODDEF
12285 OS_WTERMSIG_METHODDEF
12286 OS_WSTOPSIG_METHODDEF
12287 OS_FSTATVFS_METHODDEF
12288 OS_STATVFS_METHODDEF
12289 OS_CONFSTR_METHODDEF
12290 OS_SYSCONF_METHODDEF
12291 OS_FPATHCONF_METHODDEF
12292 OS_PATHCONF_METHODDEF
12293 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012294 OS__GETFULLPATHNAME_METHODDEF
12295 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012296 OS__GETDISKUSAGE_METHODDEF
12297 OS__GETFINALPATHNAME_METHODDEF
12298 OS__GETVOLUMEPATHNAME_METHODDEF
12299 OS_GETLOADAVG_METHODDEF
12300 OS_URANDOM_METHODDEF
12301 OS_SETRESUID_METHODDEF
12302 OS_SETRESGID_METHODDEF
12303 OS_GETRESUID_METHODDEF
12304 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012305
Larry Hastings2f936352014-08-05 14:04:04 +100012306 OS_GETXATTR_METHODDEF
12307 OS_SETXATTR_METHODDEF
12308 OS_REMOVEXATTR_METHODDEF
12309 OS_LISTXATTR_METHODDEF
12310
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012311#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12312 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12313#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012314 OS_CPU_COUNT_METHODDEF
12315 OS_GET_INHERITABLE_METHODDEF
12316 OS_SET_INHERITABLE_METHODDEF
12317 OS_GET_HANDLE_INHERITABLE_METHODDEF
12318 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012319#ifndef MS_WINDOWS
12320 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12321 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12322#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012323 {"scandir", (PyCFunction)posix_scandir,
12324 METH_VARARGS | METH_KEYWORDS,
12325 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012326 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012327 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012328 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012329};
12330
12331
Brian Curtin52173d42010-12-02 18:29:18 +000012332#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012333static int
Brian Curtin52173d42010-12-02 18:29:18 +000012334enable_symlink()
12335{
12336 HANDLE tok;
12337 TOKEN_PRIVILEGES tok_priv;
12338 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012339
12340 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012341 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012342
12343 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012344 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012345
12346 tok_priv.PrivilegeCount = 1;
12347 tok_priv.Privileges[0].Luid = luid;
12348 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12349
12350 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12351 sizeof(TOKEN_PRIVILEGES),
12352 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012353 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012354
Brian Curtin3b4499c2010-12-28 14:31:47 +000012355 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12356 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012357}
12358#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12359
Barry Warsaw4a342091996-12-19 23:50:02 +000012360static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012361all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012362{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012363#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012364 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012365#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012366#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012367 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012368#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012369#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012370 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012371#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012372#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012373 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012374#endif
Fred Drakec9680921999-12-13 16:37:25 +000012375#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012376 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012377#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012378#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012380#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012381#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012383#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012384#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012385 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012386#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012387#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012388 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012389#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012390#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012391 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012392#endif
12393#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012394 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012395#endif
12396#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012397 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012398#endif
12399#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012400 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012401#endif
12402#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012404#endif
12405#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012407#endif
12408#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012410#endif
12411#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012413#endif
12414#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012416#endif
12417#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012419#endif
12420#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012422#endif
12423#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#endif
12426#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012428#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012429#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012431#endif
12432#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012434#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012435#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012437#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012438#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012440#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012441#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012442#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012443 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012444#endif
12445#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012446 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012447#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012448#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012449#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012450 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012451#endif
12452#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012453 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012454#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012455#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012456 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012457#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012458#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012460#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012461#ifdef O_TMPFILE
12462 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12463#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012464#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012466#endif
12467#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012469#endif
12470#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012472#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012473#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012475#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012476#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012477 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012478#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012479
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012480
Jesus Cea94363612012-06-22 18:32:07 +020012481#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012483#endif
12484#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012486#endif
12487
Tim Peters5aa91602002-01-30 05:46:57 +000012488/* MS Windows */
12489#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012490 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012492#endif
12493#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012494 /* Optimize for short life (keep in memory). */
12495 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012497#endif
12498#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012499 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012501#endif
12502#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012503 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012504 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012505#endif
12506#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012507 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012508 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012509#endif
12510
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012511/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012512#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012513 /* Send a SIGIO signal whenever input or output
12514 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012516#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012517#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012518 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012519 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012520#endif
12521#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012522 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012523 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012524#endif
12525#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012526 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012527 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012528#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012529#ifdef O_NOLINKS
12530 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012531 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012532#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012533#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012534 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012535 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012536#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012537
Victor Stinner8c62be82010-05-06 00:08:46 +000012538 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012539#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012540 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012541#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012542#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012544#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012545#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012546 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012547#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012548#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012549 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012550#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012551#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012552 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012553#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012554#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012556#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012557#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012559#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012560#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012561 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012562#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012563#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012565#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012566#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012568#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012569#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012571#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012572#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012573 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012574#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012575#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012577#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012591 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012592#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012594#endif /* ST_RDONLY */
12595#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012597#endif /* ST_NOSUID */
12598
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012599 /* GNU extensions */
12600#ifdef ST_NODEV
12601 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12602#endif /* ST_NODEV */
12603#ifdef ST_NOEXEC
12604 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12605#endif /* ST_NOEXEC */
12606#ifdef ST_SYNCHRONOUS
12607 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12608#endif /* ST_SYNCHRONOUS */
12609#ifdef ST_MANDLOCK
12610 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12611#endif /* ST_MANDLOCK */
12612#ifdef ST_WRITE
12613 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12614#endif /* ST_WRITE */
12615#ifdef ST_APPEND
12616 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12617#endif /* ST_APPEND */
12618#ifdef ST_NOATIME
12619 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12620#endif /* ST_NOATIME */
12621#ifdef ST_NODIRATIME
12622 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12623#endif /* ST_NODIRATIME */
12624#ifdef ST_RELATIME
12625 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12626#endif /* ST_RELATIME */
12627
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012628 /* FreeBSD sendfile() constants */
12629#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012630 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012631#endif
12632#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012634#endif
12635#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012637#endif
12638
Ross Lagerwall7807c352011-03-17 20:20:30 +020012639 /* constants for posix_fadvise */
12640#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012642#endif
12643#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012645#endif
12646#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012648#endif
12649#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012651#endif
12652#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012654#endif
12655#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012657#endif
12658
12659 /* constants for waitid */
12660#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12662 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12663 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012664#endif
12665#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012666 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012667#endif
12668#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012670#endif
12671#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012673#endif
12674#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012676#endif
12677#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012679#endif
12680#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012682#endif
12683#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012685#endif
12686
12687 /* constants for lockf */
12688#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012699#endif
12700
Guido van Rossum246bc171999-02-01 23:54:31 +000012701#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012702 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12703 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12704 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12705 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12706 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012707#endif
12708
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012709#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012710#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012712#endif
12713#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012715#endif
12716#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012718#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012719#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012721#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012722#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012724#endif
12725#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012727#endif
12728#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012730#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012731#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012733#endif
12734#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012736#endif
12737#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012739#endif
12740#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012742#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012743#endif
12744
Benjamin Peterson9428d532011-09-14 11:45:52 -040012745#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12747 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12748 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012749#endif
12750
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012751#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012753#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012754#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012755 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012756#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012757#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012759#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012760#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012762#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012763#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012765#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012766#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012768#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012769#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012771#endif
12772
Victor Stinner9b1f4742016-09-06 16:18:52 -070012773#ifdef HAVE_GETRANDOM_SYSCALL
12774 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12775 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12776#endif
12777
Victor Stinner8c62be82010-05-06 00:08:46 +000012778 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012779}
12780
12781
Martin v. Löwis1a214512008-06-11 05:26:20 +000012782static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012783 PyModuleDef_HEAD_INIT,
12784 MODNAME,
12785 posix__doc__,
12786 -1,
12787 posix_methods,
12788 NULL,
12789 NULL,
12790 NULL,
12791 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012792};
12793
12794
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012795static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012796
12797#ifdef HAVE_FACCESSAT
12798 "HAVE_FACCESSAT",
12799#endif
12800
12801#ifdef HAVE_FCHDIR
12802 "HAVE_FCHDIR",
12803#endif
12804
12805#ifdef HAVE_FCHMOD
12806 "HAVE_FCHMOD",
12807#endif
12808
12809#ifdef HAVE_FCHMODAT
12810 "HAVE_FCHMODAT",
12811#endif
12812
12813#ifdef HAVE_FCHOWN
12814 "HAVE_FCHOWN",
12815#endif
12816
Larry Hastings00964ed2013-08-12 13:49:30 -040012817#ifdef HAVE_FCHOWNAT
12818 "HAVE_FCHOWNAT",
12819#endif
12820
Larry Hastings9cf065c2012-06-22 16:30:09 -070012821#ifdef HAVE_FEXECVE
12822 "HAVE_FEXECVE",
12823#endif
12824
12825#ifdef HAVE_FDOPENDIR
12826 "HAVE_FDOPENDIR",
12827#endif
12828
Georg Brandl306336b2012-06-24 12:55:33 +020012829#ifdef HAVE_FPATHCONF
12830 "HAVE_FPATHCONF",
12831#endif
12832
Larry Hastings9cf065c2012-06-22 16:30:09 -070012833#ifdef HAVE_FSTATAT
12834 "HAVE_FSTATAT",
12835#endif
12836
12837#ifdef HAVE_FSTATVFS
12838 "HAVE_FSTATVFS",
12839#endif
12840
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012841#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012842 "HAVE_FTRUNCATE",
12843#endif
12844
Larry Hastings9cf065c2012-06-22 16:30:09 -070012845#ifdef HAVE_FUTIMENS
12846 "HAVE_FUTIMENS",
12847#endif
12848
12849#ifdef HAVE_FUTIMES
12850 "HAVE_FUTIMES",
12851#endif
12852
12853#ifdef HAVE_FUTIMESAT
12854 "HAVE_FUTIMESAT",
12855#endif
12856
12857#ifdef HAVE_LINKAT
12858 "HAVE_LINKAT",
12859#endif
12860
12861#ifdef HAVE_LCHFLAGS
12862 "HAVE_LCHFLAGS",
12863#endif
12864
12865#ifdef HAVE_LCHMOD
12866 "HAVE_LCHMOD",
12867#endif
12868
12869#ifdef HAVE_LCHOWN
12870 "HAVE_LCHOWN",
12871#endif
12872
12873#ifdef HAVE_LSTAT
12874 "HAVE_LSTAT",
12875#endif
12876
12877#ifdef HAVE_LUTIMES
12878 "HAVE_LUTIMES",
12879#endif
12880
12881#ifdef HAVE_MKDIRAT
12882 "HAVE_MKDIRAT",
12883#endif
12884
12885#ifdef HAVE_MKFIFOAT
12886 "HAVE_MKFIFOAT",
12887#endif
12888
12889#ifdef HAVE_MKNODAT
12890 "HAVE_MKNODAT",
12891#endif
12892
12893#ifdef HAVE_OPENAT
12894 "HAVE_OPENAT",
12895#endif
12896
12897#ifdef HAVE_READLINKAT
12898 "HAVE_READLINKAT",
12899#endif
12900
12901#ifdef HAVE_RENAMEAT
12902 "HAVE_RENAMEAT",
12903#endif
12904
12905#ifdef HAVE_SYMLINKAT
12906 "HAVE_SYMLINKAT",
12907#endif
12908
12909#ifdef HAVE_UNLINKAT
12910 "HAVE_UNLINKAT",
12911#endif
12912
12913#ifdef HAVE_UTIMENSAT
12914 "HAVE_UTIMENSAT",
12915#endif
12916
12917#ifdef MS_WINDOWS
12918 "MS_WINDOWS",
12919#endif
12920
12921 NULL
12922};
12923
12924
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012925PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012926INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012927{
Victor Stinner8c62be82010-05-06 00:08:46 +000012928 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012929 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012930 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012931
Brian Curtin52173d42010-12-02 18:29:18 +000012932#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012933 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012934#endif
12935
Victor Stinner8c62be82010-05-06 00:08:46 +000012936 m = PyModule_Create(&posixmodule);
12937 if (m == NULL)
12938 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012939
Victor Stinner8c62be82010-05-06 00:08:46 +000012940 /* Initialize environ dictionary */
12941 v = convertenviron();
12942 Py_XINCREF(v);
12943 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12944 return NULL;
12945 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012946
Victor Stinner8c62be82010-05-06 00:08:46 +000012947 if (all_ins(m))
12948 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012949
Victor Stinner8c62be82010-05-06 00:08:46 +000012950 if (setup_confname_tables(m))
12951 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012952
Victor Stinner8c62be82010-05-06 00:08:46 +000012953 Py_INCREF(PyExc_OSError);
12954 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012955
Guido van Rossumb3d39562000-01-31 18:41:26 +000012956#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012957 if (posix_putenv_garbage == NULL)
12958 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012959#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012960
Victor Stinner8c62be82010-05-06 00:08:46 +000012961 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012962#if defined(HAVE_WAITID) && !defined(__APPLE__)
12963 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012964 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12965 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012966#endif
12967
Christian Heimes25827622013-10-12 01:27:08 +020012968 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12970 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12971 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012972 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12973 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012974 structseq_new = StatResultType.tp_new;
12975 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012976
Christian Heimes25827622013-10-12 01:27:08 +020012977 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012978 if (PyStructSequence_InitType2(&StatVFSResultType,
12979 &statvfs_result_desc) < 0)
12980 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012981#ifdef NEED_TICKS_PER_SECOND
12982# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012983 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012984# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012985 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012986# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012988# endif
12989#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012990
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012991#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012992 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012993 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12994 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012995 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012996#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012997
12998 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012999 if (PyStructSequence_InitType2(&TerminalSizeType,
13000 &TerminalSize_desc) < 0)
13001 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013002
13003 /* initialize scandir types */
13004 if (PyType_Ready(&ScandirIteratorType) < 0)
13005 return NULL;
13006 if (PyType_Ready(&DirEntryType) < 0)
13007 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013008 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013009#if defined(HAVE_WAITID) && !defined(__APPLE__)
13010 Py_INCREF((PyObject*) &WaitidResultType);
13011 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 Py_INCREF((PyObject*) &StatResultType);
13014 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13015 Py_INCREF((PyObject*) &StatVFSResultType);
13016 PyModule_AddObject(m, "statvfs_result",
13017 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013018
13019#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013020 Py_INCREF(&SchedParamType);
13021 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013022#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013023
Larry Hastings605a62d2012-06-24 04:33:36 -070013024 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013025 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13026 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013027 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13028
13029 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013030 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13031 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013032 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13033
Thomas Wouters477c8d52006-05-27 19:21:47 +000013034#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013035 /*
13036 * Step 2 of weak-linking support on Mac OS X.
13037 *
13038 * The code below removes functions that are not available on the
13039 * currently active platform.
13040 *
13041 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013042 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013043 * OSX 10.4.
13044 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013045#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013046 if (fstatvfs == NULL) {
13047 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13048 return NULL;
13049 }
13050 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013051#endif /* HAVE_FSTATVFS */
13052
13053#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013054 if (statvfs == NULL) {
13055 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13056 return NULL;
13057 }
13058 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013059#endif /* HAVE_STATVFS */
13060
13061# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013062 if (lchown == NULL) {
13063 if (PyObject_DelAttrString(m, "lchown") == -1) {
13064 return NULL;
13065 }
13066 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013067#endif /* HAVE_LCHOWN */
13068
13069
13070#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013071
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013072 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013073 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13074
Larry Hastings6fe20b32012-04-19 15:07:49 -070013075 billion = PyLong_FromLong(1000000000);
13076 if (!billion)
13077 return NULL;
13078
Larry Hastings9cf065c2012-06-22 16:30:09 -070013079 /* suppress "function not used" warnings */
13080 {
13081 int ignored;
13082 fd_specified("", -1);
13083 follow_symlinks_specified("", 1);
13084 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13085 dir_fd_converter(Py_None, &ignored);
13086 dir_fd_unavailable(Py_None, &ignored);
13087 }
13088
13089 /*
13090 * provide list of locally available functions
13091 * so os.py can populate support_* lists
13092 */
13093 list = PyList_New(0);
13094 if (!list)
13095 return NULL;
13096 for (trace = have_functions; *trace; trace++) {
13097 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13098 if (!unicode)
13099 return NULL;
13100 if (PyList_Append(list, unicode))
13101 return NULL;
13102 Py_DECREF(unicode);
13103 }
13104 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013105
13106 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013107 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013108
13109 initialized = 1;
13110
Victor Stinner8c62be82010-05-06 00:08:46 +000013111 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013112}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013113
13114#ifdef __cplusplus
13115}
13116#endif