blob: 43e3c77cbb29727a0a96461d6d2a0bc1a1395e79 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020035/* On android API level 21, 'AT_EACCESS' is not declared although
36 * HAVE_FACCESSAT is defined. */
37#ifdef __ANDROID__
38#undef HAVE_FACCESSAT
39#endif
40
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000041#include <stdio.h> /* needed for ctermid() */
42
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#ifdef __cplusplus
44extern "C" {
45#endif
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000048"This module provides access to operating system functionality that is\n\
49standardized by the C Standard and the POSIX standard (a thinly\n\
50disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000053
Ross Lagerwall4d076da2011-03-18 06:56:53 +020054#ifdef HAVE_SYS_UIO_H
55#include <sys/uio.h>
56#endif
57
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000059#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#endif /* HAVE_SYS_TYPES_H */
61
62#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000065
Guido van Rossum36bc6801995-06-14 22:54:23 +000066#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000067#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000073
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#ifdef HAVE_FCNTL_H
75#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000076#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Guido van Rossuma6535fd2001-10-18 19:44:10 +000078#ifdef HAVE_GRP_H
79#include <grp.h>
80#endif
81
Barry Warsaw5676bd12003-01-07 20:57:09 +000082#ifdef HAVE_SYSEXITS_H
83#include <sysexits.h>
84#endif /* HAVE_SYSEXITS_H */
85
Anthony Baxter8a560de2004-10-13 15:30:56 +000086#ifdef HAVE_SYS_LOADAVG_H
87#include <sys/loadavg.h>
88#endif
89
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000090#ifdef HAVE_LANGINFO_H
91#include <langinfo.h>
92#endif
93
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000094#ifdef HAVE_SYS_SENDFILE_H
95#include <sys/sendfile.h>
96#endif
97
Benjamin Peterson94b580d2011-08-02 17:30:04 -050098#ifdef HAVE_SCHED_H
99#include <sched.h>
100#endif
101
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500102#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500103#undef HAVE_SCHED_SETAFFINITY
104#endif
105
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200106#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400107#define USE_XATTRS
108#endif
109
110#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400111#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400112#endif
113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
115#ifdef HAVE_SYS_SOCKET_H
116#include <sys/socket.h>
117#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#endif
119
Victor Stinner8b905bd2011-10-25 13:34:04 +0200120#ifdef HAVE_DLFCN_H
121#include <dlfcn.h>
122#endif
123
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200124#ifdef __hpux
125#include <sys/mpctl.h>
126#endif
127
128#if defined(__DragonFly__) || \
129 defined(__OpenBSD__) || \
130 defined(__FreeBSD__) || \
131 defined(__NetBSD__) || \
132 defined(__APPLE__)
133#include <sys/sysctl.h>
134#endif
135
Victor Stinner9b1f4742016-09-06 16:18:52 -0700136#ifdef HAVE_LINUX_RANDOM_H
137# include <linux/random.h>
138#endif
139#ifdef HAVE_GETRANDOM_SYSCALL
140# include <sys/syscall.h>
141#endif
142
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100143#if defined(MS_WINDOWS)
144# define TERMSIZE_USE_CONIO
145#elif defined(HAVE_SYS_IOCTL_H)
146# include <sys/ioctl.h>
147# if defined(HAVE_TERMIOS_H)
148# include <termios.h>
149# endif
150# if defined(TIOCGWINSZ)
151# define TERMSIZE_USE_IOCTL
152# endif
153#endif /* MS_WINDOWS */
154
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000155/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000156/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000157#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000159#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160#include <process.h>
161#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000162#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000163#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000164#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000165#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_EXECV 1
Steve Dowercc16be82016-09-08 10:35:16 -0700167#define HAVE_WSPAWNV 1
168#define HAVE_WEXECV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000169#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000170#define HAVE_SYSTEM 1
171#define HAVE_CWAIT 1
172#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000173#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000174#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175/* Unix functions that the configure script doesn't check for */
176#define HAVE_EXECV 1
177#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000178#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000179#define HAVE_FORK1 1
180#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_GETEGID 1
182#define HAVE_GETEUID 1
183#define HAVE_GETGID 1
184#define HAVE_GETPPID 1
185#define HAVE_GETUID 1
186#define HAVE_KILL 1
187#define HAVE_OPENDIR 1
188#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000189#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000190#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000191#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000192#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000193#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000194
Victor Stinnera2f7c002012-02-08 03:36:25 +0100195
Larry Hastings61272b72014-01-07 12:41:53 -0800196/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000197# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800198module os
Larry Hastings61272b72014-01-07 12:41:53 -0800199[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000200/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100201
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000202#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000203
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000204#if defined(__sgi)&&_COMPILER_VERSION>=700
205/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
206 (default) */
207extern char *ctermid_r(char *);
208#endif
209
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000210#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000213#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000214#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000216#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000218#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000219#endif
220#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000221extern int chdir(char *);
222extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000223#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000224extern int chdir(const char *);
225extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000226#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000228/*#ifdef HAVE_FCHMOD
229extern int fchmod(int, mode_t);
230#endif*/
231/*#ifdef HAVE_LCHMOD
232extern int lchmod(const char *, mode_t);
233#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000234extern int chown(const char *, uid_t, gid_t);
235extern char *getcwd(char *, int);
236extern char *strerror(int);
237extern int link(const char *, const char *);
238extern int rename(const char *, const char *);
239extern int stat(const char *, struct stat *);
240extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000241#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000242extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000243#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000244#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000245extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000246#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000247#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000248
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000249#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_UTIME_H
252#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000255#ifdef HAVE_SYS_UTIME_H
256#include <sys/utime.h>
257#define HAVE_UTIME_H /* pretend we do for the rest of this file */
258#endif /* HAVE_SYS_UTIME_H */
259
Guido van Rossumb6775db1994-08-01 11:34:53 +0000260#ifdef HAVE_SYS_TIMES_H
261#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000262#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263
264#ifdef HAVE_SYS_PARAM_H
265#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000266#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267
268#ifdef HAVE_SYS_UTSNAME_H
269#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000270#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#define NAMLEN(dirent) strlen((dirent)->d_name)
275#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000276#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#include <direct.h>
278#define NAMLEN(dirent) strlen((dirent)->d_name)
279#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000280#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000281#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000282#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000283#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000285#endif
286#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000288#endif
289#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000291#endif
292#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000294#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000295#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000296#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000297#endif
298#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000299#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000300#endif
301#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000302#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000303#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000304#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000305#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000306#endif
307#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000308#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000309#endif
310#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000311#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000312#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100313#ifndef IO_REPARSE_TAG_MOUNT_POINT
314#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000317#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000318#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000319#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000320#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000321#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
322#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000323static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000324#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000325#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000326
Tim Petersbc2e10e2002-03-03 23:17:02 +0000327#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000328#if defined(PATH_MAX) && PATH_MAX > 1024
329#define MAXPATHLEN PATH_MAX
330#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000331#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000332#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000333#endif /* MAXPATHLEN */
334
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000335#ifdef UNION_WAIT
336/* Emulate some macros on systems that have a union instead of macros */
337
338#ifndef WIFEXITED
339#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
340#endif
341
342#ifndef WEXITSTATUS
343#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
344#endif
345
346#ifndef WTERMSIG
347#define WTERMSIG(u_wait) ((u_wait).w_termsig)
348#endif
349
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000350#define WAIT_TYPE union wait
351#define WAIT_STATUS_INT(s) (s.w_status)
352
353#else /* !UNION_WAIT */
354#define WAIT_TYPE int
355#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000356#endif /* UNION_WAIT */
357
Greg Wardb48bc172000-03-01 21:51:56 +0000358/* Don't use the "_r" form if we don't need it (also, won't have a
359 prototype for it, at least on Solaris -- maybe others as well?). */
360#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
361#define USE_CTERMID_R
362#endif
363
Fred Drake699f3522000-06-29 21:12:41 +0000364/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000365#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000366#undef FSTAT
367#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200368#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000369# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700370# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200371# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800372# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000373#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000374# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700375# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000376# define FSTAT fstat
377# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000378#endif
379
Tim Peters11b23062003-04-23 02:39:17 +0000380#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000381#include <sys/mkdev.h>
382#else
383#if defined(MAJOR_IN_SYSMACROS)
384#include <sys/sysmacros.h>
385#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000386#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
387#include <sys/mkdev.h>
388#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000389#endif
Fred Drake699f3522000-06-29 21:12:41 +0000390
Victor Stinner6edddfa2013-11-24 19:22:57 +0100391#define DWORD_MAX 4294967295U
392
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100394#define INITFUNC PyInit_nt
395#define MODNAME "nt"
396#else
397#define INITFUNC PyInit_posix
398#define MODNAME "posix"
399#endif
400
401#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200402/* defined in fileutils.c */
403PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
404PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
405 ULONG, struct _Py_stat_struct *);
406#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700407
408#ifdef MS_WINDOWS
409static int
410win32_warn_bytes_api()
411{
412 return PyErr_WarnEx(PyExc_DeprecationWarning,
413 "The Windows bytes API has been deprecated, "
414 "use Unicode filenames instead",
415 1);
416}
417#endif
418
419
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200420#ifndef MS_WINDOWS
421PyObject *
422_PyLong_FromUid(uid_t uid)
423{
424 if (uid == (uid_t)-1)
425 return PyLong_FromLong(-1);
426 return PyLong_FromUnsignedLong(uid);
427}
428
429PyObject *
430_PyLong_FromGid(gid_t gid)
431{
432 if (gid == (gid_t)-1)
433 return PyLong_FromLong(-1);
434 return PyLong_FromUnsignedLong(gid);
435}
436
437int
438_Py_Uid_Converter(PyObject *obj, void *p)
439{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700440 uid_t uid;
441 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200442 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200443 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444 unsigned long uresult;
445
446 index = PyNumber_Index(obj);
447 if (index == NULL) {
448 PyErr_Format(PyExc_TypeError,
449 "uid should be integer, not %.200s",
450 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200451 return 0;
452 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700453
454 /*
455 * Handling uid_t is complicated for two reasons:
456 * * Although uid_t is (always?) unsigned, it still
457 * accepts -1.
458 * * We don't know its size in advance--it may be
459 * bigger than an int, or it may be smaller than
460 * a long.
461 *
462 * So a bit of defensive programming is in order.
463 * Start with interpreting the value passed
464 * in as a signed long and see if it works.
465 */
466
467 result = PyLong_AsLongAndOverflow(index, &overflow);
468
469 if (!overflow) {
470 uid = (uid_t)result;
471
472 if (result == -1) {
473 if (PyErr_Occurred())
474 goto fail;
475 /* It's a legitimate -1, we're done. */
476 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200477 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700478
479 /* Any other negative number is disallowed. */
480 if (result < 0)
481 goto underflow;
482
483 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200484 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700485 (long)uid != result)
486 goto underflow;
487 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200488 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700489
490 if (overflow < 0)
491 goto underflow;
492
493 /*
494 * Okay, the value overflowed a signed long. If it
495 * fits in an *unsigned* long, it may still be okay,
496 * as uid_t may be unsigned long on this platform.
497 */
498 uresult = PyLong_AsUnsignedLong(index);
499 if (PyErr_Occurred()) {
500 if (PyErr_ExceptionMatches(PyExc_OverflowError))
501 goto overflow;
502 goto fail;
503 }
504
505 uid = (uid_t)uresult;
506
507 /*
508 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
509 * but this value would get interpreted as (uid_t)-1 by chown
510 * and its siblings. That's not what the user meant! So we
511 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100512 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 */
514 if (uid == (uid_t)-1)
515 goto overflow;
516
517 /* Ensure the value wasn't truncated. */
518 if (sizeof(uid_t) < sizeof(long) &&
519 (unsigned long)uid != uresult)
520 goto overflow;
521 /* fallthrough */
522
523success:
524 Py_DECREF(index);
525 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200526 return 1;
527
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700528underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200529 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700530 "uid is less than minimum");
531 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200532
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200534 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 "uid is greater than maximum");
536 /* fallthrough */
537
538fail:
539 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200540 return 0;
541}
542
543int
544_Py_Gid_Converter(PyObject *obj, void *p)
545{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700546 gid_t gid;
547 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200548 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200549 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550 unsigned long uresult;
551
552 index = PyNumber_Index(obj);
553 if (index == NULL) {
554 PyErr_Format(PyExc_TypeError,
555 "gid should be integer, not %.200s",
556 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200557 return 0;
558 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700559
560 /*
561 * Handling gid_t is complicated for two reasons:
562 * * Although gid_t is (always?) unsigned, it still
563 * accepts -1.
564 * * We don't know its size in advance--it may be
565 * bigger than an int, or it may be smaller than
566 * a long.
567 *
568 * So a bit of defensive programming is in order.
569 * Start with interpreting the value passed
570 * in as a signed long and see if it works.
571 */
572
573 result = PyLong_AsLongAndOverflow(index, &overflow);
574
575 if (!overflow) {
576 gid = (gid_t)result;
577
578 if (result == -1) {
579 if (PyErr_Occurred())
580 goto fail;
581 /* It's a legitimate -1, we're done. */
582 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200583 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700584
585 /* Any other negative number is disallowed. */
586 if (result < 0) {
587 goto underflow;
588 }
589
590 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200591 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700592 (long)gid != result)
593 goto underflow;
594 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200595 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700596
597 if (overflow < 0)
598 goto underflow;
599
600 /*
601 * Okay, the value overflowed a signed long. If it
602 * fits in an *unsigned* long, it may still be okay,
603 * as gid_t may be unsigned long on this platform.
604 */
605 uresult = PyLong_AsUnsignedLong(index);
606 if (PyErr_Occurred()) {
607 if (PyErr_ExceptionMatches(PyExc_OverflowError))
608 goto overflow;
609 goto fail;
610 }
611
612 gid = (gid_t)uresult;
613
614 /*
615 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
616 * but this value would get interpreted as (gid_t)-1 by chown
617 * and its siblings. That's not what the user meant! So we
618 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100619 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 */
621 if (gid == (gid_t)-1)
622 goto overflow;
623
624 /* Ensure the value wasn't truncated. */
625 if (sizeof(gid_t) < sizeof(long) &&
626 (unsigned long)gid != uresult)
627 goto overflow;
628 /* fallthrough */
629
630success:
631 Py_DECREF(index);
632 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200633 return 1;
634
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700635underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200636 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700637 "gid is less than minimum");
638 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200639
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700640overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200641 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700642 "gid is greater than maximum");
643 /* fallthrough */
644
645fail:
646 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200647 return 0;
648}
649#endif /* MS_WINDOWS */
650
651
Benjamin Petersoned4aa832016-09-05 17:44:18 -0700652#define _PyLong_FromDev PyLong_FromLongLong
Gregory P. Smith702dada2015-01-28 16:07:52 -0800653
654
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200655#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
656static int
657_Py_Dev_Converter(PyObject *obj, void *p)
658{
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200659 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200660 if (PyErr_Occurred())
661 return 0;
662 return 1;
663}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800664#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200665
666
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400668/*
669 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
670 * without the int cast, the value gets interpreted as uint (4291925331),
671 * which doesn't play nicely with all the initializer lines in this file that
672 * look like this:
673 * int dir_fd = DEFAULT_DIR_FD;
674 */
675#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700676#else
677#define DEFAULT_DIR_FD (-100)
678#endif
679
680static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300681_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200682{
683 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684 long long_value;
685
686 PyObject *index = PyNumber_Index(o);
687 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 return 0;
689 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700690
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300691 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700692 long_value = PyLong_AsLongAndOverflow(index, &overflow);
693 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300694 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200695 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700696 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 return 0;
699 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200700 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700701 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700702 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700703 return 0;
704 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700705
Larry Hastings9cf065c2012-06-22 16:30:09 -0700706 *p = (int)long_value;
707 return 1;
708}
709
710static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200711dir_fd_converter(PyObject *o, void *p)
712{
713 if (o == Py_None) {
714 *(int *)p = DEFAULT_DIR_FD;
715 return 1;
716 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300717 else if (PyIndex_Check(o)) {
718 return _fd_converter(o, (int *)p);
719 }
720 else {
721 PyErr_Format(PyExc_TypeError,
722 "argument should be integer or None, not %.200s",
723 Py_TYPE(o)->tp_name);
724 return 0;
725 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700726}
727
728
Larry Hastings9cf065c2012-06-22 16:30:09 -0700729/*
730 * A PyArg_ParseTuple "converter" function
731 * that handles filesystem paths in the manner
732 * preferred by the os module.
733 *
734 * path_converter accepts (Unicode) strings and their
735 * subclasses, and bytes and their subclasses. What
736 * it does with the argument depends on the platform:
737 *
738 * * On Windows, if we get a (Unicode) string we
739 * extract the wchar_t * and return it; if we get
Steve Dowercc16be82016-09-08 10:35:16 -0700740 * bytes we decode to wchar_t * and return that.
Larry Hastings9cf065c2012-06-22 16:30:09 -0700741 *
742 * * On all other platforms, strings are encoded
743 * to bytes using PyUnicode_FSConverter, then we
744 * extract the char * from the bytes object and
745 * return that.
746 *
747 * path_converter also optionally accepts signed
748 * integers (representing open file descriptors) instead
749 * of path strings.
750 *
751 * Input fields:
752 * path.nullable
753 * If nonzero, the path is permitted to be None.
754 * path.allow_fd
755 * If nonzero, the path is permitted to be a file handle
756 * (a signed int) instead of a string.
757 * path.function_name
758 * If non-NULL, path_converter will use that as the name
759 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700760 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700761 * path.argument_name
762 * If non-NULL, path_converter will use that as the name
763 * of the parameter in error messages.
764 * (If path.argument_name is NULL it uses "path".)
765 *
766 * Output fields:
767 * path.wide
768 * Points to the path if it was expressed as Unicode
769 * and was not encoded. (Only used on Windows.)
770 * path.narrow
771 * Points to the path if it was expressed as bytes,
Steve Dowercc16be82016-09-08 10:35:16 -0700772 * or it was Unicode and was encoded to bytes. (On Windows,
773 * is an non-zero integer if the path was expressed as bytes.
774 * The type is deliberately incompatible to prevent misuse.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700775 * path.fd
776 * Contains a file descriptor if path.accept_fd was true
777 * and the caller provided a signed integer instead of any
778 * sort of string.
779 *
780 * WARNING: if your "path" parameter is optional, and is
781 * unspecified, path_converter will never get called.
782 * So if you set allow_fd, you *MUST* initialize path.fd = -1
783 * yourself!
784 * path.length
785 * The length of the path in characters, if specified as
786 * a string.
787 * path.object
788 * The original object passed in.
789 * path.cleanup
790 * For internal use only. May point to a temporary object.
791 * (Pay no attention to the man behind the curtain.)
792 *
793 * At most one of path.wide or path.narrow will be non-NULL.
794 * If path was None and path.nullable was set,
795 * or if path was an integer and path.allow_fd was set,
796 * both path.wide and path.narrow will be NULL
797 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200798 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700799 * path_converter takes care to not write to the path_t
800 * unless it's successful. However it must reset the
801 * "cleanup" field each time it's called.
802 *
803 * Use as follows:
804 * path_t path;
805 * memset(&path, 0, sizeof(path));
806 * PyArg_ParseTuple(args, "O&", path_converter, &path);
807 * // ... use values from path ...
808 * path_cleanup(&path);
809 *
810 * (Note that if PyArg_Parse fails you don't need to call
811 * path_cleanup(). However it is safe to do so.)
812 */
813typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100814 const char *function_name;
815 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700816 int nullable;
817 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300818 const wchar_t *wide;
Steve Dowercc16be82016-09-08 10:35:16 -0700819#ifdef MS_WINDOWS
820 BOOL narrow;
821#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300822 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700823#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700824 int fd;
825 Py_ssize_t length;
826 PyObject *object;
827 PyObject *cleanup;
828} path_t;
829
Steve Dowercc16be82016-09-08 10:35:16 -0700830#ifdef MS_WINDOWS
831#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
832 {function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
833#else
Larry Hastings2f936352014-08-05 14:04:04 +1000834#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
835 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Steve Dowercc16be82016-09-08 10:35:16 -0700836#endif
Larry Hastings31826802013-10-19 00:09:25 -0700837
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838static void
839path_cleanup(path_t *path) {
840 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200841 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700842 }
843}
844
845static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300846path_converter(PyObject *o, void *p)
847{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700848 path_t *path = (path_t *)p;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700849 PyObject *bytes, *to_cleanup = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700850 Py_ssize_t length;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700851 int is_index, is_buffer, is_bytes, is_unicode;
852 /* Default to failure, forcing explicit signaling of succcess. */
853 int ret = 0;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300854 const char *narrow;
Steve Dowercc16be82016-09-08 10:35:16 -0700855#ifdef MS_WINDOWS
856 PyObject *wo;
857 const wchar_t *wide;
858#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700859
860#define FORMAT_EXCEPTION(exc, fmt) \
861 PyErr_Format(exc, "%s%s" fmt, \
862 path->function_name ? path->function_name : "", \
863 path->function_name ? ": " : "", \
864 path->argument_name ? path->argument_name : "path")
865
866 /* Py_CLEANUP_SUPPORTED support */
867 if (o == NULL) {
868 path_cleanup(path);
869 return 1;
870 }
871
Brett Cannon3f9183b2016-08-26 14:44:48 -0700872 /* Ensure it's always safe to call path_cleanup(). */
Larry Hastings9cf065c2012-06-22 16:30:09 -0700873 path->cleanup = NULL;
874
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300875 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700877#ifdef MS_WINDOWS
878 path->narrow = FALSE;
879#else
Larry Hastings9cf065c2012-06-22 16:30:09 -0700880 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700881#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700882 path->length = 0;
883 path->object = o;
884 path->fd = -1;
885 return 1;
886 }
887
Brett Cannon3f9183b2016-08-26 14:44:48 -0700888 /* Only call this here so that we don't treat the return value of
889 os.fspath() as an fd or buffer. */
890 is_index = path->allow_fd && PyIndex_Check(o);
891 is_buffer = PyObject_CheckBuffer(o);
892 is_bytes = PyBytes_Check(o);
893 is_unicode = PyUnicode_Check(o);
894
895 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
896 /* Inline PyOS_FSPath() for better error messages. */
897 _Py_IDENTIFIER(__fspath__);
898 PyObject *func = NULL;
899
900 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
901 if (NULL == func) {
902 goto error_exit;
903 }
904
905 o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL);
906 Py_DECREF(func);
907 if (NULL == o) {
908 goto error_exit;
909 }
910 else if (PyUnicode_Check(o)) {
911 is_unicode = 1;
912 }
913 else if (PyBytes_Check(o)) {
914 is_bytes = 1;
915 }
916 else {
917 goto error_exit;
918 }
919 }
920
921 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -0700923 wide = PyUnicode_AsWideCharString(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100924 if (!wide) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700925 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700926 }
Victor Stinner59799a82013-11-13 14:17:30 +0100927 if (length > 32767) {
928 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700929 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700930 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300931 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300932 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700933 goto exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300934 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700935
936 path->wide = wide;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700937 path->length = length;
938 path->object = o;
939 path->fd = -1;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700940 ret = 1;
941 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700942#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300943 if (!PyUnicode_FSConverter(o, &bytes)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700944 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300945 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946#endif
947 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700948 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300949 bytes = o;
950 Py_INCREF(bytes);
951 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300953 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
954 "%s%s%s should be %s, not %.200s",
955 path->function_name ? path->function_name : "",
956 path->function_name ? ": " : "",
957 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700958 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
959 "integer or None" :
960 path->allow_fd ? "string, bytes, os.PathLike or integer" :
961 path->nullable ? "string, bytes, os.PathLike or None" :
962 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300963 Py_TYPE(o)->tp_name)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700964 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300965 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300966 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 if (!bytes) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700968 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700969 }
970 }
Steve Dowercc16be82016-09-08 10:35:16 -0700971 else if (is_index) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300972 if (!_fd_converter(o, &path->fd)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700973 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300974 }
975 path->wide = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700976#ifdef MS_WINDOWS
977 path->narrow = FALSE;
978#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300979 path->narrow = NULL;
Steve Dowercc16be82016-09-08 10:35:16 -0700980#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300981 path->length = 0;
982 path->object = o;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700983 ret = 1;
984 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300985 }
986 else {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 error_exit:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300988 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
989 path->function_name ? path->function_name : "",
990 path->function_name ? ": " : "",
991 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700992 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
993 "integer or None" :
994 path->allow_fd ? "string, bytes, os.PathLike or integer" :
995 path->nullable ? "string, bytes, os.PathLike or None" :
996 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300997 Py_TYPE(o)->tp_name);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700998 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700999 }
1000
Larry Hastings9cf065c2012-06-22 16:30:09 -07001001 length = PyBytes_GET_SIZE(bytes);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001003 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001004 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -07001005 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001006 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 }
1008
Steve Dowercc16be82016-09-08 10:35:16 -07001009#ifdef MS_WINDOWS
1010 wo = PyUnicode_DecodeFSDefaultAndSize(
1011 narrow,
1012 length
1013 );
1014 if (!wo) {
1015 goto exit;
1016 }
1017
1018 wide = PyUnicode_AsWideCharString(wo, &length);
1019 Py_DECREF(wo);
1020
1021 if (!wide) {
1022 goto exit;
1023 }
1024 if (length > 32767) {
1025 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
1026 goto exit;
1027 }
1028 if (wcslen(wide) != length) {
1029 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
1030 goto exit;
1031 }
1032 path->wide = wide;
1033 path->narrow = TRUE;
1034#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07001035 path->wide = NULL;
1036 path->narrow = narrow;
Steve Dowercc16be82016-09-08 10:35:16 -07001037#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 path->length = length;
1039 path->object = o;
1040 path->fd = -1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001041 if (bytes == o) {
1042 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001043 ret = 1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001044 }
1045 else {
1046 path->cleanup = bytes;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001047 ret = Py_CLEANUP_SUPPORTED;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001048 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001049 exit:
1050 Py_XDECREF(to_cleanup);
1051 return ret;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052}
1053
1054static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001055argument_unavailable_error(const char *function_name, const char *argument_name)
1056{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001057 PyErr_Format(PyExc_NotImplementedError,
1058 "%s%s%s unavailable on this platform",
1059 (function_name != NULL) ? function_name : "",
1060 (function_name != NULL) ? ": ": "",
1061 argument_name);
1062}
1063
1064static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001065dir_fd_unavailable(PyObject *o, void *p)
1066{
1067 int dir_fd;
1068 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001069 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001070 if (dir_fd != DEFAULT_DIR_FD) {
1071 argument_unavailable_error(NULL, "dir_fd");
1072 return 0;
1073 }
1074 *(int *)p = dir_fd;
1075 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001076}
1077
1078static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001079fd_specified(const char *function_name, int fd)
1080{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001081 if (fd == -1)
1082 return 0;
1083
1084 argument_unavailable_error(function_name, "fd");
1085 return 1;
1086}
1087
1088static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001089follow_symlinks_specified(const char *function_name, int follow_symlinks)
1090{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001091 if (follow_symlinks)
1092 return 0;
1093
1094 argument_unavailable_error(function_name, "follow_symlinks");
1095 return 1;
1096}
1097
1098static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001099path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1100{
Steve Dowercc16be82016-09-08 10:35:16 -07001101 if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
1102#ifndef MS_WINDOWS
1103 && !path->narrow
1104#endif
1105 ) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07001106 PyErr_Format(PyExc_ValueError,
1107 "%s: can't specify dir_fd without matching path",
1108 function_name);
1109 return 1;
1110 }
1111 return 0;
1112}
1113
1114static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001115dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1116{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001117 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1118 PyErr_Format(PyExc_ValueError,
1119 "%s: can't specify both dir_fd and fd",
1120 function_name);
1121 return 1;
1122 }
1123 return 0;
1124}
1125
1126static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001127fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1128 int follow_symlinks)
1129{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001130 if ((fd > 0) && (!follow_symlinks)) {
1131 PyErr_Format(PyExc_ValueError,
1132 "%s: cannot use fd and follow_symlinks together",
1133 function_name);
1134 return 1;
1135 }
1136 return 0;
1137}
1138
1139static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001140dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1141 int follow_symlinks)
1142{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001143 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1144 PyErr_Format(PyExc_ValueError,
1145 "%s: cannot use dir_fd and follow_symlinks together",
1146 function_name);
1147 return 1;
1148 }
1149 return 0;
1150}
1151
Larry Hastings2f936352014-08-05 14:04:04 +10001152#ifdef MS_WINDOWS
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001153 typedef long long Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001154#else
Larry Hastings2f936352014-08-05 14:04:04 +10001155 typedef off_t Py_off_t;
1156#endif
1157
1158static int
1159Py_off_t_converter(PyObject *arg, void *addr)
1160{
1161#ifdef HAVE_LARGEFILE_SUPPORT
1162 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1163#else
1164 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001165#endif
1166 if (PyErr_Occurred())
1167 return 0;
1168 return 1;
1169}
Larry Hastings2f936352014-08-05 14:04:04 +10001170
1171static PyObject *
1172PyLong_FromPy_off_t(Py_off_t offset)
1173{
1174#ifdef HAVE_LARGEFILE_SUPPORT
1175 return PyLong_FromLongLong(offset);
1176#else
1177 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001178#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001179}
1180
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001181#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182
1183static int
Brian Curtind25aef52011-06-13 15:16:04 -05001184win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001185{
Martin Panter70214ad2016-08-04 02:38:59 +00001186 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1187 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001188 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001189
1190 if (0 == DeviceIoControl(
1191 reparse_point_handle,
1192 FSCTL_GET_REPARSE_POINT,
1193 NULL, 0, /* in buffer */
1194 target_buffer, sizeof(target_buffer),
1195 &n_bytes_returned,
1196 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001197 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001198
1199 if (reparse_tag)
1200 *reparse_tag = rdb->ReparseTag;
1201
Brian Curtind25aef52011-06-13 15:16:04 -05001202 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001203}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001204
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001205#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001206
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001207/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001208#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001209/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001210** environ directly, we must obtain it with _NSGetEnviron(). See also
1211** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001212*/
1213#include <crt_externs.h>
1214static char **environ;
1215#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001216extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001217#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218
Barry Warsaw53699e91996-12-10 23:23:01 +00001219static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001220convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221{
Victor Stinner8c62be82010-05-06 00:08:46 +00001222 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001223#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001224 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001225#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001226 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001227#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001228
Victor Stinner8c62be82010-05-06 00:08:46 +00001229 d = PyDict_New();
1230 if (d == NULL)
1231 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001232#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 if (environ == NULL)
1234 environ = *_NSGetEnviron();
1235#endif
1236#ifdef MS_WINDOWS
1237 /* _wenviron must be initialized in this way if the program is started
1238 through main() instead of wmain(). */
1239 _wgetenv(L"");
1240 if (_wenviron == NULL)
1241 return d;
1242 /* This part ignores errors */
1243 for (e = _wenviron; *e != NULL; e++) {
1244 PyObject *k;
1245 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001246 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001247 if (p == NULL)
1248 continue;
1249 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1250 if (k == NULL) {
1251 PyErr_Clear();
1252 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001253 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1255 if (v == NULL) {
1256 PyErr_Clear();
1257 Py_DECREF(k);
1258 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001259 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001260 if (PyDict_GetItem(d, k) == NULL) {
1261 if (PyDict_SetItem(d, k, v) != 0)
1262 PyErr_Clear();
1263 }
1264 Py_DECREF(k);
1265 Py_DECREF(v);
1266 }
1267#else
1268 if (environ == NULL)
1269 return d;
1270 /* This part ignores errors */
1271 for (e = environ; *e != NULL; e++) {
1272 PyObject *k;
1273 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001274 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001275 if (p == NULL)
1276 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001277 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 if (k == NULL) {
1279 PyErr_Clear();
1280 continue;
1281 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001282 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 if (v == NULL) {
1284 PyErr_Clear();
1285 Py_DECREF(k);
1286 continue;
1287 }
1288 if (PyDict_GetItem(d, k) == NULL) {
1289 if (PyDict_SetItem(d, k, v) != 0)
1290 PyErr_Clear();
1291 }
1292 Py_DECREF(k);
1293 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001294 }
1295#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001296 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001297}
1298
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299/* Set a POSIX-specific error from errno, and return NULL */
1300
Barry Warsawd58d7641998-07-23 16:14:40 +00001301static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001302posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001303{
Victor Stinner8c62be82010-05-06 00:08:46 +00001304 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001305}
Mark Hammondef8b6542001-05-13 08:04:26 +00001306
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001307#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001308static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001309win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001310{
Victor Stinner8c62be82010-05-06 00:08:46 +00001311 /* XXX We should pass the function name along in the future.
1312 (winreg.c also wants to pass the function name.)
1313 This would however require an additional param to the
1314 Windows error object, which is non-trivial.
1315 */
1316 errno = GetLastError();
1317 if (filename)
1318 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1319 else
1320 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001321}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001322
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001323static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001324win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001325{
1326 /* XXX - see win32_error for comments on 'function' */
1327 errno = GetLastError();
1328 if (filename)
1329 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001330 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001331 errno,
1332 filename);
1333 else
1334 return PyErr_SetFromWindowsErr(errno);
1335}
1336
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001337#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001338
Larry Hastings9cf065c2012-06-22 16:30:09 -07001339static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001340path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001341{
1342#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001343 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1344 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001345#else
Victor Stinner292c8352012-10-30 02:17:38 +01001346 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001347#endif
1348}
1349
Larry Hastings31826802013-10-19 00:09:25 -07001350
Larry Hastingsb0827312014-02-09 22:05:19 -08001351static PyObject *
1352path_error2(path_t *path, path_t *path2)
1353{
1354#ifdef MS_WINDOWS
1355 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1356 0, path->object, path2->object);
1357#else
1358 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1359 path->object, path2->object);
1360#endif
1361}
1362
1363
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001364/* POSIX generic methods */
1365
Larry Hastings2f936352014-08-05 14:04:04 +10001366static int
1367fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001368{
Victor Stinner8c62be82010-05-06 00:08:46 +00001369 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001370 int *pointer = (int *)p;
1371 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001373 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001374 *pointer = fd;
1375 return 1;
1376}
1377
1378static PyObject *
1379posix_fildes_fd(int fd, int (*func)(int))
1380{
1381 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001382 int async_err = 0;
1383
1384 do {
1385 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001386 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001387 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001388 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001389 Py_END_ALLOW_THREADS
1390 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1391 if (res != 0)
1392 return (!async_err) ? posix_error() : NULL;
1393 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001394}
Guido van Rossum21142a01999-01-08 21:05:37 +00001395
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001396
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001397#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001398/* This is a reimplementation of the C library's chdir function,
1399 but one that produces Win32 errors instead of DOS error codes.
1400 chdir is essentially a wrapper around SetCurrentDirectory; however,
1401 it also needs to set "magic" environment variables indicating
1402 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001403static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001404win32_wchdir(LPCWSTR path)
1405{
Victor Stinnered537822015-12-13 21:40:26 +01001406 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 int result;
1408 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001409
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 if(!SetCurrentDirectoryW(path))
1411 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001412 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 if (!result)
1414 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001415 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001416 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001417 if (!new_path) {
1418 SetLastError(ERROR_OUTOFMEMORY);
1419 return FALSE;
1420 }
1421 result = GetCurrentDirectoryW(result, new_path);
1422 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001423 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001424 return FALSE;
1425 }
1426 }
1427 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1428 wcsncmp(new_path, L"//", 2) == 0)
1429 /* UNC path, nothing to do. */
1430 return TRUE;
1431 env[1] = new_path[0];
1432 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001433 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001434 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001436}
1437#endif
1438
Martin v. Löwis14694662006-02-03 12:54:16 +00001439#ifdef MS_WINDOWS
1440/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1441 - time stamps are restricted to second resolution
1442 - file modification times suffer from forth-and-back conversions between
1443 UTC and local time
1444 Therefore, we implement our own stat, based on the Win32 API directly.
1445*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001446#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001447#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001448
Victor Stinner6036e442015-03-08 01:58:04 +01001449static void
Steve Dowercc16be82016-09-08 10:35:16 -07001450find_data_to_file_info(WIN32_FIND_DATAW *pFileData,
1451 BY_HANDLE_FILE_INFORMATION *info,
1452 ULONG *reparse_tag)
Victor Stinner6036e442015-03-08 01:58:04 +01001453{
1454 memset(info, 0, sizeof(*info));
1455 info->dwFileAttributes = pFileData->dwFileAttributes;
1456 info->ftCreationTime = pFileData->ftCreationTime;
1457 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1458 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1459 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1460 info->nFileSizeLow = pFileData->nFileSizeLow;
1461/* info->nNumberOfLinks = 1; */
1462 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1463 *reparse_tag = pFileData->dwReserved0;
1464 else
1465 *reparse_tag = 0;
1466}
1467
Guido van Rossumd8faa362007-04-27 19:54:29 +00001468static BOOL
Steve Dowercc16be82016-09-08 10:35:16 -07001469attributes_from_dir(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001470{
Victor Stinner8c62be82010-05-06 00:08:46 +00001471 HANDLE hFindFile;
1472 WIN32_FIND_DATAW FileData;
1473 hFindFile = FindFirstFileW(pszFile, &FileData);
1474 if (hFindFile == INVALID_HANDLE_VALUE)
1475 return FALSE;
1476 FindClose(hFindFile);
Steve Dowercc16be82016-09-08 10:35:16 -07001477 find_data_to_file_info(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001478 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001479}
1480
Brian Curtind25aef52011-06-13 15:16:04 -05001481static BOOL
1482get_target_path(HANDLE hdl, wchar_t **target_path)
1483{
1484 int buf_size, result_length;
1485 wchar_t *buf;
1486
1487 /* We have a good handle to the target, use it to determine
1488 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001489 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1490 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001491 if(!buf_size)
1492 return FALSE;
1493
Victor Stinnerc36674a2016-03-16 14:30:16 +01001494 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001495 if (!buf) {
1496 SetLastError(ERROR_OUTOFMEMORY);
1497 return FALSE;
1498 }
1499
Steve Dower2ea51c92015-03-20 21:49:12 -07001500 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001501 buf, buf_size, VOLUME_NAME_DOS);
1502
1503 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001504 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001505 return FALSE;
1506 }
1507
1508 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001509 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001510 return FALSE;
1511 }
1512
1513 buf[result_length] = 0;
1514
1515 *target_path = buf;
1516 return TRUE;
1517}
1518
1519static int
Steve Dowercc16be82016-09-08 10:35:16 -07001520win32_xstat_impl(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001521 BOOL traverse)
1522{
Victor Stinner26de69d2011-06-17 15:15:38 +02001523 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001524 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001525 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001527 wchar_t *target_path;
Steve Dowercc16be82016-09-08 10:35:16 -07001528 const wchar_t *dot;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529
Steve Dowercc16be82016-09-08 10:35:16 -07001530 hFile = CreateFileW(
Brian Curtinf5e76d02010-11-24 13:14:05 +00001531 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001532 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 0, /* share mode */
1534 NULL, /* security attributes */
1535 OPEN_EXISTING,
1536 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001537 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1538 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001539 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001540 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1541 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001542 NULL);
1543
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001545 /* Either the target doesn't exist, or we don't have access to
1546 get a handle to it. If the former, we need to return an error.
1547 If the latter, we can use attributes_from_dir. */
1548 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001549 return -1;
1550 /* Could not get attributes on open file. Fall back to
1551 reading the directory. */
1552 if (!attributes_from_dir(path, &info, &reparse_tag))
1553 /* Very strange. This should not fail now */
1554 return -1;
1555 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1556 if (traverse) {
1557 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001558 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001559 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001560 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001562 } else {
1563 if (!GetFileInformationByHandle(hFile, &info)) {
1564 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001565 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001566 }
1567 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001568 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1569 return -1;
1570
1571 /* Close the outer open file handle now that we're about to
1572 reopen it with different flags. */
1573 if (!CloseHandle(hFile))
1574 return -1;
1575
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001576 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001577 /* In order to call GetFinalPathNameByHandle we need to open
1578 the file without the reparse handling flag set. */
Brian Curtind25aef52011-06-13 15:16:04 -05001579 hFile2 = CreateFileW(
1580 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1581 NULL, OPEN_EXISTING,
1582 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1583 NULL);
1584 if (hFile2 == INVALID_HANDLE_VALUE)
1585 return -1;
1586
1587 if (!get_target_path(hFile2, &target_path))
1588 return -1;
1589
Steve Dowercc16be82016-09-08 10:35:16 -07001590 code = win32_xstat_impl(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001591 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 return code;
1593 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001594 } else
1595 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001596 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001597 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001598
1599 /* Set S_IEXEC if it is an .exe, .bat, ... */
1600 dot = wcsrchr(path, '.');
1601 if (dot) {
1602 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1603 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1604 result->st_mode |= 0111;
1605 }
1606 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607}
1608
1609static int
Steve Dowercc16be82016-09-08 10:35:16 -07001610win32_xstat(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001611{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001612 /* Protocol violation: we explicitly clear errno, instead of
1613 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001614 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001615 errno = 0;
1616 return code;
1617}
Brian Curtind25aef52011-06-13 15:16:04 -05001618/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001619
1620 In Posix, stat automatically traverses symlinks and returns the stat
1621 structure for the target. In Windows, the equivalent GetFileAttributes by
1622 default does not traverse symlinks and instead returns attributes for
1623 the symlink.
1624
1625 Therefore, win32_lstat will get the attributes traditionally, and
1626 win32_stat will first explicitly resolve the symlink target and then will
Steve Dowercc16be82016-09-08 10:35:16 -07001627 call win32_lstat on that result. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001628
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001629static int
Steve Dowercc16be82016-09-08 10:35:16 -07001630win32_lstat(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001631{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001632 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001633}
1634
Victor Stinner8c62be82010-05-06 00:08:46 +00001635static int
Steve Dowercc16be82016-09-08 10:35:16 -07001636win32_stat(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001637{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001638 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001639}
1640
Martin v. Löwis14694662006-02-03 12:54:16 +00001641#endif /* MS_WINDOWS */
1642
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001643PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001644"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001645This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001646 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001647or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1648\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001649Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1650or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001651\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001652See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001653
1654static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001655 {"st_mode", "protection bits"},
1656 {"st_ino", "inode"},
1657 {"st_dev", "device"},
1658 {"st_nlink", "number of hard links"},
1659 {"st_uid", "user ID of owner"},
1660 {"st_gid", "group ID of owner"},
1661 {"st_size", "total size, in bytes"},
1662 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1663 {NULL, "integer time of last access"},
1664 {NULL, "integer time of last modification"},
1665 {NULL, "integer time of last change"},
1666 {"st_atime", "time of last access"},
1667 {"st_mtime", "time of last modification"},
1668 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001669 {"st_atime_ns", "time of last access in nanoseconds"},
1670 {"st_mtime_ns", "time of last modification in nanoseconds"},
1671 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001672#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001673 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001674#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001675#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001676 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001677#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001678#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001679 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001680#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001681#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001682 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001683#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001684#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001685 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001686#endif
1687#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001688 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001689#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001690#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1691 {"st_file_attributes", "Windows file attribute bits"},
1692#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001693 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001694};
1695
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001696#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001697#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001698#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001699#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001700#endif
1701
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001702#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001703#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1704#else
1705#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1706#endif
1707
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001708#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001709#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1710#else
1711#define ST_RDEV_IDX ST_BLOCKS_IDX
1712#endif
1713
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001714#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1715#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1716#else
1717#define ST_FLAGS_IDX ST_RDEV_IDX
1718#endif
1719
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001720#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001721#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001722#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001723#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001724#endif
1725
1726#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1727#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1728#else
1729#define ST_BIRTHTIME_IDX ST_GEN_IDX
1730#endif
1731
Zachary Ware63f277b2014-06-19 09:46:37 -05001732#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1733#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1734#else
1735#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1736#endif
1737
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001738static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001739 "stat_result", /* name */
1740 stat_result__doc__, /* doc */
1741 stat_result_fields,
1742 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001743};
1744
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001745PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001746"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1747This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001748 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001749or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001750\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001751See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001752
1753static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001754 {"f_bsize", },
1755 {"f_frsize", },
1756 {"f_blocks", },
1757 {"f_bfree", },
1758 {"f_bavail", },
1759 {"f_files", },
1760 {"f_ffree", },
1761 {"f_favail", },
1762 {"f_flag", },
1763 {"f_namemax",},
1764 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765};
1766
1767static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 "statvfs_result", /* name */
1769 statvfs_result__doc__, /* doc */
1770 statvfs_result_fields,
1771 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001772};
1773
Ross Lagerwall7807c352011-03-17 20:20:30 +02001774#if defined(HAVE_WAITID) && !defined(__APPLE__)
1775PyDoc_STRVAR(waitid_result__doc__,
1776"waitid_result: Result from waitid.\n\n\
1777This object may be accessed either as a tuple of\n\
1778 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1779or via the attributes si_pid, si_uid, and so on.\n\
1780\n\
1781See os.waitid for more information.");
1782
1783static PyStructSequence_Field waitid_result_fields[] = {
1784 {"si_pid", },
1785 {"si_uid", },
1786 {"si_signo", },
1787 {"si_status", },
1788 {"si_code", },
1789 {0}
1790};
1791
1792static PyStructSequence_Desc waitid_result_desc = {
1793 "waitid_result", /* name */
1794 waitid_result__doc__, /* doc */
1795 waitid_result_fields,
1796 5
1797};
1798static PyTypeObject WaitidResultType;
1799#endif
1800
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001801static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001802static PyTypeObject StatResultType;
1803static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001804#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001805static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001806#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001807static newfunc structseq_new;
1808
1809static PyObject *
1810statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1811{
Victor Stinner8c62be82010-05-06 00:08:46 +00001812 PyStructSequence *result;
1813 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001814
Victor Stinner8c62be82010-05-06 00:08:46 +00001815 result = (PyStructSequence*)structseq_new(type, args, kwds);
1816 if (!result)
1817 return NULL;
1818 /* If we have been initialized from a tuple,
1819 st_?time might be set to None. Initialize it
1820 from the int slots. */
1821 for (i = 7; i <= 9; i++) {
1822 if (result->ob_item[i+3] == Py_None) {
1823 Py_DECREF(Py_None);
1824 Py_INCREF(result->ob_item[i]);
1825 result->ob_item[i+3] = result->ob_item[i];
1826 }
1827 }
1828 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001829}
1830
1831
1832
1833/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001834static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001835
1836PyDoc_STRVAR(stat_float_times__doc__,
1837"stat_float_times([newval]) -> oldval\n\n\
1838Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001839\n\
1840If value is True, future calls to stat() return floats; if it is False,\n\
1841future calls return ints.\n\
1842If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001843
Larry Hastings2f936352014-08-05 14:04:04 +10001844/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001845static PyObject*
1846stat_float_times(PyObject* self, PyObject *args)
1847{
Victor Stinner8c62be82010-05-06 00:08:46 +00001848 int newval = -1;
1849 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1850 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001851 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1852 "stat_float_times() is deprecated",
1853 1))
1854 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 if (newval == -1)
1856 /* Return old value */
1857 return PyBool_FromLong(_stat_float_times);
1858 _stat_float_times = newval;
1859 Py_INCREF(Py_None);
1860 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001861}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001862
Larry Hastings6fe20b32012-04-19 15:07:49 -07001863static PyObject *billion = NULL;
1864
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001865static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001866fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001867{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001868 PyObject *s = _PyLong_FromTime_t(sec);
1869 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1870 PyObject *s_in_ns = NULL;
1871 PyObject *ns_total = NULL;
1872 PyObject *float_s = NULL;
1873
1874 if (!(s && ns_fractional))
1875 goto exit;
1876
1877 s_in_ns = PyNumber_Multiply(s, billion);
1878 if (!s_in_ns)
1879 goto exit;
1880
1881 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1882 if (!ns_total)
1883 goto exit;
1884
Victor Stinner4195b5c2012-02-08 23:03:19 +01001885 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001886 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1887 if (!float_s)
1888 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001890 else {
1891 float_s = s;
1892 Py_INCREF(float_s);
1893 }
1894
1895 PyStructSequence_SET_ITEM(v, index, s);
1896 PyStructSequence_SET_ITEM(v, index+3, float_s);
1897 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1898 s = NULL;
1899 float_s = NULL;
1900 ns_total = NULL;
1901exit:
1902 Py_XDECREF(s);
1903 Py_XDECREF(ns_fractional);
1904 Py_XDECREF(s_in_ns);
1905 Py_XDECREF(ns_total);
1906 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001907}
1908
Tim Peters5aa91602002-01-30 05:46:57 +00001909/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001910 (used by posix_stat() and posix_fstat()) */
1911static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001912_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001913{
Victor Stinner8c62be82010-05-06 00:08:46 +00001914 unsigned long ansec, mnsec, cnsec;
1915 PyObject *v = PyStructSequence_New(&StatResultType);
1916 if (v == NULL)
1917 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001918
Victor Stinner8c62be82010-05-06 00:08:46 +00001919 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001920#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001921 PyStructSequence_SET_ITEM(v, 1,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001922 PyLong_FromLongLong((long long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001923#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001924 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00001925#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02001926#ifdef MS_WINDOWS
1927 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001928#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02001929 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00001930#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001931 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02001932#if defined(MS_WINDOWS)
1933 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
1934 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
1935#else
1936 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
1937 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
1938#endif
Fred Drake699f3522000-06-29 21:12:41 +00001939#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001940 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07001941 PyLong_FromLongLong((long long)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001942#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00001944#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001945
Martin v. Löwis14694662006-02-03 12:54:16 +00001946#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001947 ansec = st->st_atim.tv_nsec;
1948 mnsec = st->st_mtim.tv_nsec;
1949 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001950#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00001951 ansec = st->st_atimespec.tv_nsec;
1952 mnsec = st->st_mtimespec.tv_nsec;
1953 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00001954#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00001955 ansec = st->st_atime_nsec;
1956 mnsec = st->st_mtime_nsec;
1957 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001958#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001959 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001960#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001961 fill_time(v, 7, st->st_atime, ansec);
1962 fill_time(v, 8, st->st_mtime, mnsec);
1963 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001965#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
1967 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001968#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001969#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001970 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
1971 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001972#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001973#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
1975 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00001976#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001977#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
1979 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001980#endif
1981#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001982 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01001983 PyObject *val;
1984 unsigned long bsec,bnsec;
1985 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001986#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01001987 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001988#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01001989 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001990#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01001991 if (_stat_float_times) {
1992 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
1993 } else {
1994 val = PyLong_FromLong((long)bsec);
1995 }
1996 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
1997 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001999#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002000#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2002 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002003#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002004#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2005 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2006 PyLong_FromUnsignedLong(st->st_file_attributes));
2007#endif
Fred Drake699f3522000-06-29 21:12:41 +00002008
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 if (PyErr_Occurred()) {
2010 Py_DECREF(v);
2011 return NULL;
2012 }
Fred Drake699f3522000-06-29 21:12:41 +00002013
Victor Stinner8c62be82010-05-06 00:08:46 +00002014 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002015}
2016
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002017/* POSIX methods */
2018
Guido van Rossum94f6f721999-01-06 18:42:14 +00002019
2020static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002021posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002022 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002023{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002024 STRUCT_STAT st;
2025 int result;
2026
2027#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2028 if (follow_symlinks_specified(function_name, follow_symlinks))
2029 return NULL;
2030#endif
2031
2032 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2033 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2034 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2035 return NULL;
2036
2037 Py_BEGIN_ALLOW_THREADS
2038 if (path->fd != -1)
2039 result = FSTAT(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002040#ifdef MS_WINDOWS
Steve Dower513d7472016-09-08 10:41:50 -07002041 else if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -07002042 result = win32_stat(path->wide, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002043 else
Steve Dowercc16be82016-09-08 10:35:16 -07002044 result = win32_lstat(path->wide, &st);
2045#else
2046 else
2047#if defined(HAVE_LSTAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002048 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2049 result = LSTAT(path->narrow, &st);
2050 else
Steve Dowercc16be82016-09-08 10:35:16 -07002051#endif /* HAVE_LSTAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002052#ifdef HAVE_FSTATAT
2053 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2054 result = fstatat(dir_fd, path->narrow, &st,
2055 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2056 else
Steve Dowercc16be82016-09-08 10:35:16 -07002057#endif /* HAVE_FSTATAT */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002058 result = STAT(path->narrow, &st);
Steve Dowercc16be82016-09-08 10:35:16 -07002059#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002060 Py_END_ALLOW_THREADS
2061
Victor Stinner292c8352012-10-30 02:17:38 +01002062 if (result != 0) {
2063 return path_error(path);
2064 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002065
2066 return _pystat_fromstructstat(&st);
2067}
2068
Larry Hastings2f936352014-08-05 14:04:04 +10002069/*[python input]
2070
2071for s in """
2072
2073FACCESSAT
2074FCHMODAT
2075FCHOWNAT
2076FSTATAT
2077LINKAT
2078MKDIRAT
2079MKFIFOAT
2080MKNODAT
2081OPENAT
2082READLINKAT
2083SYMLINKAT
2084UNLINKAT
2085
2086""".strip().split():
2087 s = s.strip()
2088 print("""
2089#ifdef HAVE_{s}
2090 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002091#else
Larry Hastings2f936352014-08-05 14:04:04 +10002092 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002093#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002094""".rstrip().format(s=s))
2095
2096for s in """
2097
2098FCHDIR
2099FCHMOD
2100FCHOWN
2101FDOPENDIR
2102FEXECVE
2103FPATHCONF
2104FSTATVFS
2105FTRUNCATE
2106
2107""".strip().split():
2108 s = s.strip()
2109 print("""
2110#ifdef HAVE_{s}
2111 #define PATH_HAVE_{s} 1
2112#else
2113 #define PATH_HAVE_{s} 0
2114#endif
2115
2116""".rstrip().format(s=s))
2117[python start generated code]*/
2118
2119#ifdef HAVE_FACCESSAT
2120 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2121#else
2122 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2123#endif
2124
2125#ifdef HAVE_FCHMODAT
2126 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2127#else
2128 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2129#endif
2130
2131#ifdef HAVE_FCHOWNAT
2132 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2133#else
2134 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2135#endif
2136
2137#ifdef HAVE_FSTATAT
2138 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2139#else
2140 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2141#endif
2142
2143#ifdef HAVE_LINKAT
2144 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2145#else
2146 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2147#endif
2148
2149#ifdef HAVE_MKDIRAT
2150 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2151#else
2152 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2153#endif
2154
2155#ifdef HAVE_MKFIFOAT
2156 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2157#else
2158 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2159#endif
2160
2161#ifdef HAVE_MKNODAT
2162 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2163#else
2164 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2165#endif
2166
2167#ifdef HAVE_OPENAT
2168 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2169#else
2170 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2171#endif
2172
2173#ifdef HAVE_READLINKAT
2174 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2175#else
2176 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2177#endif
2178
2179#ifdef HAVE_SYMLINKAT
2180 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2181#else
2182 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2183#endif
2184
2185#ifdef HAVE_UNLINKAT
2186 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2187#else
2188 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2189#endif
2190
2191#ifdef HAVE_FCHDIR
2192 #define PATH_HAVE_FCHDIR 1
2193#else
2194 #define PATH_HAVE_FCHDIR 0
2195#endif
2196
2197#ifdef HAVE_FCHMOD
2198 #define PATH_HAVE_FCHMOD 1
2199#else
2200 #define PATH_HAVE_FCHMOD 0
2201#endif
2202
2203#ifdef HAVE_FCHOWN
2204 #define PATH_HAVE_FCHOWN 1
2205#else
2206 #define PATH_HAVE_FCHOWN 0
2207#endif
2208
2209#ifdef HAVE_FDOPENDIR
2210 #define PATH_HAVE_FDOPENDIR 1
2211#else
2212 #define PATH_HAVE_FDOPENDIR 0
2213#endif
2214
2215#ifdef HAVE_FEXECVE
2216 #define PATH_HAVE_FEXECVE 1
2217#else
2218 #define PATH_HAVE_FEXECVE 0
2219#endif
2220
2221#ifdef HAVE_FPATHCONF
2222 #define PATH_HAVE_FPATHCONF 1
2223#else
2224 #define PATH_HAVE_FPATHCONF 0
2225#endif
2226
2227#ifdef HAVE_FSTATVFS
2228 #define PATH_HAVE_FSTATVFS 1
2229#else
2230 #define PATH_HAVE_FSTATVFS 0
2231#endif
2232
2233#ifdef HAVE_FTRUNCATE
2234 #define PATH_HAVE_FTRUNCATE 1
2235#else
2236 #define PATH_HAVE_FTRUNCATE 0
2237#endif
2238/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002239
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002240#ifdef MS_WINDOWS
2241 #undef PATH_HAVE_FTRUNCATE
2242 #define PATH_HAVE_FTRUNCATE 1
2243#endif
Larry Hastings31826802013-10-19 00:09:25 -07002244
Larry Hastings61272b72014-01-07 12:41:53 -08002245/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002246
2247class path_t_converter(CConverter):
2248
2249 type = "path_t"
2250 impl_by_reference = True
2251 parse_by_reference = True
2252
2253 converter = 'path_converter'
2254
2255 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002256 # right now path_t doesn't support default values.
2257 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002258 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002259 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002260
Larry Hastings2f936352014-08-05 14:04:04 +10002261 if self.c_default not in (None, 'Py_None'):
2262 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002263
2264 self.nullable = nullable
2265 self.allow_fd = allow_fd
2266
Larry Hastings7726ac92014-01-31 22:03:12 -08002267 def pre_render(self):
2268 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002269 if isinstance(value, str):
2270 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002271 return str(int(bool(value)))
2272
2273 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002274 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002275 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002276 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002277 strify(self.nullable),
2278 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002279 )
2280
2281 def cleanup(self):
2282 return "path_cleanup(&" + self.name + ");\n"
2283
2284
2285class dir_fd_converter(CConverter):
2286 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002287
Larry Hastings2f936352014-08-05 14:04:04 +10002288 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002289 if self.default in (unspecified, None):
2290 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002291 if isinstance(requires, str):
2292 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2293 else:
2294 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002295
Larry Hastings2f936352014-08-05 14:04:04 +10002296class fildes_converter(CConverter):
2297 type = 'int'
2298 converter = 'fildes_converter'
2299
2300class uid_t_converter(CConverter):
2301 type = "uid_t"
2302 converter = '_Py_Uid_Converter'
2303
2304class gid_t_converter(CConverter):
2305 type = "gid_t"
2306 converter = '_Py_Gid_Converter'
2307
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002308class dev_t_converter(CConverter):
2309 type = 'dev_t'
2310 converter = '_Py_Dev_Converter'
2311
2312class dev_t_return_converter(unsigned_long_return_converter):
2313 type = 'dev_t'
2314 conversion_fn = '_PyLong_FromDev'
2315 unsigned_cast = '(dev_t)'
2316
Larry Hastings2f936352014-08-05 14:04:04 +10002317class FSConverter_converter(CConverter):
2318 type = 'PyObject *'
2319 converter = 'PyUnicode_FSConverter'
2320 def converter_init(self):
2321 if self.default is not unspecified:
2322 fail("FSConverter_converter does not support default values")
2323 self.c_default = 'NULL'
2324
2325 def cleanup(self):
2326 return "Py_XDECREF(" + self.name + ");\n"
2327
2328class pid_t_converter(CConverter):
2329 type = 'pid_t'
2330 format_unit = '" _Py_PARSE_PID "'
2331
2332class idtype_t_converter(int_converter):
2333 type = 'idtype_t'
2334
2335class id_t_converter(CConverter):
2336 type = 'id_t'
2337 format_unit = '" _Py_PARSE_PID "'
2338
Benjamin Petersonca470632016-09-06 13:47:26 -07002339class intptr_t_converter(CConverter):
2340 type = 'intptr_t'
Larry Hastings2f936352014-08-05 14:04:04 +10002341 format_unit = '" _Py_PARSE_INTPTR "'
2342
2343class Py_off_t_converter(CConverter):
2344 type = 'Py_off_t'
2345 converter = 'Py_off_t_converter'
2346
2347class Py_off_t_return_converter(long_return_converter):
2348 type = 'Py_off_t'
2349 conversion_fn = 'PyLong_FromPy_off_t'
2350
2351class path_confname_converter(CConverter):
2352 type="int"
2353 converter="conv_path_confname"
2354
2355class confstr_confname_converter(path_confname_converter):
2356 converter='conv_confstr_confname'
2357
2358class sysconf_confname_converter(path_confname_converter):
2359 converter="conv_sysconf_confname"
2360
2361class sched_param_converter(CConverter):
2362 type = 'struct sched_param'
2363 converter = 'convert_sched_param'
2364 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002365
Larry Hastings61272b72014-01-07 12:41:53 -08002366[python start generated code]*/
Victor Stinner581139c2016-09-06 15:54:20 -07002367/*[python end generated code: output=da39a3ee5e6b4b0d input=418fce0e01144461]*/
Larry Hastings31826802013-10-19 00:09:25 -07002368
Larry Hastings61272b72014-01-07 12:41:53 -08002369/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002370
Larry Hastings2a727912014-01-16 11:32:01 -08002371os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002372
2373 path : path_t(allow_fd=True)
2374 Path to be examined; can be string, bytes, or open-file-descriptor int.
2375
2376 *
2377
Larry Hastings2f936352014-08-05 14:04:04 +10002378 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002379 If not None, it should be a file descriptor open to a directory,
2380 and path should be a relative string; path will then be relative to
2381 that directory.
2382
2383 follow_symlinks: bool = True
2384 If False, and the last element of the path is a symbolic link,
2385 stat will examine the symbolic link itself instead of the file
2386 the link points to.
2387
2388Perform a stat system call on the given path.
2389
2390dir_fd and follow_symlinks may not be implemented
2391 on your platform. If they are unavailable, using them will raise a
2392 NotImplementedError.
2393
2394It's an error to use dir_fd or follow_symlinks when specifying path as
2395 an open file descriptor.
2396
Larry Hastings61272b72014-01-07 12:41:53 -08002397[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002398
Larry Hastings31826802013-10-19 00:09:25 -07002399static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002400os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2401/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002402{
2403 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2404}
2405
Larry Hastings2f936352014-08-05 14:04:04 +10002406
2407/*[clinic input]
2408os.lstat
2409
2410 path : path_t
2411
2412 *
2413
2414 dir_fd : dir_fd(requires='fstatat') = None
2415
2416Perform a stat system call on the given path, without following symbolic links.
2417
2418Like stat(), but do not follow symbolic links.
2419Equivalent to stat(path, follow_symlinks=False).
2420[clinic start generated code]*/
2421
Larry Hastings2f936352014-08-05 14:04:04 +10002422static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002423os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2424/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002425{
2426 int follow_symlinks = 0;
2427 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2428}
Larry Hastings31826802013-10-19 00:09:25 -07002429
Larry Hastings2f936352014-08-05 14:04:04 +10002430
Larry Hastings61272b72014-01-07 12:41:53 -08002431/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002432os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002433
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002434 path: path_t
2435 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002436
2437 mode: int
2438 Operating-system mode bitfield. Can be F_OK to test existence,
2439 or the inclusive-OR of R_OK, W_OK, and X_OK.
2440
2441 *
2442
Larry Hastings2f936352014-08-05 14:04:04 +10002443 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002444 If not None, it should be a file descriptor open to a directory,
2445 and path should be relative; path will then be relative to that
2446 directory.
2447
2448 effective_ids: bool = False
2449 If True, access will use the effective uid/gid instead of
2450 the real uid/gid.
2451
2452 follow_symlinks: bool = True
2453 If False, and the last element of the path is a symbolic link,
2454 access will examine the symbolic link itself instead of the file
2455 the link points to.
2456
2457Use the real uid/gid to test for access to a path.
2458
2459{parameters}
2460dir_fd, effective_ids, and follow_symlinks may not be implemented
2461 on your platform. If they are unavailable, using them will raise a
2462 NotImplementedError.
2463
2464Note that most operations will use the effective uid/gid, therefore this
2465 routine can be used in a suid/sgid environment to test if the invoking user
2466 has the specified access to the path.
2467
Larry Hastings61272b72014-01-07 12:41:53 -08002468[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002469
Larry Hastings2f936352014-08-05 14:04:04 +10002470static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002471os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002472 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002473/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002474{
Larry Hastings2f936352014-08-05 14:04:04 +10002475 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002476
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002477#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002478 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002479#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002480 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002481#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002482
Larry Hastings9cf065c2012-06-22 16:30:09 -07002483#ifndef HAVE_FACCESSAT
2484 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002485 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002486
2487 if (effective_ids) {
2488 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002489 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002490 }
2491#endif
2492
2493#ifdef MS_WINDOWS
2494 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002495 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002496 Py_END_ALLOW_THREADS
2497
2498 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002499 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002500 * * we didn't get a -1, and
2501 * * write access wasn't requested,
2502 * * or the file isn't read-only,
2503 * * or it's a directory.
2504 * (Directories cannot be read-only on Windows.)
2505 */
Larry Hastings2f936352014-08-05 14:04:04 +10002506 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002507 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002508 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002509 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002510#else
2511
2512 Py_BEGIN_ALLOW_THREADS
2513#ifdef HAVE_FACCESSAT
2514 if ((dir_fd != DEFAULT_DIR_FD) ||
2515 effective_ids ||
2516 !follow_symlinks) {
2517 int flags = 0;
2518 if (!follow_symlinks)
2519 flags |= AT_SYMLINK_NOFOLLOW;
2520 if (effective_ids)
2521 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002522 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002523 }
2524 else
2525#endif
Larry Hastings31826802013-10-19 00:09:25 -07002526 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002527 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002528 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002529#endif
2530
Larry Hastings9cf065c2012-06-22 16:30:09 -07002531 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002532}
2533
Guido van Rossumd371ff11999-01-25 16:12:23 +00002534#ifndef F_OK
2535#define F_OK 0
2536#endif
2537#ifndef R_OK
2538#define R_OK 4
2539#endif
2540#ifndef W_OK
2541#define W_OK 2
2542#endif
2543#ifndef X_OK
2544#define X_OK 1
2545#endif
2546
Larry Hastings31826802013-10-19 00:09:25 -07002547
Guido van Rossumd371ff11999-01-25 16:12:23 +00002548#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002549/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002550os.ttyname -> DecodeFSDefault
2551
2552 fd: int
2553 Integer file descriptor handle.
2554
2555 /
2556
2557Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002558[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559
Larry Hastings31826802013-10-19 00:09:25 -07002560static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002561os_ttyname_impl(PyObject *module, int fd)
2562/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002563{
2564 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002565
Larry Hastings31826802013-10-19 00:09:25 -07002566 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002567 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002568 posix_error();
2569 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002570}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002571#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002572
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002573#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002574/*[clinic input]
2575os.ctermid
2576
2577Return the name of the controlling terminal for this process.
2578[clinic start generated code]*/
2579
Larry Hastings2f936352014-08-05 14:04:04 +10002580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002581os_ctermid_impl(PyObject *module)
2582/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002583{
Victor Stinner8c62be82010-05-06 00:08:46 +00002584 char *ret;
2585 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002586
Greg Wardb48bc172000-03-01 21:51:56 +00002587#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002588 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002589#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002590 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002591#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002592 if (ret == NULL)
2593 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002594 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002595}
Larry Hastings2f936352014-08-05 14:04:04 +10002596#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002597
Larry Hastings2f936352014-08-05 14:04:04 +10002598
2599/*[clinic input]
2600os.chdir
2601
2602 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2603
2604Change the current working directory to the specified path.
2605
2606path may always be specified as a string.
2607On some platforms, path may also be specified as an open file descriptor.
2608 If this functionality is unavailable, using it raises an exception.
2609[clinic start generated code]*/
2610
Larry Hastings2f936352014-08-05 14:04:04 +10002611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002612os_chdir_impl(PyObject *module, path_t *path)
2613/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002614{
2615 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002616
2617 Py_BEGIN_ALLOW_THREADS
2618#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07002619 /* on unix, success = 0, on windows, success = !0 */
2620 result = !win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002621#else
2622#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002623 if (path->fd != -1)
2624 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002625 else
2626#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002627 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628#endif
2629 Py_END_ALLOW_THREADS
2630
2631 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002632 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633 }
2634
Larry Hastings2f936352014-08-05 14:04:04 +10002635 Py_RETURN_NONE;
2636}
2637
2638
2639#ifdef HAVE_FCHDIR
2640/*[clinic input]
2641os.fchdir
2642
2643 fd: fildes
2644
2645Change to the directory of the given file descriptor.
2646
2647fd must be opened on a directory, not a file.
2648Equivalent to os.chdir(fd).
2649
2650[clinic start generated code]*/
2651
Fred Drake4d1e64b2002-04-15 19:40:07 +00002652static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002653os_fchdir_impl(PyObject *module, int fd)
2654/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002655{
Larry Hastings2f936352014-08-05 14:04:04 +10002656 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002657}
2658#endif /* HAVE_FCHDIR */
2659
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002660
Larry Hastings2f936352014-08-05 14:04:04 +10002661/*[clinic input]
2662os.chmod
2663
2664 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2665 Path to be modified. May always be specified as a str or bytes.
2666 On some platforms, path may also be specified as an open file descriptor.
2667 If this functionality is unavailable, using it raises an exception.
2668
2669 mode: int
2670 Operating-system mode bitfield.
2671
2672 *
2673
2674 dir_fd : dir_fd(requires='fchmodat') = None
2675 If not None, it should be a file descriptor open to a directory,
2676 and path should be relative; path will then be relative to that
2677 directory.
2678
2679 follow_symlinks: bool = True
2680 If False, and the last element of the path is a symbolic link,
2681 chmod will modify the symbolic link itself instead of the file
2682 the link points to.
2683
2684Change the access permissions of a file.
2685
2686It is an error to use dir_fd or follow_symlinks when specifying path as
2687 an open file descriptor.
2688dir_fd and follow_symlinks may not be implemented on your platform.
2689 If they are unavailable, using them will raise a NotImplementedError.
2690
2691[clinic start generated code]*/
2692
Larry Hastings2f936352014-08-05 14:04:04 +10002693static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002694os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002695 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002696/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002697{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002698 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002699
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002700#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002701 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002703
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704#ifdef HAVE_FCHMODAT
2705 int fchmodat_nofollow_unsupported = 0;
2706#endif
2707
Larry Hastings9cf065c2012-06-22 16:30:09 -07002708#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2709 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002710 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711#endif
2712
2713#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002714 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07002715 attr = GetFileAttributesW(path->wide);
Tim Golden23005082013-10-25 11:22:37 +01002716 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717 result = 0;
2718 else {
2719 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002720 attr &= ~FILE_ATTRIBUTE_READONLY;
2721 else
2722 attr |= FILE_ATTRIBUTE_READONLY;
Steve Dowercc16be82016-09-08 10:35:16 -07002723 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724 }
2725 Py_END_ALLOW_THREADS
2726
2727 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002728 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 }
2730#else /* MS_WINDOWS */
2731 Py_BEGIN_ALLOW_THREADS
2732#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002733 if (path->fd != -1)
2734 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002735 else
2736#endif
2737#ifdef HAVE_LCHMOD
2738 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002739 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002740 else
2741#endif
2742#ifdef HAVE_FCHMODAT
2743 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2744 /*
2745 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2746 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002747 * and then says it isn't implemented yet.
2748 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002749 *
2750 * Once it is supported, os.chmod will automatically
2751 * support dir_fd and follow_symlinks=False. (Hopefully.)
2752 * Until then, we need to be careful what exception we raise.
2753 */
Larry Hastings2f936352014-08-05 14:04:04 +10002754 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002755 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2756 /*
2757 * But wait! We can't throw the exception without allowing threads,
2758 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2759 */
2760 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002761 result &&
2762 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2763 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002764 }
2765 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002766#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002767 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002768 Py_END_ALLOW_THREADS
2769
2770 if (result) {
2771#ifdef HAVE_FCHMODAT
2772 if (fchmodat_nofollow_unsupported) {
2773 if (dir_fd != DEFAULT_DIR_FD)
2774 dir_fd_and_follow_symlinks_invalid("chmod",
2775 dir_fd, follow_symlinks);
2776 else
2777 follow_symlinks_specified("chmod", follow_symlinks);
2778 }
2779 else
2780#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002781 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782 }
2783#endif
2784
Larry Hastings2f936352014-08-05 14:04:04 +10002785 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002786}
2787
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788
Christian Heimes4e30a842007-11-30 22:12:06 +00002789#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002790/*[clinic input]
2791os.fchmod
2792
2793 fd: int
2794 mode: int
2795
2796Change the access permissions of the file given by file descriptor fd.
2797
2798Equivalent to os.chmod(fd, mode).
2799[clinic start generated code]*/
2800
Larry Hastings2f936352014-08-05 14:04:04 +10002801static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002802os_fchmod_impl(PyObject *module, int fd, int mode)
2803/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002804{
2805 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002806 int async_err = 0;
2807
2808 do {
2809 Py_BEGIN_ALLOW_THREADS
2810 res = fchmod(fd, mode);
2811 Py_END_ALLOW_THREADS
2812 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2813 if (res != 0)
2814 return (!async_err) ? posix_error() : NULL;
2815
Victor Stinner8c62be82010-05-06 00:08:46 +00002816 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002817}
2818#endif /* HAVE_FCHMOD */
2819
Larry Hastings2f936352014-08-05 14:04:04 +10002820
Christian Heimes4e30a842007-11-30 22:12:06 +00002821#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002822/*[clinic input]
2823os.lchmod
2824
2825 path: path_t
2826 mode: int
2827
2828Change the access permissions of a file, without following symbolic links.
2829
2830If path is a symlink, this affects the link itself rather than the target.
2831Equivalent to chmod(path, mode, follow_symlinks=False)."
2832[clinic start generated code]*/
2833
Larry Hastings2f936352014-08-05 14:04:04 +10002834static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002835os_lchmod_impl(PyObject *module, path_t *path, int mode)
2836/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002837{
Victor Stinner8c62be82010-05-06 00:08:46 +00002838 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002839 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002840 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002841 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002842 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002843 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002844 return NULL;
2845 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002846 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002847}
2848#endif /* HAVE_LCHMOD */
2849
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002850
Thomas Wouterscf297e42007-02-23 15:07:44 +00002851#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002852/*[clinic input]
2853os.chflags
2854
2855 path: path_t
2856 flags: unsigned_long(bitwise=True)
2857 follow_symlinks: bool=True
2858
2859Set file flags.
2860
2861If follow_symlinks is False, and the last element of the path is a symbolic
2862 link, chflags will change flags on the symbolic link itself instead of the
2863 file the link points to.
2864follow_symlinks may not be implemented on your platform. If it is
2865unavailable, using it will raise a NotImplementedError.
2866
2867[clinic start generated code]*/
2868
Larry Hastings2f936352014-08-05 14:04:04 +10002869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002870os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002871 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002872/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002873{
2874 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002875
2876#ifndef HAVE_LCHFLAGS
2877 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002878 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879#endif
2880
Victor Stinner8c62be82010-05-06 00:08:46 +00002881 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882#ifdef HAVE_LCHFLAGS
2883 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002884 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885 else
2886#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002887 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002888 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002889
Larry Hastings2f936352014-08-05 14:04:04 +10002890 if (result)
2891 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892
Larry Hastings2f936352014-08-05 14:04:04 +10002893 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002894}
2895#endif /* HAVE_CHFLAGS */
2896
Larry Hastings2f936352014-08-05 14:04:04 +10002897
Thomas Wouterscf297e42007-02-23 15:07:44 +00002898#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002899/*[clinic input]
2900os.lchflags
2901
2902 path: path_t
2903 flags: unsigned_long(bitwise=True)
2904
2905Set file flags.
2906
2907This function will not follow symbolic links.
2908Equivalent to chflags(path, flags, follow_symlinks=False).
2909[clinic start generated code]*/
2910
Larry Hastings2f936352014-08-05 14:04:04 +10002911static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002912os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
2913/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002914{
Victor Stinner8c62be82010-05-06 00:08:46 +00002915 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002917 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002919 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002920 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002921 }
Victor Stinner292c8352012-10-30 02:17:38 +01002922 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002923}
2924#endif /* HAVE_LCHFLAGS */
2925
Larry Hastings2f936352014-08-05 14:04:04 +10002926
Martin v. Löwis244edc82001-10-04 22:44:26 +00002927#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10002928/*[clinic input]
2929os.chroot
2930 path: path_t
2931
2932Change root directory to path.
2933
2934[clinic start generated code]*/
2935
Larry Hastings2f936352014-08-05 14:04:04 +10002936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937os_chroot_impl(PyObject *module, path_t *path)
2938/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002939{
2940 int res;
2941 Py_BEGIN_ALLOW_THREADS
2942 res = chroot(path->narrow);
2943 Py_END_ALLOW_THREADS
2944 if (res < 0)
2945 return path_error(path);
2946 Py_RETURN_NONE;
2947}
2948#endif /* HAVE_CHROOT */
2949
Martin v. Löwis244edc82001-10-04 22:44:26 +00002950
Guido van Rossum21142a01999-01-08 21:05:37 +00002951#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002952/*[clinic input]
2953os.fsync
2954
2955 fd: fildes
2956
2957Force write of fd to disk.
2958[clinic start generated code]*/
2959
Larry Hastings2f936352014-08-05 14:04:04 +10002960static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002961os_fsync_impl(PyObject *module, int fd)
2962/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002963{
2964 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00002965}
2966#endif /* HAVE_FSYNC */
2967
Larry Hastings2f936352014-08-05 14:04:04 +10002968
Ross Lagerwall7807c352011-03-17 20:20:30 +02002969#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10002970/*[clinic input]
2971os.sync
2972
2973Force write of everything to disk.
2974[clinic start generated code]*/
2975
Larry Hastings2f936352014-08-05 14:04:04 +10002976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002977os_sync_impl(PyObject *module)
2978/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02002979{
2980 Py_BEGIN_ALLOW_THREADS
2981 sync();
2982 Py_END_ALLOW_THREADS
2983 Py_RETURN_NONE;
2984}
Larry Hastings2f936352014-08-05 14:04:04 +10002985#endif /* HAVE_SYNC */
2986
Ross Lagerwall7807c352011-03-17 20:20:30 +02002987
Guido van Rossum21142a01999-01-08 21:05:37 +00002988#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00002989#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00002990extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
2991#endif
2992
Larry Hastings2f936352014-08-05 14:04:04 +10002993/*[clinic input]
2994os.fdatasync
2995
2996 fd: fildes
2997
2998Force write of fd to disk without forcing update of metadata.
2999[clinic start generated code]*/
3000
Larry Hastings2f936352014-08-05 14:04:04 +10003001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003002os_fdatasync_impl(PyObject *module, int fd)
3003/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003004{
3005 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003006}
3007#endif /* HAVE_FDATASYNC */
3008
3009
Fredrik Lundh10723342000-07-10 16:38:09 +00003010#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003011/*[clinic input]
3012os.chown
3013
3014 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3015 Path to be examined; can be string, bytes, or open-file-descriptor int.
3016
3017 uid: uid_t
3018
3019 gid: gid_t
3020
3021 *
3022
3023 dir_fd : dir_fd(requires='fchownat') = None
3024 If not None, it should be a file descriptor open to a directory,
3025 and path should be relative; path will then be relative to that
3026 directory.
3027
3028 follow_symlinks: bool = True
3029 If False, and the last element of the path is a symbolic link,
3030 stat will examine the symbolic link itself instead of the file
3031 the link points to.
3032
3033Change the owner and group id of path to the numeric uid and gid.\
3034
3035path may always be specified as a string.
3036On some platforms, path may also be specified as an open file descriptor.
3037 If this functionality is unavailable, using it raises an exception.
3038If dir_fd is not None, it should be a file descriptor open to a directory,
3039 and path should be relative; path will then be relative to that directory.
3040If follow_symlinks is False, and the last element of the path is a symbolic
3041 link, chown will modify the symbolic link itself instead of the file the
3042 link points to.
3043It is an error to use dir_fd or follow_symlinks when specifying path as
3044 an open file descriptor.
3045dir_fd and follow_symlinks may not be implemented on your platform.
3046 If they are unavailable, using them will raise a NotImplementedError.
3047
3048[clinic start generated code]*/
3049
Larry Hastings2f936352014-08-05 14:04:04 +10003050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003051os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003052 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003053/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003054{
3055 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003056
3057#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3058 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003059 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003060#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003061 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3062 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3063 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003064
3065#ifdef __APPLE__
3066 /*
3067 * This is for Mac OS X 10.3, which doesn't have lchown.
3068 * (But we still have an lchown symbol because of weak-linking.)
3069 * It doesn't have fchownat either. So there's no possibility
3070 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003071 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003072 if ((!follow_symlinks) && (lchown == NULL)) {
3073 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003074 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003075 }
3076#endif
3077
Victor Stinner8c62be82010-05-06 00:08:46 +00003078 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003079#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003080 if (path->fd != -1)
3081 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003082 else
3083#endif
3084#ifdef HAVE_LCHOWN
3085 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003086 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003087 else
3088#endif
3089#ifdef HAVE_FCHOWNAT
3090 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003091 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003092 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3093 else
3094#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003095 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003096 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003097
Larry Hastings2f936352014-08-05 14:04:04 +10003098 if (result)
3099 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003100
Larry Hastings2f936352014-08-05 14:04:04 +10003101 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003102}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003103#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003104
Larry Hastings2f936352014-08-05 14:04:04 +10003105
Christian Heimes4e30a842007-11-30 22:12:06 +00003106#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003107/*[clinic input]
3108os.fchown
3109
3110 fd: int
3111 uid: uid_t
3112 gid: gid_t
3113
3114Change the owner and group id of the file specified by file descriptor.
3115
3116Equivalent to os.chown(fd, uid, gid).
3117
3118[clinic start generated code]*/
3119
Larry Hastings2f936352014-08-05 14:04:04 +10003120static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003121os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3122/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003123{
Victor Stinner8c62be82010-05-06 00:08:46 +00003124 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003125 int async_err = 0;
3126
3127 do {
3128 Py_BEGIN_ALLOW_THREADS
3129 res = fchown(fd, uid, gid);
3130 Py_END_ALLOW_THREADS
3131 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3132 if (res != 0)
3133 return (!async_err) ? posix_error() : NULL;
3134
Victor Stinner8c62be82010-05-06 00:08:46 +00003135 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003136}
3137#endif /* HAVE_FCHOWN */
3138
Larry Hastings2f936352014-08-05 14:04:04 +10003139
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003140#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003141/*[clinic input]
3142os.lchown
3143
3144 path : path_t
3145 uid: uid_t
3146 gid: gid_t
3147
3148Change the owner and group id of path to the numeric uid and gid.
3149
3150This function will not follow symbolic links.
3151Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3152[clinic start generated code]*/
3153
Larry Hastings2f936352014-08-05 14:04:04 +10003154static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003155os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3156/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003157{
Victor Stinner8c62be82010-05-06 00:08:46 +00003158 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003159 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003160 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003161 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003162 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003163 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003164 }
Larry Hastings2f936352014-08-05 14:04:04 +10003165 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003166}
3167#endif /* HAVE_LCHOWN */
3168
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003169
Barry Warsaw53699e91996-12-10 23:23:01 +00003170static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003171posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003172{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003173 char *buf, *tmpbuf;
3174 char *cwd;
3175 const size_t chunk = 1024;
3176 size_t buflen = 0;
3177 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003178
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003179#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003181 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 wchar_t *wbuf2 = wbuf;
3183 PyObject *resobj;
3184 DWORD len;
3185 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003186 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003187 /* If the buffer is large enough, len does not include the
3188 terminating \0. If the buffer is too small, len includes
3189 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003190 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003191 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003192 if (wbuf2)
3193 len = GetCurrentDirectoryW(len, wbuf2);
3194 }
3195 Py_END_ALLOW_THREADS
3196 if (!wbuf2) {
3197 PyErr_NoMemory();
3198 return NULL;
3199 }
3200 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003201 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003202 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003203 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003204 }
3205 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003206 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003207 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003208 return resobj;
3209 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003210
3211 if (win32_warn_bytes_api())
3212 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003213#endif
3214
Victor Stinner4403d7d2015-04-25 00:16:10 +02003215 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003216 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003217 do {
3218 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003219#ifdef MS_WINDOWS
3220 if (buflen > INT_MAX) {
3221 PyErr_NoMemory();
3222 break;
3223 }
3224#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003225 tmpbuf = PyMem_RawRealloc(buf, buflen);
3226 if (tmpbuf == NULL)
3227 break;
3228
3229 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003230#ifdef MS_WINDOWS
3231 cwd = getcwd(buf, (int)buflen);
3232#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003233 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003234#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003235 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003236 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003237
3238 if (cwd == NULL) {
3239 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003241 }
3242
Victor Stinner8c62be82010-05-06 00:08:46 +00003243 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003244 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3245 else
3246 obj = PyUnicode_DecodeFSDefault(buf);
3247 PyMem_RawFree(buf);
3248
3249 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003250}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003251
Larry Hastings2f936352014-08-05 14:04:04 +10003252
3253/*[clinic input]
3254os.getcwd
3255
3256Return a unicode string representing the current working directory.
3257[clinic start generated code]*/
3258
Larry Hastings2f936352014-08-05 14:04:04 +10003259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003260os_getcwd_impl(PyObject *module)
3261/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003262{
3263 return posix_getcwd(0);
3264}
3265
Larry Hastings2f936352014-08-05 14:04:04 +10003266
3267/*[clinic input]
3268os.getcwdb
3269
3270Return a bytes string representing the current working directory.
3271[clinic start generated code]*/
3272
Larry Hastings2f936352014-08-05 14:04:04 +10003273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003274os_getcwdb_impl(PyObject *module)
3275/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003276{
3277 return posix_getcwd(1);
3278}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003279
Larry Hastings2f936352014-08-05 14:04:04 +10003280
Larry Hastings9cf065c2012-06-22 16:30:09 -07003281#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3282#define HAVE_LINK 1
3283#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003284
Guido van Rossumb6775db1994-08-01 11:34:53 +00003285#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003286/*[clinic input]
3287
3288os.link
3289
3290 src : path_t
3291 dst : path_t
3292 *
3293 src_dir_fd : dir_fd = None
3294 dst_dir_fd : dir_fd = None
3295 follow_symlinks: bool = True
3296
3297Create a hard link to a file.
3298
3299If either src_dir_fd or dst_dir_fd is not None, it should be a file
3300 descriptor open to a directory, and the respective path string (src or dst)
3301 should be relative; the path will then be relative to that directory.
3302If follow_symlinks is False, and the last element of src is a symbolic
3303 link, link will create a link to the symbolic link itself instead of the
3304 file the link points to.
3305src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3306 platform. If they are unavailable, using them will raise a
3307 NotImplementedError.
3308[clinic start generated code]*/
3309
Larry Hastings2f936352014-08-05 14:04:04 +10003310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003311os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003312 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003313/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003314{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003315#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07003316 BOOL result = FALSE;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003317#else
3318 int result;
3319#endif
3320
Larry Hastings9cf065c2012-06-22 16:30:09 -07003321#ifndef HAVE_LINKAT
3322 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3323 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003324 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003325 }
3326#endif
3327
Steve Dowercc16be82016-09-08 10:35:16 -07003328#ifndef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10003329 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003330 PyErr_SetString(PyExc_NotImplementedError,
3331 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003332 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003333 }
Steve Dowercc16be82016-09-08 10:35:16 -07003334#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003335
Brian Curtin1b9df392010-11-24 20:24:31 +00003336#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003337 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003338 if (src->wide)
3339 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003340 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003341
Larry Hastings2f936352014-08-05 14:04:04 +10003342 if (!result)
3343 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003344#else
3345 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003346#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003347 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3348 (dst_dir_fd != DEFAULT_DIR_FD) ||
3349 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003350 result = linkat(src_dir_fd, src->narrow,
3351 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003352 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3353 else
Steve Dowercc16be82016-09-08 10:35:16 -07003354#endif /* HAVE_LINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10003355 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003356 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003357
Larry Hastings2f936352014-08-05 14:04:04 +10003358 if (result)
3359 return path_error2(src, dst);
Steve Dowercc16be82016-09-08 10:35:16 -07003360#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003361
Larry Hastings2f936352014-08-05 14:04:04 +10003362 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003363}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003364#endif
3365
Brian Curtin1b9df392010-11-24 20:24:31 +00003366
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003367#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003368static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003369_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003370{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371 PyObject *v;
3372 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3373 BOOL result;
Steve Dowercc16be82016-09-08 10:35:16 -07003374 wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003376 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003378
Steve Dowercc16be82016-09-08 10:35:16 -07003379 WIN32_FIND_DATAW wFileData;
3380 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003381
Steve Dowercc16be82016-09-08 10:35:16 -07003382 if (!path->wide) { /* Default arg: "." */
3383 po_wchars = L".";
3384 len = 1;
3385 } else {
3386 po_wchars = path->wide;
3387 len = wcslen(path->wide);
3388 }
3389 /* The +5 is so we can append "\\*.*\0" */
3390 wnamebuf = PyMem_New(wchar_t, len + 5);
3391 if (!wnamebuf) {
3392 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003393 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003394 }
Steve Dowercc16be82016-09-08 10:35:16 -07003395 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003396 if (len > 0) {
Steve Dowercc16be82016-09-08 10:35:16 -07003397 wchar_t wch = wnamebuf[len-1];
3398 if (wch != SEP && wch != ALTSEP && wch != L':')
3399 wnamebuf[len++] = SEP;
3400 wcscpy(wnamebuf + len, L"*.*");
Victor Stinner8c62be82010-05-06 00:08:46 +00003401 }
Steve Dowercc16be82016-09-08 10:35:16 -07003402 if ((list = PyList_New(0)) == NULL) {
3403 goto exit;
3404 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003405 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003406 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003407 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003408 if (hFindFile == INVALID_HANDLE_VALUE) {
3409 int error = GetLastError();
3410 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411 goto exit;
3412 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003413 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003414 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003415 }
3416 do {
3417 /* Skip over . and .. */
Steve Dowercc16be82016-09-08 10:35:16 -07003418 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3419 wcscmp(wFileData.cFileName, L"..") != 0) {
3420 v = PyUnicode_FromWideChar(wFileData.cFileName,
3421 wcslen(wFileData.cFileName));
3422 if (path->narrow && v) {
3423 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3424 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003425 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 Py_DECREF(list);
3427 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003428 break;
3429 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003431 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_DECREF(list);
3433 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003434 break;
3435 }
3436 Py_DECREF(v);
3437 }
3438 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003439 result = FindNextFileW(hFindFile, &wFileData);
Victor Stinner8c62be82010-05-06 00:08:46 +00003440 Py_END_ALLOW_THREADS
3441 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3442 it got to the end of the directory. */
3443 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003445 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003447 }
3448 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003449
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450exit:
3451 if (hFindFile != INVALID_HANDLE_VALUE) {
3452 if (FindClose(hFindFile) == FALSE) {
3453 if (list != NULL) {
3454 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003455 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 }
3457 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003458 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003459 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003462} /* end of _listdir_windows_no_opendir */
3463
3464#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3465
3466static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003467_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003468{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003469 PyObject *v;
3470 DIR *dirp = NULL;
3471 struct dirent *ep;
3472 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003473#ifdef HAVE_FDOPENDIR
3474 int fd = -1;
3475#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003476
Victor Stinner8c62be82010-05-06 00:08:46 +00003477 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003479 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003481 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003482 if (fd == -1)
3483 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484
Larry Hastingsfdaea062012-06-25 04:42:23 -07003485 return_str = 1;
3486
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 Py_BEGIN_ALLOW_THREADS
3488 dirp = fdopendir(fd);
3489 Py_END_ALLOW_THREADS
3490 }
3491 else
3492#endif
3493 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003494 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003495 if (path->narrow) {
3496 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003497 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003498 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003499 }
3500 else {
3501 name = ".";
3502 return_str = 1;
3503 }
3504
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 Py_BEGIN_ALLOW_THREADS
3506 dirp = opendir(name);
3507 Py_END_ALLOW_THREADS
3508 }
3509
3510 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003511 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003512#ifdef HAVE_FDOPENDIR
3513 if (fd != -1) {
3514 Py_BEGIN_ALLOW_THREADS
3515 close(fd);
3516 Py_END_ALLOW_THREADS
3517 }
3518#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 goto exit;
3520 }
3521 if ((list = PyList_New(0)) == NULL) {
3522 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
3524 for (;;) {
3525 errno = 0;
3526 Py_BEGIN_ALLOW_THREADS
3527 ep = readdir(dirp);
3528 Py_END_ALLOW_THREADS
3529 if (ep == NULL) {
3530 if (errno == 0) {
3531 break;
3532 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003534 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 }
3537 }
3538 if (ep->d_name[0] == '.' &&
3539 (NAMLEN(ep) == 1 ||
3540 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3541 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003542 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003543 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3544 else
3545 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 break;
3549 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 break;
3554 }
3555 Py_DECREF(v);
3556 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003557
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558exit:
3559 if (dirp != NULL) {
3560 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003561#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562 if (fd > -1)
3563 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003564#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 closedir(dirp);
3566 Py_END_ALLOW_THREADS
3567 }
3568
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003570} /* end of _posix_listdir */
3571#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003572
Larry Hastings2f936352014-08-05 14:04:04 +10003573
3574/*[clinic input]
3575os.listdir
3576
3577 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3578
3579Return a list containing the names of the files in the directory.
3580
3581path can be specified as either str or bytes. If path is bytes,
3582 the filenames returned will also be bytes; in all other circumstances
3583 the filenames returned will be str.
3584If path is None, uses the path='.'.
3585On some platforms, path may also be specified as an open file descriptor;\
3586 the file descriptor must refer to a directory.
3587 If this functionality is unavailable, using it raises NotImplementedError.
3588
3589The list is in arbitrary order. It does not include the special
3590entries '.' and '..' even if they are present in the directory.
3591
3592
3593[clinic start generated code]*/
3594
Larry Hastings2f936352014-08-05 14:04:04 +10003595static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003596os_listdir_impl(PyObject *module, path_t *path)
3597/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003598{
3599#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3600 return _listdir_windows_no_opendir(path, NULL);
3601#else
3602 return _posix_listdir(path, NULL);
3603#endif
3604}
3605
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003606#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003607/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003608/*[clinic input]
3609os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003610
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003611 path: path_t
3612 /
3613
3614[clinic start generated code]*/
3615
3616static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003617os__getfullpathname_impl(PyObject *module, path_t *path)
3618/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003619{
Steve Dowercc16be82016-09-08 10:35:16 -07003620 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
3621 wchar_t *wtemp;
3622 DWORD result;
3623 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003624
Steve Dowercc16be82016-09-08 10:35:16 -07003625 result = GetFullPathNameW(path->wide,
3626 Py_ARRAY_LENGTH(woutbuf),
3627 woutbuf, &wtemp);
3628 if (result > Py_ARRAY_LENGTH(woutbuf)) {
3629 woutbufp = PyMem_New(wchar_t, result);
3630 if (!woutbufp)
3631 return PyErr_NoMemory();
3632 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 }
Steve Dowercc16be82016-09-08 10:35:16 -07003634 if (result) {
3635 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
3636 if (path->narrow)
3637 Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
3638 } else
3639 v = win32_error_object("GetFullPathNameW", path->object);
3640 if (woutbufp != woutbuf)
3641 PyMem_Free(woutbufp);
3642 return v;
Larry Hastings2f936352014-08-05 14:04:04 +10003643}
Brian Curtind40e6f72010-07-08 21:39:08 +00003644
Brian Curtind25aef52011-06-13 15:16:04 -05003645
Larry Hastings2f936352014-08-05 14:04:04 +10003646/*[clinic input]
3647os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003648
Larry Hastings2f936352014-08-05 14:04:04 +10003649 path: unicode
3650 /
3651
3652A helper function for samepath on windows.
3653[clinic start generated code]*/
3654
Larry Hastings2f936352014-08-05 14:04:04 +10003655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003656os__getfinalpathname_impl(PyObject *module, PyObject *path)
3657/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003658{
3659 HANDLE hFile;
3660 int buf_size;
3661 wchar_t *target_path;
3662 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003663 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003664 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003665
Larry Hastings2f936352014-08-05 14:04:04 +10003666 path_wchar = PyUnicode_AsUnicode(path);
3667 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003668 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003669
Brian Curtind40e6f72010-07-08 21:39:08 +00003670 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003671 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003672 0, /* desired access */
3673 0, /* share mode */
3674 NULL, /* security attributes */
3675 OPEN_EXISTING,
3676 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3677 FILE_FLAG_BACKUP_SEMANTICS,
3678 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003679
Victor Stinnereb5657a2011-09-30 01:44:27 +02003680 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003681 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003682
3683 /* We have a good handle to the target, use it to determine the
3684 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003685 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003686
3687 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003688 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003689
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003690 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003691 if(!target_path)
3692 return PyErr_NoMemory();
3693
Steve Dower2ea51c92015-03-20 21:49:12 -07003694 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3695 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003696 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003697 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003698
3699 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003700 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003701
3702 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003703 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003704 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003705 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003706}
Brian Curtin62857742010-09-06 17:07:27 +00003707
Brian Curtin95d028f2011-06-09 09:10:38 -05003708PyDoc_STRVAR(posix__isdir__doc__,
3709"Return true if the pathname refers to an existing directory.");
3710
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003711/*[clinic input]
3712os._isdir
3713
3714 path: path_t
3715 /
3716
3717[clinic start generated code]*/
3718
Brian Curtin9c669cc2011-06-08 18:17:18 -05003719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003720os__isdir_impl(PyObject *module, path_t *path)
3721/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003722{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003723 DWORD attributes;
3724
Steve Dowerb22a6772016-07-17 20:49:38 -07003725 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003726 attributes = GetFileAttributesW(path->wide);
Steve Dowerb22a6772016-07-17 20:49:38 -07003727 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003728
Brian Curtin9c669cc2011-06-08 18:17:18 -05003729 if (attributes == INVALID_FILE_ATTRIBUTES)
3730 Py_RETURN_FALSE;
3731
Brian Curtin9c669cc2011-06-08 18:17:18 -05003732 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3733 Py_RETURN_TRUE;
3734 else
3735 Py_RETURN_FALSE;
3736}
Tim Golden6b528062013-08-01 12:44:00 +01003737
Tim Golden6b528062013-08-01 12:44:00 +01003738
Larry Hastings2f936352014-08-05 14:04:04 +10003739/*[clinic input]
3740os._getvolumepathname
3741
3742 path: unicode
3743
3744A helper function for ismount on Win32.
3745[clinic start generated code]*/
3746
Larry Hastings2f936352014-08-05 14:04:04 +10003747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003748os__getvolumepathname_impl(PyObject *module, PyObject *path)
3749/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003750{
3751 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003752 const wchar_t *path_wchar;
3753 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003754 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003755 BOOL ret;
3756
Larry Hastings2f936352014-08-05 14:04:04 +10003757 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3758 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003759 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003760 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003761
3762 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003763 buflen = Py_MAX(buflen, MAX_PATH);
3764
3765 if (buflen > DWORD_MAX) {
3766 PyErr_SetString(PyExc_OverflowError, "path too long");
3767 return NULL;
3768 }
3769
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003770 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003771 if (mountpath == NULL)
3772 return PyErr_NoMemory();
3773
3774 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003775 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003776 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003777 Py_END_ALLOW_THREADS
3778
3779 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003780 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003781 goto exit;
3782 }
3783 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3784
3785exit:
3786 PyMem_Free(mountpath);
3787 return result;
3788}
Tim Golden6b528062013-08-01 12:44:00 +01003789
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003790#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003791
Larry Hastings2f936352014-08-05 14:04:04 +10003792
3793/*[clinic input]
3794os.mkdir
3795
3796 path : path_t
3797
3798 mode: int = 0o777
3799
3800 *
3801
3802 dir_fd : dir_fd(requires='mkdirat') = None
3803
3804# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3805
3806Create a directory.
3807
3808If dir_fd is not None, it should be a file descriptor open to a directory,
3809 and path should be relative; path will then be relative to that directory.
3810dir_fd may not be implemented on your platform.
3811 If it is unavailable, using it will raise a NotImplementedError.
3812
3813The mode argument is ignored on Windows.
3814[clinic start generated code]*/
3815
Larry Hastings2f936352014-08-05 14:04:04 +10003816static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003817os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3818/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003819{
3820 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003821
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003822#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003823 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003824 result = CreateDirectoryW(path->wide, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003825 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003826
Larry Hastings2f936352014-08-05 14:04:04 +10003827 if (!result)
3828 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003829#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003830 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003831#if HAVE_MKDIRAT
3832 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003833 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003834 else
3835#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003836#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003837 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003838#else
Larry Hastings2f936352014-08-05 14:04:04 +10003839 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003840#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003841 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003842 if (result < 0)
3843 return path_error(path);
Steve Dowercc16be82016-09-08 10:35:16 -07003844#endif /* MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10003845 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003846}
3847
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003848
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003849/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3850#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003851#include <sys/resource.h>
3852#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003853
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003854
3855#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10003856/*[clinic input]
3857os.nice
3858
3859 increment: int
3860 /
3861
3862Add increment to the priority of process and return the new priority.
3863[clinic start generated code]*/
3864
Larry Hastings2f936352014-08-05 14:04:04 +10003865static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003866os_nice_impl(PyObject *module, int increment)
3867/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003868{
3869 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003870
Victor Stinner8c62be82010-05-06 00:08:46 +00003871 /* There are two flavours of 'nice': one that returns the new
3872 priority (as required by almost all standards out there) and the
3873 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
3874 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00003875
Victor Stinner8c62be82010-05-06 00:08:46 +00003876 If we are of the nice family that returns the new priority, we
3877 need to clear errno before the call, and check if errno is filled
3878 before calling posix_error() on a returnvalue of -1, because the
3879 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003880
Victor Stinner8c62be82010-05-06 00:08:46 +00003881 errno = 0;
3882 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003883#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 if (value == 0)
3885 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00003886#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003887 if (value == -1 && errno != 0)
3888 /* either nice() or getpriority() returned an error */
3889 return posix_error();
3890 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00003891}
Guido van Rossumb6775db1994-08-01 11:34:53 +00003892#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00003893
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003894
3895#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003896/*[clinic input]
3897os.getpriority
3898
3899 which: int
3900 who: int
3901
3902Return program scheduling priority.
3903[clinic start generated code]*/
3904
Larry Hastings2f936352014-08-05 14:04:04 +10003905static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003906os_getpriority_impl(PyObject *module, int which, int who)
3907/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003908{
3909 int retval;
3910
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003911 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003912 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003913 if (errno != 0)
3914 return posix_error();
3915 return PyLong_FromLong((long)retval);
3916}
3917#endif /* HAVE_GETPRIORITY */
3918
3919
3920#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10003921/*[clinic input]
3922os.setpriority
3923
3924 which: int
3925 who: int
3926 priority: int
3927
3928Set program scheduling priority.
3929[clinic start generated code]*/
3930
Larry Hastings2f936352014-08-05 14:04:04 +10003931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003932os_setpriority_impl(PyObject *module, int which, int who, int priority)
3933/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003934{
3935 int retval;
3936
3937 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00003938 if (retval == -1)
3939 return posix_error();
3940 Py_RETURN_NONE;
3941}
3942#endif /* HAVE_SETPRIORITY */
3943
3944
Barry Warsaw53699e91996-12-10 23:23:01 +00003945static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10003946internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003947{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003948 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07003949 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003950
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003951#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003952 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01003953 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003954#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07003955 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003956#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003957
Larry Hastings9cf065c2012-06-22 16:30:09 -07003958 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
3959 (dst_dir_fd != DEFAULT_DIR_FD);
3960#ifndef HAVE_RENAMEAT
3961 if (dir_fd_specified) {
3962 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003963 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003964 }
3965#endif
3966
Larry Hastings9cf065c2012-06-22 16:30:09 -07003967#ifdef MS_WINDOWS
3968 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07003969 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003970 Py_END_ALLOW_THREADS
3971
Larry Hastings2f936352014-08-05 14:04:04 +10003972 if (!result)
3973 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974
3975#else
Steve Dowercc16be82016-09-08 10:35:16 -07003976 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
3977 PyErr_Format(PyExc_ValueError,
3978 "%s: src and dst must be the same type", function_name);
3979 return NULL;
3980 }
3981
Larry Hastings9cf065c2012-06-22 16:30:09 -07003982 Py_BEGIN_ALLOW_THREADS
3983#ifdef HAVE_RENAMEAT
3984 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10003985 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986 else
3987#endif
Steve Dowercc16be82016-09-08 10:35:16 -07003988 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989 Py_END_ALLOW_THREADS
3990
Larry Hastings2f936352014-08-05 14:04:04 +10003991 if (result)
3992 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003993#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003994 Py_RETURN_NONE;
3995}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996
Larry Hastings2f936352014-08-05 14:04:04 +10003997
3998/*[clinic input]
3999os.rename
4000
4001 src : path_t
4002 dst : path_t
4003 *
4004 src_dir_fd : dir_fd = None
4005 dst_dir_fd : dir_fd = None
4006
4007Rename a file or directory.
4008
4009If either src_dir_fd or dst_dir_fd is not None, it should be a file
4010 descriptor open to a directory, and the respective path string (src or dst)
4011 should be relative; the path will then be relative to that directory.
4012src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4013 If they are unavailable, using them will raise a NotImplementedError.
4014[clinic start generated code]*/
4015
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004017os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004018 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004019/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004020{
Larry Hastings2f936352014-08-05 14:04:04 +10004021 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004022}
4023
Larry Hastings2f936352014-08-05 14:04:04 +10004024
4025/*[clinic input]
4026os.replace = os.rename
4027
4028Rename a file or directory, overwriting the destination.
4029
4030If either src_dir_fd or dst_dir_fd is not None, it should be a file
4031 descriptor open to a directory, and the respective path string (src or dst)
4032 should be relative; the path will then be relative to that directory.
4033src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4034 If they are unavailable, using them will raise a NotImplementedError."
4035[clinic start generated code]*/
4036
Larry Hastings2f936352014-08-05 14:04:04 +10004037static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004038os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4039 int dst_dir_fd)
4040/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004041{
4042 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4043}
4044
4045
4046/*[clinic input]
4047os.rmdir
4048
4049 path: path_t
4050 *
4051 dir_fd: dir_fd(requires='unlinkat') = None
4052
4053Remove a directory.
4054
4055If dir_fd is not None, it should be a file descriptor open to a directory,
4056 and path should be relative; path will then be relative to that directory.
4057dir_fd may not be implemented on your platform.
4058 If it is unavailable, using it will raise a NotImplementedError.
4059[clinic start generated code]*/
4060
Larry Hastings2f936352014-08-05 14:04:04 +10004061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004062os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4063/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004064{
4065 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004066
4067 Py_BEGIN_ALLOW_THREADS
4068#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004069 /* Windows, success=1, UNIX, success=0 */
4070 result = !RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004071#else
4072#ifdef HAVE_UNLINKAT
4073 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004074 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004075 else
4076#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004077 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004078#endif
4079 Py_END_ALLOW_THREADS
4080
Larry Hastings2f936352014-08-05 14:04:04 +10004081 if (result)
4082 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004083
Larry Hastings2f936352014-08-05 14:04:04 +10004084 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004085}
4086
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004087
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004088#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004089#ifdef MS_WINDOWS
4090/*[clinic input]
4091os.system -> long
4092
4093 command: Py_UNICODE
4094
4095Execute the command in a subshell.
4096[clinic start generated code]*/
4097
Larry Hastings2f936352014-08-05 14:04:04 +10004098static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004099os_system_impl(PyObject *module, Py_UNICODE *command)
4100/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004101{
4102 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004103 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004104 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004105 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004106 return result;
4107}
4108#else /* MS_WINDOWS */
4109/*[clinic input]
4110os.system -> long
4111
4112 command: FSConverter
4113
4114Execute the command in a subshell.
4115[clinic start generated code]*/
4116
Larry Hastings2f936352014-08-05 14:04:04 +10004117static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004118os_system_impl(PyObject *module, PyObject *command)
4119/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004120{
4121 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004122 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004123 Py_BEGIN_ALLOW_THREADS
4124 result = system(bytes);
4125 Py_END_ALLOW_THREADS
4126 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004127}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004128#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004129#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004130
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004131
Larry Hastings2f936352014-08-05 14:04:04 +10004132/*[clinic input]
4133os.umask
4134
4135 mask: int
4136 /
4137
4138Set the current numeric umask and return the previous umask.
4139[clinic start generated code]*/
4140
Larry Hastings2f936352014-08-05 14:04:04 +10004141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004142os_umask_impl(PyObject *module, int mask)
4143/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004144{
4145 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004146 if (i < 0)
4147 return posix_error();
4148 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004149}
4150
Brian Curtind40e6f72010-07-08 21:39:08 +00004151#ifdef MS_WINDOWS
4152
4153/* override the default DeleteFileW behavior so that directory
4154symlinks can be removed with this function, the same as with
4155Unix symlinks */
4156BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4157{
4158 WIN32_FILE_ATTRIBUTE_DATA info;
4159 WIN32_FIND_DATAW find_data;
4160 HANDLE find_data_handle;
4161 int is_directory = 0;
4162 int is_link = 0;
4163
4164 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4165 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004166
Brian Curtind40e6f72010-07-08 21:39:08 +00004167 /* Get WIN32_FIND_DATA structure for the path to determine if
4168 it is a symlink */
4169 if(is_directory &&
4170 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4171 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4172
4173 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004174 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4175 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4176 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4177 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004178 FindClose(find_data_handle);
4179 }
4180 }
4181 }
4182
4183 if (is_directory && is_link)
4184 return RemoveDirectoryW(lpFileName);
4185
4186 return DeleteFileW(lpFileName);
4187}
4188#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004189
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004190
Larry Hastings2f936352014-08-05 14:04:04 +10004191/*[clinic input]
4192os.unlink
4193
4194 path: path_t
4195 *
4196 dir_fd: dir_fd(requires='unlinkat')=None
4197
4198Remove a file (same as remove()).
4199
4200If dir_fd is not None, it should be a file descriptor open to a directory,
4201 and path should be relative; path will then be relative to that directory.
4202dir_fd may not be implemented on your platform.
4203 If it is unavailable, using it will raise a NotImplementedError.
4204
4205[clinic start generated code]*/
4206
Larry Hastings2f936352014-08-05 14:04:04 +10004207static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004208os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4209/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004210{
4211 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004212
4213 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004214 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004215#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07004216 /* Windows, success=1, UNIX, success=0 */
4217 result = !Py_DeleteFileW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004218#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004219#ifdef HAVE_UNLINKAT
4220 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004221 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004222 else
4223#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004224 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004225#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004226 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004227 Py_END_ALLOW_THREADS
4228
Larry Hastings2f936352014-08-05 14:04:04 +10004229 if (result)
4230 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231
Larry Hastings2f936352014-08-05 14:04:04 +10004232 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004233}
4234
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004235
Larry Hastings2f936352014-08-05 14:04:04 +10004236/*[clinic input]
4237os.remove = os.unlink
4238
4239Remove a file (same as unlink()).
4240
4241If dir_fd is not None, it should be a file descriptor open to a directory,
4242 and path should be relative; path will then be relative to that directory.
4243dir_fd may not be implemented on your platform.
4244 If it is unavailable, using it will raise a NotImplementedError.
4245[clinic start generated code]*/
4246
Larry Hastings2f936352014-08-05 14:04:04 +10004247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004248os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4249/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004250{
4251 return os_unlink_impl(module, path, dir_fd);
4252}
4253
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004254
Larry Hastings605a62d2012-06-24 04:33:36 -07004255static PyStructSequence_Field uname_result_fields[] = {
4256 {"sysname", "operating system name"},
4257 {"nodename", "name of machine on network (implementation-defined)"},
4258 {"release", "operating system release"},
4259 {"version", "operating system version"},
4260 {"machine", "hardware identifier"},
4261 {NULL}
4262};
4263
4264PyDoc_STRVAR(uname_result__doc__,
4265"uname_result: Result from os.uname().\n\n\
4266This object may be accessed either as a tuple of\n\
4267 (sysname, nodename, release, version, machine),\n\
4268or via the attributes sysname, nodename, release, version, and machine.\n\
4269\n\
4270See os.uname for more information.");
4271
4272static PyStructSequence_Desc uname_result_desc = {
4273 "uname_result", /* name */
4274 uname_result__doc__, /* doc */
4275 uname_result_fields,
4276 5
4277};
4278
4279static PyTypeObject UnameResultType;
4280
4281
4282#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004283/*[clinic input]
4284os.uname
4285
4286Return an object identifying the current operating system.
4287
4288The object behaves like a named tuple with the following fields:
4289 (sysname, nodename, release, version, machine)
4290
4291[clinic start generated code]*/
4292
Larry Hastings2f936352014-08-05 14:04:04 +10004293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004294os_uname_impl(PyObject *module)
4295/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004296{
Victor Stinner8c62be82010-05-06 00:08:46 +00004297 struct utsname u;
4298 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004299 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004300
Victor Stinner8c62be82010-05-06 00:08:46 +00004301 Py_BEGIN_ALLOW_THREADS
4302 res = uname(&u);
4303 Py_END_ALLOW_THREADS
4304 if (res < 0)
4305 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004306
4307 value = PyStructSequence_New(&UnameResultType);
4308 if (value == NULL)
4309 return NULL;
4310
4311#define SET(i, field) \
4312 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004313 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004314 if (!o) { \
4315 Py_DECREF(value); \
4316 return NULL; \
4317 } \
4318 PyStructSequence_SET_ITEM(value, i, o); \
4319 } \
4320
4321 SET(0, u.sysname);
4322 SET(1, u.nodename);
4323 SET(2, u.release);
4324 SET(3, u.version);
4325 SET(4, u.machine);
4326
4327#undef SET
4328
4329 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004330}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004331#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004332
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004333
Larry Hastings9cf065c2012-06-22 16:30:09 -07004334
4335typedef struct {
4336 int now;
4337 time_t atime_s;
4338 long atime_ns;
4339 time_t mtime_s;
4340 long mtime_ns;
4341} utime_t;
4342
4343/*
Victor Stinner484df002014-10-09 13:52:31 +02004344 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004345 * they also intentionally leak the declaration of a pointer named "time"
4346 */
4347#define UTIME_TO_TIMESPEC \
4348 struct timespec ts[2]; \
4349 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004350 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004351 time = NULL; \
4352 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004353 ts[0].tv_sec = ut->atime_s; \
4354 ts[0].tv_nsec = ut->atime_ns; \
4355 ts[1].tv_sec = ut->mtime_s; \
4356 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004357 time = ts; \
4358 } \
4359
4360#define UTIME_TO_TIMEVAL \
4361 struct timeval tv[2]; \
4362 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004363 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364 time = NULL; \
4365 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004366 tv[0].tv_sec = ut->atime_s; \
4367 tv[0].tv_usec = ut->atime_ns / 1000; \
4368 tv[1].tv_sec = ut->mtime_s; \
4369 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004370 time = tv; \
4371 } \
4372
4373#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004374 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004375 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004376 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377 time = NULL; \
4378 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004379 u.actime = ut->atime_s; \
4380 u.modtime = ut->mtime_s; \
4381 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 }
4383
4384#define UTIME_TO_TIME_T \
4385 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004386 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004387 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004388 time = NULL; \
4389 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004390 timet[0] = ut->atime_s; \
4391 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004392 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393 } \
4394
4395
Victor Stinner528a9ab2015-09-03 21:30:26 +02004396#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397
4398static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004399utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004400{
4401#ifdef HAVE_UTIMENSAT
4402 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4403 UTIME_TO_TIMESPEC;
4404 return utimensat(dir_fd, path, time, flags);
4405#elif defined(HAVE_FUTIMESAT)
4406 UTIME_TO_TIMEVAL;
4407 /*
4408 * follow_symlinks will never be false here;
4409 * we only allow !follow_symlinks and dir_fd together
4410 * if we have utimensat()
4411 */
4412 assert(follow_symlinks);
4413 return futimesat(dir_fd, path, time);
4414#endif
4415}
4416
Larry Hastings2f936352014-08-05 14:04:04 +10004417 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4418#else
4419 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004420#endif
4421
Victor Stinner528a9ab2015-09-03 21:30:26 +02004422#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004423
4424static int
Victor Stinner484df002014-10-09 13:52:31 +02004425utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004426{
4427#ifdef HAVE_FUTIMENS
4428 UTIME_TO_TIMESPEC;
4429 return futimens(fd, time);
4430#else
4431 UTIME_TO_TIMEVAL;
4432 return futimes(fd, time);
4433#endif
4434}
4435
Larry Hastings2f936352014-08-05 14:04:04 +10004436 #define PATH_UTIME_HAVE_FD 1
4437#else
4438 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004439#endif
4440
Victor Stinner5ebae872015-09-22 01:29:33 +02004441#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4442# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4443#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444
Victor Stinner4552ced2015-09-21 22:37:15 +02004445#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004446
4447static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004448utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004449{
4450#ifdef HAVE_UTIMENSAT
4451 UTIME_TO_TIMESPEC;
4452 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4453#else
4454 UTIME_TO_TIMEVAL;
4455 return lutimes(path, time);
4456#endif
4457}
4458
4459#endif
4460
4461#ifndef MS_WINDOWS
4462
4463static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004464utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004465{
4466#ifdef HAVE_UTIMENSAT
4467 UTIME_TO_TIMESPEC;
4468 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4469#elif defined(HAVE_UTIMES)
4470 UTIME_TO_TIMEVAL;
4471 return utimes(path, time);
4472#elif defined(HAVE_UTIME_H)
4473 UTIME_TO_UTIMBUF;
4474 return utime(path, time);
4475#else
4476 UTIME_TO_TIME_T;
4477 return utime(path, time);
4478#endif
4479}
4480
4481#endif
4482
Larry Hastings76ad59b2012-05-03 00:30:07 -07004483static int
4484split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4485{
4486 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004487 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004488 divmod = PyNumber_Divmod(py_long, billion);
4489 if (!divmod)
4490 goto exit;
4491 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4492 if ((*s == -1) && PyErr_Occurred())
4493 goto exit;
4494 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004495 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004496 goto exit;
4497
4498 result = 1;
4499exit:
4500 Py_XDECREF(divmod);
4501 return result;
4502}
4503
Larry Hastings2f936352014-08-05 14:04:04 +10004504
4505/*[clinic input]
4506os.utime
4507
4508 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4509 times: object = NULL
4510 *
4511 ns: object = NULL
4512 dir_fd: dir_fd(requires='futimensat') = None
4513 follow_symlinks: bool=True
4514
Martin Panter0ff89092015-09-09 01:56:53 +00004515# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004516
4517Set the access and modified time of path.
4518
4519path may always be specified as a string.
4520On some platforms, path may also be specified as an open file descriptor.
4521 If this functionality is unavailable, using it raises an exception.
4522
4523If times is not None, it must be a tuple (atime, mtime);
4524 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004525If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004526 atime_ns and mtime_ns should be expressed as integer nanoseconds
4527 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004528If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004529Specifying tuples for both times and ns is an error.
4530
4531If dir_fd is not None, it should be a file descriptor open to a directory,
4532 and path should be relative; path will then be relative to that directory.
4533If follow_symlinks is False, and the last element of the path is a symbolic
4534 link, utime will modify the symbolic link itself instead of the file the
4535 link points to.
4536It is an error to use dir_fd or follow_symlinks when specifying path
4537 as an open file descriptor.
4538dir_fd and follow_symlinks may not be available on your platform.
4539 If they are unavailable, using them will raise a NotImplementedError.
4540
4541[clinic start generated code]*/
4542
Larry Hastings2f936352014-08-05 14:04:04 +10004543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004544os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4545 int dir_fd, int follow_symlinks)
4546/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004547{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548#ifdef MS_WINDOWS
4549 HANDLE hFile;
4550 FILETIME atime, mtime;
4551#else
4552 int result;
4553#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004554
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004556 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004557
Christian Heimesb3c87242013-08-01 00:08:16 +02004558 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004559
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 if (times && (times != Py_None) && ns) {
4561 PyErr_SetString(PyExc_ValueError,
4562 "utime: you may specify either 'times'"
4563 " or 'ns' but not both");
4564 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004565 }
4566
4567 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004568 time_t a_sec, m_sec;
4569 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004570 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004571 PyErr_SetString(PyExc_TypeError,
4572 "utime: 'times' must be either"
4573 " a tuple of two ints or None");
4574 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004575 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004576 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004577 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004578 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004579 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004580 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004582 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004583 utime.atime_s = a_sec;
4584 utime.atime_ns = a_nsec;
4585 utime.mtime_s = m_sec;
4586 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004587 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004589 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 PyErr_SetString(PyExc_TypeError,
4591 "utime: 'ns' must be a tuple of two ints");
4592 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004593 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004595 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004596 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004597 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598 &utime.mtime_s, &utime.mtime_ns)) {
4599 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004600 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601 }
4602 else {
4603 /* times and ns are both None/unspecified. use "now". */
4604 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004605 }
4606
Victor Stinner4552ced2015-09-21 22:37:15 +02004607#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 if (follow_symlinks_specified("utime", follow_symlinks))
4609 goto exit;
4610#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004611
Larry Hastings2f936352014-08-05 14:04:04 +10004612 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4613 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4614 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004615 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004616
Larry Hastings9cf065c2012-06-22 16:30:09 -07004617#if !defined(HAVE_UTIMENSAT)
4618 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004619 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004620 "utime: cannot use dir_fd and follow_symlinks "
4621 "together on this platform");
4622 goto exit;
4623 }
4624#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004625
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004626#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07004628 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
4629 NULL, OPEN_EXISTING,
4630 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631 Py_END_ALLOW_THREADS
4632 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004633 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004635 }
4636
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004638 GetSystemTimeAsFileTime(&mtime);
4639 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004640 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004641 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004642 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4643 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004644 }
4645 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4646 /* Avoid putting the file name into the error here,
4647 as that may confuse the user into believing that
4648 something is wrong with the file, when it also
4649 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004650 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004652 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004653#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004655
Victor Stinner4552ced2015-09-21 22:37:15 +02004656#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004658 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004660#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004661
Victor Stinner528a9ab2015-09-03 21:30:26 +02004662#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004663 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004664 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004665 else
4666#endif
4667
Victor Stinner528a9ab2015-09-03 21:30:26 +02004668#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004669 if (path->fd != -1)
4670 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004671 else
4672#endif
4673
Larry Hastings2f936352014-08-05 14:04:04 +10004674 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004675
4676 Py_END_ALLOW_THREADS
4677
4678 if (result < 0) {
4679 /* see previous comment about not putting filename in error here */
4680 return_value = posix_error();
4681 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004682 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004683
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004684#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004685
4686 Py_INCREF(Py_None);
4687 return_value = Py_None;
4688
4689exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004690#ifdef MS_WINDOWS
4691 if (hFile != INVALID_HANDLE_VALUE)
4692 CloseHandle(hFile);
4693#endif
4694 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004695}
4696
Guido van Rossum3b066191991-06-04 19:40:25 +00004697/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004698
Larry Hastings2f936352014-08-05 14:04:04 +10004699
4700/*[clinic input]
4701os._exit
4702
4703 status: int
4704
4705Exit to the system with specified status, without normal exit processing.
4706[clinic start generated code]*/
4707
Larry Hastings2f936352014-08-05 14:04:04 +10004708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004709os__exit_impl(PyObject *module, int status)
4710/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004711{
4712 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004713 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004714}
4715
Steve Dowercc16be82016-09-08 10:35:16 -07004716#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4717#define EXECV_CHAR wchar_t
4718#else
4719#define EXECV_CHAR char
4720#endif
4721
Martin v. Löwis114619e2002-10-07 06:44:21 +00004722#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4723static void
Steve Dowercc16be82016-09-08 10:35:16 -07004724free_string_array(EXECV_CHAR **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004725{
Victor Stinner8c62be82010-05-06 00:08:46 +00004726 Py_ssize_t i;
4727 for (i = 0; i < count; i++)
4728 PyMem_Free(array[i]);
4729 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004730}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004731
Antoine Pitrou69f71142009-05-24 21:25:49 +00004732static
Steve Dowercc16be82016-09-08 10:35:16 -07004733int fsconvert_strdup(PyObject *o, EXECV_CHAR**out)
Martin v. Löwis011e8422009-05-05 04:43:17 +00004734{
Victor Stinner8c62be82010-05-06 00:08:46 +00004735 Py_ssize_t size;
Steve Dowercc16be82016-09-08 10:35:16 -07004736#if defined(HAVE_WEXECV) || defined(HAVE_WSPAWNV)
4737 *out = PyUnicode_AsWideCharString(o, &size);
4738 if (!*out)
4739 return 0;
4740#else
4741 PyObject *bytes;
Victor Stinner8c62be82010-05-06 00:08:46 +00004742 if (!PyUnicode_FSConverter(o, &bytes))
4743 return 0;
4744 size = PyBytes_GET_SIZE(bytes);
4745 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004746 if (!*out) {
4747 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004748 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004749 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004750 memcpy(*out, PyBytes_AsString(bytes), size+1);
4751 Py_DECREF(bytes);
Steve Dowercc16be82016-09-08 10:35:16 -07004752#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004753 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004754}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004755#endif
4756
Ross Lagerwall7807c352011-03-17 20:20:30 +02004757#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Steve Dowercc16be82016-09-08 10:35:16 -07004758static EXECV_CHAR**
Victor Stinner13bb71c2010-04-23 21:41:56 +00004759parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4760{
Victor Stinner8c62be82010-05-06 00:08:46 +00004761 Py_ssize_t i, pos, envc;
4762 PyObject *keys=NULL, *vals=NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004763 PyObject *key, *val, *keyval;
4764 EXECV_CHAR **envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004765
Victor Stinner8c62be82010-05-06 00:08:46 +00004766 i = PyMapping_Size(env);
4767 if (i < 0)
4768 return NULL;
Steve Dowercc16be82016-09-08 10:35:16 -07004769 envlist = PyMem_NEW(EXECV_CHAR *, i + 1);
Victor Stinner8c62be82010-05-06 00:08:46 +00004770 if (envlist == NULL) {
4771 PyErr_NoMemory();
4772 return NULL;
4773 }
4774 envc = 0;
4775 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004776 if (!keys)
4777 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004778 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004779 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004780 goto error;
4781 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4782 PyErr_Format(PyExc_TypeError,
4783 "env.keys() or env.values() is not a list");
4784 goto error;
4785 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004786
Victor Stinner8c62be82010-05-06 00:08:46 +00004787 for (pos = 0; pos < i; pos++) {
4788 key = PyList_GetItem(keys, pos);
4789 val = PyList_GetItem(vals, pos);
4790 if (!key || !val)
4791 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004792
Steve Dowercc16be82016-09-08 10:35:16 -07004793 keyval = PyUnicode_FromFormat("%U=%U", key, val);
4794 if (!keyval)
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -07004796
4797 if (!fsconvert_strdup(keyval, &envlist[envc++])) {
4798 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 goto error;
4800 }
Steve Dowercc16be82016-09-08 10:35:16 -07004801
4802 Py_DECREF(keyval);
Victor Stinner8c62be82010-05-06 00:08:46 +00004803 }
4804 Py_DECREF(vals);
4805 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004806
Victor Stinner8c62be82010-05-06 00:08:46 +00004807 envlist[envc] = 0;
4808 *envc_ptr = envc;
4809 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004810
4811error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 Py_XDECREF(keys);
4813 Py_XDECREF(vals);
Steve Dowercc16be82016-09-08 10:35:16 -07004814 free_string_array(envlist, envc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004816}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004817
Steve Dowercc16be82016-09-08 10:35:16 -07004818static EXECV_CHAR**
Ross Lagerwall7807c352011-03-17 20:20:30 +02004819parse_arglist(PyObject* argv, Py_ssize_t *argc)
4820{
4821 int i;
Steve Dowercc16be82016-09-08 10:35:16 -07004822 EXECV_CHAR **argvlist = PyMem_NEW(EXECV_CHAR *, *argc+1);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004823 if (argvlist == NULL) {
4824 PyErr_NoMemory();
4825 return NULL;
4826 }
4827 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004828 PyObject* item = PySequence_ITEM(argv, i);
4829 if (item == NULL)
4830 goto fail;
4831 if (!fsconvert_strdup(item, &argvlist[i])) {
4832 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004833 goto fail;
4834 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004835 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004836 }
4837 argvlist[*argc] = NULL;
4838 return argvlist;
4839fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004840 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004841 free_string_array(argvlist, *argc);
4842 return NULL;
4843}
Steve Dowercc16be82016-09-08 10:35:16 -07004844
Ross Lagerwall7807c352011-03-17 20:20:30 +02004845#endif
4846
Larry Hastings2f936352014-08-05 14:04:04 +10004847
Ross Lagerwall7807c352011-03-17 20:20:30 +02004848#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10004849/*[clinic input]
4850os.execv
4851
Steve Dowercc16be82016-09-08 10:35:16 -07004852 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004853 Path of executable file.
4854 argv: object
4855 Tuple or list of strings.
4856 /
4857
4858Execute an executable path with arguments, replacing current process.
4859[clinic start generated code]*/
4860
Larry Hastings2f936352014-08-05 14:04:04 +10004861static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004862os_execv_impl(PyObject *module, path_t *path, PyObject *argv)
4863/*[clinic end generated code: output=3b52fec34cd0dafd input=9bac31efae07dac7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004864{
Steve Dowercc16be82016-09-08 10:35:16 -07004865 EXECV_CHAR **argvlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004866 Py_ssize_t argc;
4867
4868 /* execv has two arguments: (path, argv), where
4869 argv is a list or tuple of strings. */
4870
Ross Lagerwall7807c352011-03-17 20:20:30 +02004871 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
4872 PyErr_SetString(PyExc_TypeError,
4873 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004874 return NULL;
4875 }
4876 argc = PySequence_Size(argv);
4877 if (argc < 1) {
4878 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02004879 return NULL;
4880 }
4881
4882 argvlist = parse_arglist(argv, &argc);
4883 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02004884 return NULL;
4885 }
4886
Steve Dowercc16be82016-09-08 10:35:16 -07004887#ifdef HAVE_WEXECV
4888 _wexecv(path->wide, argvlist);
4889#else
4890 execv(path->narrow, argvlist);
4891#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004892
4893 /* If we get here it's definitely an error */
4894
4895 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004896 return posix_error();
4897}
4898
Larry Hastings2f936352014-08-05 14:04:04 +10004899
4900/*[clinic input]
4901os.execve
4902
4903 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
4904 Path of executable file.
4905 argv: object
4906 Tuple or list of strings.
4907 env: object
4908 Dictionary of strings mapping to strings.
4909
4910Execute an executable path with arguments, replacing current process.
4911[clinic start generated code]*/
4912
Larry Hastings2f936352014-08-05 14:04:04 +10004913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004914os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
4915/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004916{
Steve Dowercc16be82016-09-08 10:35:16 -07004917 EXECV_CHAR **argvlist = NULL;
4918 EXECV_CHAR **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02004919 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004920
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 /* execve has three arguments: (path, argv, env), where
4922 argv is a list or tuple of strings and env is a dictionary
4923 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004924
Ross Lagerwall7807c352011-03-17 20:20:30 +02004925 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 "execve: argv must be a tuple or list");
4928 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02004930 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 if (!PyMapping_Check(env)) {
4932 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004933 "execve: environment must be a mapping object");
4934 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004936
Ross Lagerwall7807c352011-03-17 20:20:30 +02004937 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004939 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00004941
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 envlist = parse_envlist(env, &envc);
4943 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02004944 goto fail;
4945
Larry Hastings9cf065c2012-06-22 16:30:09 -07004946#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10004947 if (path->fd > -1)
4948 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004949 else
4950#endif
Steve Dowercc16be82016-09-08 10:35:16 -07004951#ifdef HAVE_WEXECV
4952 _wexecve(path->wide, argvlist, envlist);
4953#else
Larry Hastings2f936352014-08-05 14:04:04 +10004954 execve(path->narrow, argvlist, envlist);
Steve Dowercc16be82016-09-08 10:35:16 -07004955#endif
Ross Lagerwall7807c352011-03-17 20:20:30 +02004956
4957 /* If we get here it's definitely an error */
4958
Larry Hastings2f936352014-08-05 14:04:04 +10004959 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004960
Steve Dowercc16be82016-09-08 10:35:16 -07004961 free_string_array(envlist, envc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004962 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004963 if (argvlist)
4964 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004965 return NULL;
4966}
Steve Dowercc16be82016-09-08 10:35:16 -07004967
Larry Hastings9cf065c2012-06-22 16:30:09 -07004968#endif /* HAVE_EXECV */
4969
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004970
Steve Dowercc16be82016-09-08 10:35:16 -07004971#if defined(HAVE_SPAWNV) || defined(HAVE_WSPAWNV)
Larry Hastings2f936352014-08-05 14:04:04 +10004972/*[clinic input]
4973os.spawnv
4974
4975 mode: int
4976 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07004977 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10004978 Path of executable file.
4979 argv: object
4980 Tuple or list of strings.
4981 /
4982
4983Execute the program specified by path in a new process.
4984[clinic start generated code]*/
4985
Larry Hastings2f936352014-08-05 14:04:04 +10004986static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07004987os_spawnv_impl(PyObject *module, int mode, path_t *path, PyObject *argv)
4988/*[clinic end generated code: output=71cd037a9d96b816 input=43224242303291be]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004989{
Steve Dowercc16be82016-09-08 10:35:16 -07004990 EXECV_CHAR **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10004991 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 Py_ssize_t argc;
Benjamin Petersonca470632016-09-06 13:47:26 -07004993 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00004994 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 /* spawnv has three arguments: (mode, path, argv), where
4997 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00004998
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 if (PyList_Check(argv)) {
5000 argc = PyList_Size(argv);
5001 getitem = PyList_GetItem;
5002 }
5003 else if (PyTuple_Check(argv)) {
5004 argc = PyTuple_Size(argv);
5005 getitem = PyTuple_GetItem;
5006 }
5007 else {
5008 PyErr_SetString(PyExc_TypeError,
5009 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005010 return NULL;
5011 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005012
Steve Dowercc16be82016-09-08 10:35:16 -07005013 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005014 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005015 return PyErr_NoMemory();
5016 }
5017 for (i = 0; i < argc; i++) {
5018 if (!fsconvert_strdup((*getitem)(argv, i),
5019 &argvlist[i])) {
5020 free_string_array(argvlist, i);
5021 PyErr_SetString(
5022 PyExc_TypeError,
5023 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 return NULL;
5025 }
5026 }
5027 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005028
Victor Stinner8c62be82010-05-06 00:08:46 +00005029 if (mode == _OLD_P_OVERLAY)
5030 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005031
Victor Stinner8c62be82010-05-06 00:08:46 +00005032 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005033 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005034#ifdef HAVE_WSPAWNV
5035 spawnval = _wspawnv(mode, path->wide, argvlist);
5036#else
5037 spawnval = _spawnv(mode, path->narrow, argvlist);
5038#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005039 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005041
Victor Stinner8c62be82010-05-06 00:08:46 +00005042 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005043
Victor Stinner8c62be82010-05-06 00:08:46 +00005044 if (spawnval == -1)
5045 return posix_error();
5046 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005047 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005048}
5049
5050
Larry Hastings2f936352014-08-05 14:04:04 +10005051/*[clinic input]
5052os.spawnve
5053
5054 mode: int
5055 Mode of process creation.
Steve Dowercc16be82016-09-08 10:35:16 -07005056 path: path_t
Larry Hastings2f936352014-08-05 14:04:04 +10005057 Path of executable file.
5058 argv: object
5059 Tuple or list of strings.
5060 env: object
5061 Dictionary of strings mapping to strings.
5062 /
5063
5064Execute the program specified by path in a new process.
5065[clinic start generated code]*/
5066
Larry Hastings2f936352014-08-05 14:04:04 +10005067static PyObject *
Steve Dowercc16be82016-09-08 10:35:16 -07005068os_spawnve_impl(PyObject *module, int mode, path_t *path, PyObject *argv,
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005069 PyObject *env)
Steve Dowercc16be82016-09-08 10:35:16 -07005070/*[clinic end generated code: output=30fe85be56fe37ad input=3e40803ee7c4c586]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005071{
Steve Dowercc16be82016-09-08 10:35:16 -07005072 EXECV_CHAR **argvlist;
5073 EXECV_CHAR **envlist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005074 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005075 Py_ssize_t argc, i, envc;
Benjamin Petersonca470632016-09-06 13:47:26 -07005076 intptr_t spawnval;
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5078 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005079
Victor Stinner8c62be82010-05-06 00:08:46 +00005080 /* spawnve has four arguments: (mode, path, argv, env), where
5081 argv is a list or tuple of strings and env is a dictionary
5082 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005083
Victor Stinner8c62be82010-05-06 00:08:46 +00005084 if (PyList_Check(argv)) {
5085 argc = PyList_Size(argv);
5086 getitem = PyList_GetItem;
5087 }
5088 else if (PyTuple_Check(argv)) {
5089 argc = PyTuple_Size(argv);
5090 getitem = PyTuple_GetItem;
5091 }
5092 else {
5093 PyErr_SetString(PyExc_TypeError,
5094 "spawnve() arg 2 must be a tuple or list");
5095 goto fail_0;
5096 }
5097 if (!PyMapping_Check(env)) {
5098 PyErr_SetString(PyExc_TypeError,
5099 "spawnve() arg 3 must be a mapping object");
5100 goto fail_0;
5101 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005102
Steve Dowercc16be82016-09-08 10:35:16 -07005103 argvlist = PyMem_NEW(EXECV_CHAR *, argc+1);
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 if (argvlist == NULL) {
5105 PyErr_NoMemory();
5106 goto fail_0;
5107 }
5108 for (i = 0; i < argc; i++) {
5109 if (!fsconvert_strdup((*getitem)(argv, i),
5110 &argvlist[i]))
5111 {
5112 lastarg = i;
5113 goto fail_1;
5114 }
5115 }
5116 lastarg = argc;
5117 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005118
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 envlist = parse_envlist(env, &envc);
5120 if (envlist == NULL)
5121 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005122
Victor Stinner8c62be82010-05-06 00:08:46 +00005123 if (mode == _OLD_P_OVERLAY)
5124 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005125
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 Py_BEGIN_ALLOW_THREADS
Steve Dower654a7bd2016-09-11 20:19:32 -07005127 _Py_BEGIN_SUPPRESS_IPH
Steve Dowercc16be82016-09-08 10:35:16 -07005128#ifdef HAVE_WSPAWNV
5129 spawnval = _wspawnve(mode, path->wide, argvlist, envlist);
5130#else
5131 spawnval = _spawnve(mode, path->narrow, argvlist, envlist);
5132#endif
Steve Dower654a7bd2016-09-11 20:19:32 -07005133 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005134 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005135
Victor Stinner8c62be82010-05-06 00:08:46 +00005136 if (spawnval == -1)
5137 (void) posix_error();
5138 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005139 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005140
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 while (--envc >= 0)
5142 PyMem_DEL(envlist[envc]);
5143 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005144 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005145 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005146 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005147 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005148}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005149
Guido van Rossuma1065681999-01-25 23:20:23 +00005150#endif /* HAVE_SPAWNV */
5151
5152
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005153#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005154/*[clinic input]
5155os.fork1
5156
5157Fork a child process with a single multiplexed (i.e., not bound) thread.
5158
5159Return 0 to child process and PID of child to parent process.
5160[clinic start generated code]*/
5161
Larry Hastings2f936352014-08-05 14:04:04 +10005162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005163os_fork1_impl(PyObject *module)
5164/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005165{
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 pid_t pid;
5167 int result = 0;
5168 _PyImport_AcquireLock();
5169 pid = fork1();
5170 if (pid == 0) {
5171 /* child: this clobbers and resets the import lock. */
5172 PyOS_AfterFork();
5173 } else {
5174 /* parent: release the import lock. */
5175 result = _PyImport_ReleaseLock();
5176 }
5177 if (pid == -1)
5178 return posix_error();
5179 if (result < 0) {
5180 /* Don't clobber the OSError if the fork failed. */
5181 PyErr_SetString(PyExc_RuntimeError,
5182 "not holding the import lock");
5183 return NULL;
5184 }
5185 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005186}
Larry Hastings2f936352014-08-05 14:04:04 +10005187#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005188
5189
Guido van Rossumad0ee831995-03-01 10:34:45 +00005190#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005191/*[clinic input]
5192os.fork
5193
5194Fork a child process.
5195
5196Return 0 to child process and PID of child to parent process.
5197[clinic start generated code]*/
5198
Larry Hastings2f936352014-08-05 14:04:04 +10005199static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005200os_fork_impl(PyObject *module)
5201/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005202{
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 pid_t pid;
5204 int result = 0;
5205 _PyImport_AcquireLock();
5206 pid = fork();
5207 if (pid == 0) {
5208 /* child: this clobbers and resets the import lock. */
5209 PyOS_AfterFork();
5210 } else {
5211 /* parent: release the import lock. */
5212 result = _PyImport_ReleaseLock();
5213 }
5214 if (pid == -1)
5215 return posix_error();
5216 if (result < 0) {
5217 /* Don't clobber the OSError if the fork failed. */
5218 PyErr_SetString(PyExc_RuntimeError,
5219 "not holding the import lock");
5220 return NULL;
5221 }
5222 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005223}
Larry Hastings2f936352014-08-05 14:04:04 +10005224#endif /* HAVE_FORK */
5225
Guido van Rossum85e3b011991-06-03 12:42:10 +00005226
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005227#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005228#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005229/*[clinic input]
5230os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005231
Larry Hastings2f936352014-08-05 14:04:04 +10005232 policy: int
5233
5234Get the maximum scheduling priority for policy.
5235[clinic start generated code]*/
5236
Larry Hastings2f936352014-08-05 14:04:04 +10005237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005238os_sched_get_priority_max_impl(PyObject *module, int policy)
5239/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005240{
5241 int max;
5242
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005243 max = sched_get_priority_max(policy);
5244 if (max < 0)
5245 return posix_error();
5246 return PyLong_FromLong(max);
5247}
5248
Larry Hastings2f936352014-08-05 14:04:04 +10005249
5250/*[clinic input]
5251os.sched_get_priority_min
5252
5253 policy: int
5254
5255Get the minimum scheduling priority for policy.
5256[clinic start generated code]*/
5257
Larry Hastings2f936352014-08-05 14:04:04 +10005258static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005259os_sched_get_priority_min_impl(PyObject *module, int policy)
5260/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005261{
5262 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005263 if (min < 0)
5264 return posix_error();
5265 return PyLong_FromLong(min);
5266}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005267#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5268
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005269
Larry Hastings2f936352014-08-05 14:04:04 +10005270#ifdef HAVE_SCHED_SETSCHEDULER
5271/*[clinic input]
5272os.sched_getscheduler
5273 pid: pid_t
5274 /
5275
5276Get the scheduling policy for the process identifiedy by pid.
5277
5278Passing 0 for pid returns the scheduling policy for the calling process.
5279[clinic start generated code]*/
5280
Larry Hastings2f936352014-08-05 14:04:04 +10005281static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005282os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5283/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005284{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005285 int policy;
5286
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005287 policy = sched_getscheduler(pid);
5288 if (policy < 0)
5289 return posix_error();
5290 return PyLong_FromLong(policy);
5291}
Larry Hastings2f936352014-08-05 14:04:04 +10005292#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005293
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005294
5295#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005296/*[clinic input]
5297class os.sched_param "PyObject *" "&SchedParamType"
5298
5299@classmethod
5300os.sched_param.__new__
5301
5302 sched_priority: object
5303 A scheduling parameter.
5304
5305Current has only one field: sched_priority");
5306[clinic start generated code]*/
5307
Larry Hastings2f936352014-08-05 14:04:04 +10005308static PyObject *
5309os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005310/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005311{
5312 PyObject *res;
5313
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005314 res = PyStructSequence_New(type);
5315 if (!res)
5316 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005317 Py_INCREF(sched_priority);
5318 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005319 return res;
5320}
5321
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005322
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005323PyDoc_VAR(os_sched_param__doc__);
5324
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005325static PyStructSequence_Field sched_param_fields[] = {
5326 {"sched_priority", "the scheduling priority"},
5327 {0}
5328};
5329
5330static PyStructSequence_Desc sched_param_desc = {
5331 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005332 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005333 sched_param_fields,
5334 1
5335};
5336
5337static int
5338convert_sched_param(PyObject *param, struct sched_param *res)
5339{
5340 long priority;
5341
5342 if (Py_TYPE(param) != &SchedParamType) {
5343 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5344 return 0;
5345 }
5346 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5347 if (priority == -1 && PyErr_Occurred())
5348 return 0;
5349 if (priority > INT_MAX || priority < INT_MIN) {
5350 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5351 return 0;
5352 }
5353 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5354 return 1;
5355}
Larry Hastings2f936352014-08-05 14:04:04 +10005356#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005357
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005358
5359#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005360/*[clinic input]
5361os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005362
Larry Hastings2f936352014-08-05 14:04:04 +10005363 pid: pid_t
5364 policy: int
5365 param: sched_param
5366 /
5367
5368Set the scheduling policy for the process identified by pid.
5369
5370If pid is 0, the calling process is changed.
5371param is an instance of sched_param.
5372[clinic start generated code]*/
5373
Larry Hastings2f936352014-08-05 14:04:04 +10005374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005375os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005376 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005377/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005378{
Jesus Cea9c822272011-09-10 01:40:52 +02005379 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005380 ** sched_setscheduler() returns 0 in Linux, but the previous
5381 ** scheduling policy under Solaris/Illumos, and others.
5382 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005383 */
Larry Hastings2f936352014-08-05 14:04:04 +10005384 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005385 return posix_error();
5386 Py_RETURN_NONE;
5387}
Larry Hastings2f936352014-08-05 14:04:04 +10005388#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005389
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005390
5391#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005392/*[clinic input]
5393os.sched_getparam
5394 pid: pid_t
5395 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005396
Larry Hastings2f936352014-08-05 14:04:04 +10005397Returns scheduling parameters for the process identified by pid.
5398
5399If pid is 0, returns parameters for the calling process.
5400Return value is an instance of sched_param.
5401[clinic start generated code]*/
5402
Larry Hastings2f936352014-08-05 14:04:04 +10005403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005404os_sched_getparam_impl(PyObject *module, pid_t pid)
5405/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005406{
5407 struct sched_param param;
5408 PyObject *result;
5409 PyObject *priority;
5410
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005411 if (sched_getparam(pid, &param))
5412 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005413 result = PyStructSequence_New(&SchedParamType);
5414 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005415 return NULL;
5416 priority = PyLong_FromLong(param.sched_priority);
5417 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005418 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005419 return NULL;
5420 }
Larry Hastings2f936352014-08-05 14:04:04 +10005421 PyStructSequence_SET_ITEM(result, 0, priority);
5422 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005423}
5424
Larry Hastings2f936352014-08-05 14:04:04 +10005425
5426/*[clinic input]
5427os.sched_setparam
5428 pid: pid_t
5429 param: sched_param
5430 /
5431
5432Set scheduling parameters for the process identified by pid.
5433
5434If pid is 0, sets parameters for the calling process.
5435param should be an instance of sched_param.
5436[clinic start generated code]*/
5437
Larry Hastings2f936352014-08-05 14:04:04 +10005438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005439os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005440 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005441/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005442{
5443 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005444 return posix_error();
5445 Py_RETURN_NONE;
5446}
Larry Hastings2f936352014-08-05 14:04:04 +10005447#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005448
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005449
5450#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005451/*[clinic input]
5452os.sched_rr_get_interval -> double
5453 pid: pid_t
5454 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005455
Larry Hastings2f936352014-08-05 14:04:04 +10005456Return the round-robin quantum for the process identified by pid, in seconds.
5457
5458Value returned is a float.
5459[clinic start generated code]*/
5460
Larry Hastings2f936352014-08-05 14:04:04 +10005461static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005462os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5463/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005464{
5465 struct timespec interval;
5466 if (sched_rr_get_interval(pid, &interval)) {
5467 posix_error();
5468 return -1.0;
5469 }
5470 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5471}
5472#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005473
Larry Hastings2f936352014-08-05 14:04:04 +10005474
5475/*[clinic input]
5476os.sched_yield
5477
5478Voluntarily relinquish the CPU.
5479[clinic start generated code]*/
5480
Larry Hastings2f936352014-08-05 14:04:04 +10005481static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005482os_sched_yield_impl(PyObject *module)
5483/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005484{
5485 if (sched_yield())
5486 return posix_error();
5487 Py_RETURN_NONE;
5488}
5489
Benjamin Peterson2740af82011-08-02 17:41:34 -05005490#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005491/* The minimum number of CPUs allocated in a cpu_set_t */
5492static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005493
Larry Hastings2f936352014-08-05 14:04:04 +10005494/*[clinic input]
5495os.sched_setaffinity
5496 pid: pid_t
5497 mask : object
5498 /
5499
5500Set the CPU affinity of the process identified by pid to mask.
5501
5502mask should be an iterable of integers identifying CPUs.
5503[clinic start generated code]*/
5504
Larry Hastings2f936352014-08-05 14:04:04 +10005505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005506os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5507/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005508{
Antoine Pitrou84869872012-08-04 16:16:35 +02005509 int ncpus;
5510 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005511 cpu_set_t *cpu_set = NULL;
5512 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005513
Larry Hastings2f936352014-08-05 14:04:04 +10005514 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005515 if (iterator == NULL)
5516 return NULL;
5517
5518 ncpus = NCPUS_START;
5519 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005520 cpu_set = CPU_ALLOC(ncpus);
5521 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005522 PyErr_NoMemory();
5523 goto error;
5524 }
Larry Hastings2f936352014-08-05 14:04:04 +10005525 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005526
5527 while ((item = PyIter_Next(iterator))) {
5528 long cpu;
5529 if (!PyLong_Check(item)) {
5530 PyErr_Format(PyExc_TypeError,
5531 "expected an iterator of ints, "
5532 "but iterator yielded %R",
5533 Py_TYPE(item));
5534 Py_DECREF(item);
5535 goto error;
5536 }
5537 cpu = PyLong_AsLong(item);
5538 Py_DECREF(item);
5539 if (cpu < 0) {
5540 if (!PyErr_Occurred())
5541 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5542 goto error;
5543 }
5544 if (cpu > INT_MAX - 1) {
5545 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5546 goto error;
5547 }
5548 if (cpu >= ncpus) {
5549 /* Grow CPU mask to fit the CPU number */
5550 int newncpus = ncpus;
5551 cpu_set_t *newmask;
5552 size_t newsetsize;
5553 while (newncpus <= cpu) {
5554 if (newncpus > INT_MAX / 2)
5555 newncpus = cpu + 1;
5556 else
5557 newncpus = newncpus * 2;
5558 }
5559 newmask = CPU_ALLOC(newncpus);
5560 if (newmask == NULL) {
5561 PyErr_NoMemory();
5562 goto error;
5563 }
5564 newsetsize = CPU_ALLOC_SIZE(newncpus);
5565 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005566 memcpy(newmask, cpu_set, setsize);
5567 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005568 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005569 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005570 ncpus = newncpus;
5571 }
Larry Hastings2f936352014-08-05 14:04:04 +10005572 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005573 }
5574 Py_CLEAR(iterator);
5575
Larry Hastings2f936352014-08-05 14:04:04 +10005576 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005577 posix_error();
5578 goto error;
5579 }
Larry Hastings2f936352014-08-05 14:04:04 +10005580 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005581 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005582
5583error:
Larry Hastings2f936352014-08-05 14:04:04 +10005584 if (cpu_set)
5585 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005586 Py_XDECREF(iterator);
5587 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005588}
5589
Larry Hastings2f936352014-08-05 14:04:04 +10005590
5591/*[clinic input]
5592os.sched_getaffinity
5593 pid: pid_t
5594 /
5595
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005596Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005597
5598The affinity is returned as a set of CPU identifiers.
5599[clinic start generated code]*/
5600
Larry Hastings2f936352014-08-05 14:04:04 +10005601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005602os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005603/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005604{
Antoine Pitrou84869872012-08-04 16:16:35 +02005605 int cpu, ncpus, count;
5606 size_t setsize;
5607 cpu_set_t *mask = NULL;
5608 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005609
Antoine Pitrou84869872012-08-04 16:16:35 +02005610 ncpus = NCPUS_START;
5611 while (1) {
5612 setsize = CPU_ALLOC_SIZE(ncpus);
5613 mask = CPU_ALLOC(ncpus);
5614 if (mask == NULL)
5615 return PyErr_NoMemory();
5616 if (sched_getaffinity(pid, setsize, mask) == 0)
5617 break;
5618 CPU_FREE(mask);
5619 if (errno != EINVAL)
5620 return posix_error();
5621 if (ncpus > INT_MAX / 2) {
5622 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5623 "a large enough CPU set");
5624 return NULL;
5625 }
5626 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005627 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005628
5629 res = PySet_New(NULL);
5630 if (res == NULL)
5631 goto error;
5632 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5633 if (CPU_ISSET_S(cpu, setsize, mask)) {
5634 PyObject *cpu_num = PyLong_FromLong(cpu);
5635 --count;
5636 if (cpu_num == NULL)
5637 goto error;
5638 if (PySet_Add(res, cpu_num)) {
5639 Py_DECREF(cpu_num);
5640 goto error;
5641 }
5642 Py_DECREF(cpu_num);
5643 }
5644 }
5645 CPU_FREE(mask);
5646 return res;
5647
5648error:
5649 if (mask)
5650 CPU_FREE(mask);
5651 Py_XDECREF(res);
5652 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005653}
5654
Benjamin Peterson2740af82011-08-02 17:41:34 -05005655#endif /* HAVE_SCHED_SETAFFINITY */
5656
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005657#endif /* HAVE_SCHED_H */
5658
Larry Hastings2f936352014-08-05 14:04:04 +10005659
Neal Norwitzb59798b2003-03-21 01:43:31 +00005660/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005661/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5662#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005663#define DEV_PTY_FILE "/dev/ptc"
5664#define HAVE_DEV_PTMX
5665#else
5666#define DEV_PTY_FILE "/dev/ptmx"
5667#endif
5668
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005669#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005670#ifdef HAVE_PTY_H
5671#include <pty.h>
5672#else
5673#ifdef HAVE_LIBUTIL_H
5674#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005675#else
5676#ifdef HAVE_UTIL_H
5677#include <util.h>
5678#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005679#endif /* HAVE_LIBUTIL_H */
5680#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005681#ifdef HAVE_STROPTS_H
5682#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005683#endif
5684#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005685
Larry Hastings2f936352014-08-05 14:04:04 +10005686
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005687#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005688/*[clinic input]
5689os.openpty
5690
5691Open a pseudo-terminal.
5692
5693Return a tuple of (master_fd, slave_fd) containing open file descriptors
5694for both the master and slave ends.
5695[clinic start generated code]*/
5696
Larry Hastings2f936352014-08-05 14:04:04 +10005697static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005698os_openpty_impl(PyObject *module)
5699/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005700{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005701 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005702#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005703 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005704#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005705#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005706 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005707#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005708 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005709#endif
5710#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005711
Thomas Wouters70c21a12000-07-14 14:28:33 +00005712#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005713 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005714 goto posix_error;
5715
5716 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5717 goto error;
5718 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5719 goto error;
5720
Neal Norwitzb59798b2003-03-21 01:43:31 +00005721#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005722 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5723 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005724 goto posix_error;
5725 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5726 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005727
Victor Stinnerdaf45552013-08-28 00:53:59 +02005728 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005729 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005730 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005731
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005732#else
Victor Stinner000de532013-11-25 23:19:58 +01005733 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005734 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005735 goto posix_error;
5736
Victor Stinner8c62be82010-05-06 00:08:46 +00005737 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005738
Victor Stinner8c62be82010-05-06 00:08:46 +00005739 /* change permission of slave */
5740 if (grantpt(master_fd) < 0) {
5741 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005742 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005743 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005744
Victor Stinner8c62be82010-05-06 00:08:46 +00005745 /* unlock slave */
5746 if (unlockpt(master_fd) < 0) {
5747 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005748 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005749 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005750
Victor Stinner8c62be82010-05-06 00:08:46 +00005751 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005752
Victor Stinner8c62be82010-05-06 00:08:46 +00005753 slave_name = ptsname(master_fd); /* get name of slave */
5754 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005755 goto posix_error;
5756
5757 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005758 if (slave_fd == -1)
5759 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005760
5761 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5762 goto posix_error;
5763
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005764#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005765 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5766 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005767#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005768 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005769#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005770#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005771#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005772
Victor Stinner8c62be82010-05-06 00:08:46 +00005773 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005774
Victor Stinnerdaf45552013-08-28 00:53:59 +02005775posix_error:
5776 posix_error();
5777error:
5778 if (master_fd != -1)
5779 close(master_fd);
5780 if (slave_fd != -1)
5781 close(slave_fd);
5782 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005783}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005784#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005785
Larry Hastings2f936352014-08-05 14:04:04 +10005786
Fred Drake8cef4cf2000-06-28 16:40:38 +00005787#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005788/*[clinic input]
5789os.forkpty
5790
5791Fork a new process with a new pseudo-terminal as controlling tty.
5792
5793Returns a tuple of (pid, master_fd).
5794Like fork(), return pid of 0 to the child process,
5795and pid of child to the parent process.
5796To both, return fd of newly opened pseudo-terminal.
5797[clinic start generated code]*/
5798
Larry Hastings2f936352014-08-05 14:04:04 +10005799static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005800os_forkpty_impl(PyObject *module)
5801/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005802{
Victor Stinner8c62be82010-05-06 00:08:46 +00005803 int master_fd = -1, result = 0;
5804 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005805
Victor Stinner8c62be82010-05-06 00:08:46 +00005806 _PyImport_AcquireLock();
5807 pid = forkpty(&master_fd, NULL, NULL, NULL);
5808 if (pid == 0) {
5809 /* child: this clobbers and resets the import lock. */
5810 PyOS_AfterFork();
5811 } else {
5812 /* parent: release the import lock. */
5813 result = _PyImport_ReleaseLock();
5814 }
5815 if (pid == -1)
5816 return posix_error();
5817 if (result < 0) {
5818 /* Don't clobber the OSError if the fork failed. */
5819 PyErr_SetString(PyExc_RuntimeError,
5820 "not holding the import lock");
5821 return NULL;
5822 }
5823 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005824}
Larry Hastings2f936352014-08-05 14:04:04 +10005825#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005826
Ross Lagerwall7807c352011-03-17 20:20:30 +02005827
Guido van Rossumad0ee831995-03-01 10:34:45 +00005828#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005829/*[clinic input]
5830os.getegid
5831
5832Return the current process's effective group id.
5833[clinic start generated code]*/
5834
Larry Hastings2f936352014-08-05 14:04:04 +10005835static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005836os_getegid_impl(PyObject *module)
5837/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005838{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005839 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005840}
Larry Hastings2f936352014-08-05 14:04:04 +10005841#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005842
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005843
Guido van Rossumad0ee831995-03-01 10:34:45 +00005844#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005845/*[clinic input]
5846os.geteuid
5847
5848Return the current process's effective user id.
5849[clinic start generated code]*/
5850
Larry Hastings2f936352014-08-05 14:04:04 +10005851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005852os_geteuid_impl(PyObject *module)
5853/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005854{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005855 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005856}
Larry Hastings2f936352014-08-05 14:04:04 +10005857#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005858
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005859
Guido van Rossumad0ee831995-03-01 10:34:45 +00005860#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10005861/*[clinic input]
5862os.getgid
5863
5864Return the current process's group id.
5865[clinic start generated code]*/
5866
Larry Hastings2f936352014-08-05 14:04:04 +10005867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005868os_getgid_impl(PyObject *module)
5869/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005870{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005871 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005872}
Larry Hastings2f936352014-08-05 14:04:04 +10005873#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005874
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005875
Larry Hastings2f936352014-08-05 14:04:04 +10005876/*[clinic input]
5877os.getpid
5878
5879Return the current process id.
5880[clinic start generated code]*/
5881
Larry Hastings2f936352014-08-05 14:04:04 +10005882static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005883os_getpid_impl(PyObject *module)
5884/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005885{
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00005887}
5888
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005889#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10005890
5891/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005892PyDoc_STRVAR(posix_getgrouplist__doc__,
5893"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
5894Returns a list of groups to which a user belongs.\n\n\
5895 user: username to lookup\n\
5896 group: base group id of the user");
5897
5898static PyObject *
5899posix_getgrouplist(PyObject *self, PyObject *args)
5900{
5901#ifdef NGROUPS_MAX
5902#define MAX_GROUPS NGROUPS_MAX
5903#else
5904 /* defined to be 16 on Solaris7, so this should be a small number */
5905#define MAX_GROUPS 64
5906#endif
5907
5908 const char *user;
5909 int i, ngroups;
5910 PyObject *list;
5911#ifdef __APPLE__
5912 int *groups, basegid;
5913#else
5914 gid_t *groups, basegid;
5915#endif
5916 ngroups = MAX_GROUPS;
5917
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005918#ifdef __APPLE__
5919 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005920 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005921#else
5922 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
5923 _Py_Gid_Converter, &basegid))
5924 return NULL;
5925#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005926
5927#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005928 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005929#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02005930 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005931#endif
5932 if (groups == NULL)
5933 return PyErr_NoMemory();
5934
5935 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
5936 PyMem_Del(groups);
5937 return posix_error();
5938 }
5939
5940 list = PyList_New(ngroups);
5941 if (list == NULL) {
5942 PyMem_Del(groups);
5943 return NULL;
5944 }
5945
5946 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005947#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005948 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005949#else
5950 PyObject *o = _PyLong_FromGid(groups[i]);
5951#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02005952 if (o == NULL) {
5953 Py_DECREF(list);
5954 PyMem_Del(groups);
5955 return NULL;
5956 }
5957 PyList_SET_ITEM(list, i, o);
5958 }
5959
5960 PyMem_Del(groups);
5961
5962 return list;
5963}
Larry Hastings2f936352014-08-05 14:04:04 +10005964#endif /* HAVE_GETGROUPLIST */
5965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005966
Fred Drakec9680921999-12-13 16:37:25 +00005967#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10005968/*[clinic input]
5969os.getgroups
5970
5971Return list of supplemental group IDs for the process.
5972[clinic start generated code]*/
5973
Larry Hastings2f936352014-08-05 14:04:04 +10005974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005975os_getgroups_impl(PyObject *module)
5976/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00005977{
5978 PyObject *result = NULL;
5979
Fred Drakec9680921999-12-13 16:37:25 +00005980#ifdef NGROUPS_MAX
5981#define MAX_GROUPS NGROUPS_MAX
5982#else
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00005984#define MAX_GROUPS 64
5985#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005987
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00005988 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00005989 * This is a helper variable to store the intermediate result when
5990 * that happens.
5991 *
5992 * To keep the code readable the OSX behaviour is unconditional,
5993 * according to the POSIX spec this should be safe on all unix-y
5994 * systems.
5995 */
5996 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00005997 int n;
Fred Drakec9680921999-12-13 16:37:25 +00005998
Ned Deilyb5dd6d22013-08-01 21:21:15 -07005999#ifdef __APPLE__
6000 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6001 * there are more groups than can fit in grouplist. Therefore, on OS X
6002 * always first call getgroups with length 0 to get the actual number
6003 * of groups.
6004 */
6005 n = getgroups(0, NULL);
6006 if (n < 0) {
6007 return posix_error();
6008 } else if (n <= MAX_GROUPS) {
6009 /* groups will fit in existing array */
6010 alt_grouplist = grouplist;
6011 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006012 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006013 if (alt_grouplist == NULL) {
6014 errno = EINVAL;
6015 return posix_error();
6016 }
6017 }
6018
6019 n = getgroups(n, alt_grouplist);
6020 if (n == -1) {
6021 if (alt_grouplist != grouplist) {
6022 PyMem_Free(alt_grouplist);
6023 }
6024 return posix_error();
6025 }
6026#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006027 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006028 if (n < 0) {
6029 if (errno == EINVAL) {
6030 n = getgroups(0, NULL);
6031 if (n == -1) {
6032 return posix_error();
6033 }
6034 if (n == 0) {
6035 /* Avoid malloc(0) */
6036 alt_grouplist = grouplist;
6037 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006038 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006039 if (alt_grouplist == NULL) {
6040 errno = EINVAL;
6041 return posix_error();
6042 }
6043 n = getgroups(n, alt_grouplist);
6044 if (n == -1) {
6045 PyMem_Free(alt_grouplist);
6046 return posix_error();
6047 }
6048 }
6049 } else {
6050 return posix_error();
6051 }
6052 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006053#endif
6054
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006055 result = PyList_New(n);
6056 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006057 int i;
6058 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006059 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006060 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006061 Py_DECREF(result);
6062 result = NULL;
6063 break;
Fred Drakec9680921999-12-13 16:37:25 +00006064 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006065 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006066 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006067 }
6068
6069 if (alt_grouplist != grouplist) {
6070 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006071 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006072
Fred Drakec9680921999-12-13 16:37:25 +00006073 return result;
6074}
Larry Hastings2f936352014-08-05 14:04:04 +10006075#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006076
Antoine Pitroub7572f02009-12-02 20:46:48 +00006077#ifdef HAVE_INITGROUPS
6078PyDoc_STRVAR(posix_initgroups__doc__,
6079"initgroups(username, gid) -> None\n\n\
6080Call the system initgroups() to initialize the group access list with all of\n\
6081the groups of which the specified username is a member, plus the specified\n\
6082group id.");
6083
Larry Hastings2f936352014-08-05 14:04:04 +10006084/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006085static PyObject *
6086posix_initgroups(PyObject *self, PyObject *args)
6087{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006088 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006089 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006090 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006091#ifdef __APPLE__
6092 int gid;
6093#else
6094 gid_t gid;
6095#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006096
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006097#ifdef __APPLE__
6098 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6099 PyUnicode_FSConverter, &oname,
6100 &gid))
6101#else
6102 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6103 PyUnicode_FSConverter, &oname,
6104 _Py_Gid_Converter, &gid))
6105#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006106 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006107 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006108
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006109 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006110 Py_DECREF(oname);
6111 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006112 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006113
Victor Stinner8c62be82010-05-06 00:08:46 +00006114 Py_INCREF(Py_None);
6115 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006116}
Larry Hastings2f936352014-08-05 14:04:04 +10006117#endif /* HAVE_INITGROUPS */
6118
Antoine Pitroub7572f02009-12-02 20:46:48 +00006119
Martin v. Löwis606edc12002-06-13 21:09:11 +00006120#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006121/*[clinic input]
6122os.getpgid
6123
6124 pid: pid_t
6125
6126Call the system call getpgid(), and return the result.
6127[clinic start generated code]*/
6128
Larry Hastings2f936352014-08-05 14:04:04 +10006129static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006130os_getpgid_impl(PyObject *module, pid_t pid)
6131/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006132{
6133 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006134 if (pgid < 0)
6135 return posix_error();
6136 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006137}
6138#endif /* HAVE_GETPGID */
6139
6140
Guido van Rossumb6775db1994-08-01 11:34:53 +00006141#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006142/*[clinic input]
6143os.getpgrp
6144
6145Return the current process group id.
6146[clinic start generated code]*/
6147
Larry Hastings2f936352014-08-05 14:04:04 +10006148static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006149os_getpgrp_impl(PyObject *module)
6150/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006151{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006152#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006154#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006156#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006157}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006158#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006160
Guido van Rossumb6775db1994-08-01 11:34:53 +00006161#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006162/*[clinic input]
6163os.setpgrp
6164
6165Make the current process the leader of its process group.
6166[clinic start generated code]*/
6167
Larry Hastings2f936352014-08-05 14:04:04 +10006168static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006169os_setpgrp_impl(PyObject *module)
6170/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006171{
Guido van Rossum64933891994-10-20 21:56:42 +00006172#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006173 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006174#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006175 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006176#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006177 return posix_error();
6178 Py_INCREF(Py_None);
6179 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006180}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006181#endif /* HAVE_SETPGRP */
6182
Guido van Rossumad0ee831995-03-01 10:34:45 +00006183#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006184
6185#ifdef MS_WINDOWS
6186#include <tlhelp32.h>
6187
6188static PyObject*
6189win32_getppid()
6190{
6191 HANDLE snapshot;
6192 pid_t mypid;
6193 PyObject* result = NULL;
6194 BOOL have_record;
6195 PROCESSENTRY32 pe;
6196
6197 mypid = getpid(); /* This function never fails */
6198
6199 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6200 if (snapshot == INVALID_HANDLE_VALUE)
6201 return PyErr_SetFromWindowsErr(GetLastError());
6202
6203 pe.dwSize = sizeof(pe);
6204 have_record = Process32First(snapshot, &pe);
6205 while (have_record) {
6206 if (mypid == (pid_t)pe.th32ProcessID) {
6207 /* We could cache the ulong value in a static variable. */
6208 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6209 break;
6210 }
6211
6212 have_record = Process32Next(snapshot, &pe);
6213 }
6214
6215 /* If our loop exits and our pid was not found (result will be NULL)
6216 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6217 * error anyway, so let's raise it. */
6218 if (!result)
6219 result = PyErr_SetFromWindowsErr(GetLastError());
6220
6221 CloseHandle(snapshot);
6222
6223 return result;
6224}
6225#endif /*MS_WINDOWS*/
6226
Larry Hastings2f936352014-08-05 14:04:04 +10006227
6228/*[clinic input]
6229os.getppid
6230
6231Return the parent's process id.
6232
6233If the parent process has already exited, Windows machines will still
6234return its id; others systems will return the id of the 'init' process (1).
6235[clinic start generated code]*/
6236
Larry Hastings2f936352014-08-05 14:04:04 +10006237static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006238os_getppid_impl(PyObject *module)
6239/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006240{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006241#ifdef MS_WINDOWS
6242 return win32_getppid();
6243#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006244 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006245#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006246}
6247#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006249
Fred Drake12c6e2d1999-12-14 21:25:03 +00006250#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006251/*[clinic input]
6252os.getlogin
6253
6254Return the actual login name.
6255[clinic start generated code]*/
6256
Larry Hastings2f936352014-08-05 14:04:04 +10006257static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006258os_getlogin_impl(PyObject *module)
6259/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006260{
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006262#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006263 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006264 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006265
6266 if (GetUserNameW(user_name, &num_chars)) {
6267 /* num_chars is the number of unicode chars plus null terminator */
6268 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006269 }
6270 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006271 result = PyErr_SetFromWindowsErr(GetLastError());
6272#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 char *name;
6274 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006275
Victor Stinner8c62be82010-05-06 00:08:46 +00006276 errno = 0;
6277 name = getlogin();
6278 if (name == NULL) {
6279 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006280 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006281 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006282 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 }
6284 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006285 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006287#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006288 return result;
6289}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006290#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006291
Larry Hastings2f936352014-08-05 14:04:04 +10006292
Guido van Rossumad0ee831995-03-01 10:34:45 +00006293#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006294/*[clinic input]
6295os.getuid
6296
6297Return the current process's user id.
6298[clinic start generated code]*/
6299
Larry Hastings2f936352014-08-05 14:04:04 +10006300static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006301os_getuid_impl(PyObject *module)
6302/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006303{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006304 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006305}
Larry Hastings2f936352014-08-05 14:04:04 +10006306#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006307
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006308
Brian Curtineb24d742010-04-12 17:16:38 +00006309#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006310#define HAVE_KILL
6311#endif /* MS_WINDOWS */
6312
6313#ifdef HAVE_KILL
6314/*[clinic input]
6315os.kill
6316
6317 pid: pid_t
6318 signal: Py_ssize_t
6319 /
6320
6321Kill a process with a signal.
6322[clinic start generated code]*/
6323
Larry Hastings2f936352014-08-05 14:04:04 +10006324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006325os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6326/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006327#ifndef MS_WINDOWS
6328{
6329 if (kill(pid, (int)signal) == -1)
6330 return posix_error();
6331 Py_RETURN_NONE;
6332}
6333#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006334{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006335 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006336 DWORD sig = (DWORD)signal;
6337 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006339
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 /* Console processes which share a common console can be sent CTRL+C or
6341 CTRL+BREAK events, provided they handle said events. */
6342 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006343 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 err = GetLastError();
6345 PyErr_SetFromWindowsErr(err);
6346 }
6347 else
6348 Py_RETURN_NONE;
6349 }
Brian Curtineb24d742010-04-12 17:16:38 +00006350
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6352 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006353 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006354 if (handle == NULL) {
6355 err = GetLastError();
6356 return PyErr_SetFromWindowsErr(err);
6357 }
Brian Curtineb24d742010-04-12 17:16:38 +00006358
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 if (TerminateProcess(handle, sig) == 0) {
6360 err = GetLastError();
6361 result = PyErr_SetFromWindowsErr(err);
6362 } else {
6363 Py_INCREF(Py_None);
6364 result = Py_None;
6365 }
Brian Curtineb24d742010-04-12 17:16:38 +00006366
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 CloseHandle(handle);
6368 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006369}
Larry Hastings2f936352014-08-05 14:04:04 +10006370#endif /* !MS_WINDOWS */
6371#endif /* HAVE_KILL */
6372
6373
6374#ifdef HAVE_KILLPG
6375/*[clinic input]
6376os.killpg
6377
6378 pgid: pid_t
6379 signal: int
6380 /
6381
6382Kill a process group with a signal.
6383[clinic start generated code]*/
6384
Larry Hastings2f936352014-08-05 14:04:04 +10006385static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006386os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6387/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006388{
6389 /* XXX some man pages make the `pgid` parameter an int, others
6390 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6391 take the same type. Moreover, pid_t is always at least as wide as
6392 int (else compilation of this module fails), which is safe. */
6393 if (killpg(pgid, signal) == -1)
6394 return posix_error();
6395 Py_RETURN_NONE;
6396}
6397#endif /* HAVE_KILLPG */
6398
Brian Curtineb24d742010-04-12 17:16:38 +00006399
Guido van Rossumc0125471996-06-28 18:55:32 +00006400#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006401#ifdef HAVE_SYS_LOCK_H
6402#include <sys/lock.h>
6403#endif
6404
Larry Hastings2f936352014-08-05 14:04:04 +10006405/*[clinic input]
6406os.plock
6407 op: int
6408 /
6409
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006410Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006411[clinic start generated code]*/
6412
Larry Hastings2f936352014-08-05 14:04:04 +10006413static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006414os_plock_impl(PyObject *module, int op)
6415/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006416{
Victor Stinner8c62be82010-05-06 00:08:46 +00006417 if (plock(op) == -1)
6418 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006419 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006420}
Larry Hastings2f936352014-08-05 14:04:04 +10006421#endif /* HAVE_PLOCK */
6422
Guido van Rossumc0125471996-06-28 18:55:32 +00006423
Guido van Rossumb6775db1994-08-01 11:34:53 +00006424#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006425/*[clinic input]
6426os.setuid
6427
6428 uid: uid_t
6429 /
6430
6431Set the current process's user id.
6432[clinic start generated code]*/
6433
Larry Hastings2f936352014-08-05 14:04:04 +10006434static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006435os_setuid_impl(PyObject *module, uid_t uid)
6436/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006437{
Victor Stinner8c62be82010-05-06 00:08:46 +00006438 if (setuid(uid) < 0)
6439 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006440 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006441}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006442#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006443
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006444
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006445#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006446/*[clinic input]
6447os.seteuid
6448
6449 euid: uid_t
6450 /
6451
6452Set the current process's effective user id.
6453[clinic start generated code]*/
6454
Larry Hastings2f936352014-08-05 14:04:04 +10006455static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006456os_seteuid_impl(PyObject *module, uid_t euid)
6457/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006458{
6459 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006460 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006461 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006462}
6463#endif /* HAVE_SETEUID */
6464
Larry Hastings2f936352014-08-05 14:04:04 +10006465
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006466#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006467/*[clinic input]
6468os.setegid
6469
6470 egid: gid_t
6471 /
6472
6473Set the current process's effective group id.
6474[clinic start generated code]*/
6475
Larry Hastings2f936352014-08-05 14:04:04 +10006476static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006477os_setegid_impl(PyObject *module, gid_t egid)
6478/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006479{
6480 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006481 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006482 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006483}
6484#endif /* HAVE_SETEGID */
6485
Larry Hastings2f936352014-08-05 14:04:04 +10006486
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006487#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006488/*[clinic input]
6489os.setreuid
6490
6491 ruid: uid_t
6492 euid: uid_t
6493 /
6494
6495Set the current process's real and effective user ids.
6496[clinic start generated code]*/
6497
Larry Hastings2f936352014-08-05 14:04:04 +10006498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006499os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6500/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006501{
Victor Stinner8c62be82010-05-06 00:08:46 +00006502 if (setreuid(ruid, euid) < 0) {
6503 return posix_error();
6504 } else {
6505 Py_INCREF(Py_None);
6506 return Py_None;
6507 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006508}
6509#endif /* HAVE_SETREUID */
6510
Larry Hastings2f936352014-08-05 14:04:04 +10006511
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006512#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006513/*[clinic input]
6514os.setregid
6515
6516 rgid: gid_t
6517 egid: gid_t
6518 /
6519
6520Set the current process's real and effective group ids.
6521[clinic start generated code]*/
6522
Larry Hastings2f936352014-08-05 14:04:04 +10006523static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006524os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6525/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006526{
6527 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006529 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006530}
6531#endif /* HAVE_SETREGID */
6532
Larry Hastings2f936352014-08-05 14:04:04 +10006533
Guido van Rossumb6775db1994-08-01 11:34:53 +00006534#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006535/*[clinic input]
6536os.setgid
6537 gid: gid_t
6538 /
6539
6540Set the current process's group id.
6541[clinic start generated code]*/
6542
Larry Hastings2f936352014-08-05 14:04:04 +10006543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006544os_setgid_impl(PyObject *module, gid_t gid)
6545/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006546{
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 if (setgid(gid) < 0)
6548 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006549 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006550}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006551#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006552
Larry Hastings2f936352014-08-05 14:04:04 +10006553
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006554#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006555/*[clinic input]
6556os.setgroups
6557
6558 groups: object
6559 /
6560
6561Set the groups of the current process to list.
6562[clinic start generated code]*/
6563
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006565os_setgroups(PyObject *module, PyObject *groups)
6566/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006567{
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 int i, len;
6569 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006570
Victor Stinner8c62be82010-05-06 00:08:46 +00006571 if (!PySequence_Check(groups)) {
6572 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6573 return NULL;
6574 }
6575 len = PySequence_Size(groups);
6576 if (len > MAX_GROUPS) {
6577 PyErr_SetString(PyExc_ValueError, "too many groups");
6578 return NULL;
6579 }
6580 for(i = 0; i < len; i++) {
6581 PyObject *elem;
6582 elem = PySequence_GetItem(groups, i);
6583 if (!elem)
6584 return NULL;
6585 if (!PyLong_Check(elem)) {
6586 PyErr_SetString(PyExc_TypeError,
6587 "groups must be integers");
6588 Py_DECREF(elem);
6589 return NULL;
6590 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006591 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006592 Py_DECREF(elem);
6593 return NULL;
6594 }
6595 }
6596 Py_DECREF(elem);
6597 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006598
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 if (setgroups(len, grouplist) < 0)
6600 return posix_error();
6601 Py_INCREF(Py_None);
6602 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006603}
6604#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006605
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006606#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6607static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006608wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006609{
Victor Stinner8c62be82010-05-06 00:08:46 +00006610 PyObject *result;
6611 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006612 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006613
Victor Stinner8c62be82010-05-06 00:08:46 +00006614 if (pid == -1)
6615 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006616
Victor Stinner8c62be82010-05-06 00:08:46 +00006617 if (struct_rusage == NULL) {
6618 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6619 if (m == NULL)
6620 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006621 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006622 Py_DECREF(m);
6623 if (struct_rusage == NULL)
6624 return NULL;
6625 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006626
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6628 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6629 if (!result)
6630 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006631
6632#ifndef doubletime
6633#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6634#endif
6635
Victor Stinner8c62be82010-05-06 00:08:46 +00006636 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006637 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006639 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006640#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006641 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6642 SET_INT(result, 2, ru->ru_maxrss);
6643 SET_INT(result, 3, ru->ru_ixrss);
6644 SET_INT(result, 4, ru->ru_idrss);
6645 SET_INT(result, 5, ru->ru_isrss);
6646 SET_INT(result, 6, ru->ru_minflt);
6647 SET_INT(result, 7, ru->ru_majflt);
6648 SET_INT(result, 8, ru->ru_nswap);
6649 SET_INT(result, 9, ru->ru_inblock);
6650 SET_INT(result, 10, ru->ru_oublock);
6651 SET_INT(result, 11, ru->ru_msgsnd);
6652 SET_INT(result, 12, ru->ru_msgrcv);
6653 SET_INT(result, 13, ru->ru_nsignals);
6654 SET_INT(result, 14, ru->ru_nvcsw);
6655 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006656#undef SET_INT
6657
Victor Stinner8c62be82010-05-06 00:08:46 +00006658 if (PyErr_Occurred()) {
6659 Py_DECREF(result);
6660 return NULL;
6661 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006662
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006664}
6665#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6666
Larry Hastings2f936352014-08-05 14:04:04 +10006667
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006668#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006669/*[clinic input]
6670os.wait3
6671
6672 options: int
6673Wait for completion of a child process.
6674
6675Returns a tuple of information about the child process:
6676 (pid, status, rusage)
6677[clinic start generated code]*/
6678
Larry Hastings2f936352014-08-05 14:04:04 +10006679static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006680os_wait3_impl(PyObject *module, int options)
6681/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006682{
Victor Stinner8c62be82010-05-06 00:08:46 +00006683 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006685 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006686 WAIT_TYPE status;
6687 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006688
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006689 do {
6690 Py_BEGIN_ALLOW_THREADS
6691 pid = wait3(&status, options, &ru);
6692 Py_END_ALLOW_THREADS
6693 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6694 if (pid < 0)
6695 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006696
Victor Stinner4195b5c2012-02-08 23:03:19 +01006697 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006698}
6699#endif /* HAVE_WAIT3 */
6700
Larry Hastings2f936352014-08-05 14:04:04 +10006701
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006702#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006703/*[clinic input]
6704
6705os.wait4
6706
6707 pid: pid_t
6708 options: int
6709
6710Wait for completion of a specific child process.
6711
6712Returns a tuple of information about the child process:
6713 (pid, status, rusage)
6714[clinic start generated code]*/
6715
Larry Hastings2f936352014-08-05 14:04:04 +10006716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006717os_wait4_impl(PyObject *module, pid_t pid, int options)
6718/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006719{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006720 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006721 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006722 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006723 WAIT_TYPE status;
6724 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006725
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006726 do {
6727 Py_BEGIN_ALLOW_THREADS
6728 res = wait4(pid, &status, options, &ru);
6729 Py_END_ALLOW_THREADS
6730 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6731 if (res < 0)
6732 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006733
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006734 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006735}
6736#endif /* HAVE_WAIT4 */
6737
Larry Hastings2f936352014-08-05 14:04:04 +10006738
Ross Lagerwall7807c352011-03-17 20:20:30 +02006739#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006740/*[clinic input]
6741os.waitid
6742
6743 idtype: idtype_t
6744 Must be one of be P_PID, P_PGID or P_ALL.
6745 id: id_t
6746 The id to wait on.
6747 options: int
6748 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6749 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6750 /
6751
6752Returns the result of waiting for a process or processes.
6753
6754Returns either waitid_result or None if WNOHANG is specified and there are
6755no children in a waitable state.
6756[clinic start generated code]*/
6757
Larry Hastings2f936352014-08-05 14:04:04 +10006758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006759os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6760/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006761{
6762 PyObject *result;
6763 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006764 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006765 siginfo_t si;
6766 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006767
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006768 do {
6769 Py_BEGIN_ALLOW_THREADS
6770 res = waitid(idtype, id, &si, options);
6771 Py_END_ALLOW_THREADS
6772 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6773 if (res < 0)
6774 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006775
6776 if (si.si_pid == 0)
6777 Py_RETURN_NONE;
6778
6779 result = PyStructSequence_New(&WaitidResultType);
6780 if (!result)
6781 return NULL;
6782
6783 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006784 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006785 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6786 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6787 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6788 if (PyErr_Occurred()) {
6789 Py_DECREF(result);
6790 return NULL;
6791 }
6792
6793 return result;
6794}
Larry Hastings2f936352014-08-05 14:04:04 +10006795#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006796
Larry Hastings2f936352014-08-05 14:04:04 +10006797
6798#if defined(HAVE_WAITPID)
6799/*[clinic input]
6800os.waitpid
6801 pid: pid_t
6802 options: int
6803 /
6804
6805Wait for completion of a given child process.
6806
6807Returns a tuple of information regarding the child process:
6808 (pid, status)
6809
6810The options argument is ignored on Windows.
6811[clinic start generated code]*/
6812
Larry Hastings2f936352014-08-05 14:04:04 +10006813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006814os_waitpid_impl(PyObject *module, pid_t pid, int options)
6815/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006816{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006817 pid_t res;
6818 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 WAIT_TYPE status;
6820 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006821
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006822 do {
6823 Py_BEGIN_ALLOW_THREADS
6824 res = waitpid(pid, &status, options);
6825 Py_END_ALLOW_THREADS
6826 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6827 if (res < 0)
6828 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006830 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006831}
Tim Petersab034fa2002-02-01 11:27:43 +00006832#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006833/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006834/*[clinic input]
6835os.waitpid
Benjamin Petersonca470632016-09-06 13:47:26 -07006836 pid: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +10006837 options: int
6838 /
6839
6840Wait for completion of a given process.
6841
6842Returns a tuple of information regarding the process:
6843 (pid, status << 8)
6844
6845The options argument is ignored on Windows.
6846[clinic start generated code]*/
6847
Larry Hastings2f936352014-08-05 14:04:04 +10006848static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -07006849os_waitpid_impl(PyObject *module, intptr_t pid, int options)
Victor Stinner581139c2016-09-06 15:54:20 -07006850/*[clinic end generated code: output=be836b221271d538 input=40f2440c515410f8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006851{
6852 int status;
Benjamin Petersonca470632016-09-06 13:47:26 -07006853 intptr_t res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006854 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006855
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006856 do {
6857 Py_BEGIN_ALLOW_THREADS
6858 res = _cwait(&status, pid, options);
6859 Py_END_ALLOW_THREADS
6860 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02006861 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006862 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006865 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00006866}
Larry Hastings2f936352014-08-05 14:04:04 +10006867#endif
6868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006869
Guido van Rossumad0ee831995-03-01 10:34:45 +00006870#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10006871/*[clinic input]
6872os.wait
6873
6874Wait for completion of a child process.
6875
6876Returns a tuple of information about the child process:
6877 (pid, status)
6878[clinic start generated code]*/
6879
Larry Hastings2f936352014-08-05 14:04:04 +10006880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006881os_wait_impl(PyObject *module)
6882/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00006883{
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006885 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 WAIT_TYPE status;
6887 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00006888
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006889 do {
6890 Py_BEGIN_ALLOW_THREADS
6891 pid = wait(&status);
6892 Py_END_ALLOW_THREADS
6893 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6894 if (pid < 0)
6895 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896
Victor Stinner8c62be82010-05-06 00:08:46 +00006897 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00006898}
Larry Hastings2f936352014-08-05 14:04:04 +10006899#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006900
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006901
Larry Hastings9cf065c2012-06-22 16:30:09 -07006902#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
6903PyDoc_STRVAR(readlink__doc__,
6904"readlink(path, *, dir_fd=None) -> path\n\n\
6905Return a string representing the path to which the symbolic link points.\n\
6906\n\
6907If dir_fd is not None, it should be a file descriptor open to a directory,\n\
6908 and path should be relative; path will then be relative to that directory.\n\
6909dir_fd may not be implemented on your platform.\n\
6910 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00006911#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006912
Guido van Rossumb6775db1994-08-01 11:34:53 +00006913#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006914
Larry Hastings2f936352014-08-05 14:04:04 +10006915/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00006916static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07006917posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006918{
Larry Hastings9cf065c2012-06-22 16:30:09 -07006919 path_t path;
6920 int dir_fd = DEFAULT_DIR_FD;
6921 char buffer[MAXPATHLEN];
6922 ssize_t length;
6923 PyObject *return_value = NULL;
6924 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00006925
Larry Hastings9cf065c2012-06-22 16:30:09 -07006926 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01006927 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07006928 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
6929 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10006930 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00006931 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00006932
Victor Stinner8c62be82010-05-06 00:08:46 +00006933 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07006934#ifdef HAVE_READLINKAT
6935 if (dir_fd != DEFAULT_DIR_FD)
6936 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00006937 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07006938#endif
6939 length = readlink(path.narrow, buffer, sizeof(buffer));
6940 Py_END_ALLOW_THREADS
6941
6942 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01006943 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07006944 goto exit;
6945 }
6946
6947 if (PyUnicode_Check(path.object))
6948 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
6949 else
6950 return_value = PyBytes_FromStringAndSize(buffer, length);
6951exit:
6952 path_cleanup(&path);
6953 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006954}
Larry Hastings9cf065c2012-06-22 16:30:09 -07006955
Guido van Rossumb6775db1994-08-01 11:34:53 +00006956#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00006957
Larry Hastings2f936352014-08-05 14:04:04 +10006958#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
6959
6960static PyObject *
6961win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
6962{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006963 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10006964 DWORD n_bytes_returned;
6965 DWORD io_result;
6966 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006967 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10006968 HANDLE reparse_point_handle;
6969
Martin Panter70214ad2016-08-04 02:38:59 +00006970 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
6971 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006972 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10006973
6974 static char *keywords[] = {"path", "dir_fd", NULL};
6975
6976 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
6977 &po,
6978 dir_fd_unavailable, &dir_fd
6979 ))
6980 return NULL;
6981
6982 path = PyUnicode_AsUnicode(po);
6983 if (path == NULL)
6984 return NULL;
6985
6986 /* First get a handle to the reparse point */
6987 Py_BEGIN_ALLOW_THREADS
6988 reparse_point_handle = CreateFileW(
6989 path,
6990 0,
6991 0,
6992 0,
6993 OPEN_EXISTING,
6994 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
6995 0);
6996 Py_END_ALLOW_THREADS
6997
6998 if (reparse_point_handle==INVALID_HANDLE_VALUE)
6999 return win32_error_object("readlink", po);
7000
7001 Py_BEGIN_ALLOW_THREADS
7002 /* New call DeviceIoControl to read the reparse point */
7003 io_result = DeviceIoControl(
7004 reparse_point_handle,
7005 FSCTL_GET_REPARSE_POINT,
7006 0, 0, /* in buffer */
7007 target_buffer, sizeof(target_buffer),
7008 &n_bytes_returned,
7009 0 /* we're not using OVERLAPPED_IO */
7010 );
7011 CloseHandle(reparse_point_handle);
7012 Py_END_ALLOW_THREADS
7013
7014 if (io_result==0)
7015 return win32_error_object("readlink", po);
7016
7017 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7018 {
7019 PyErr_SetString(PyExc_ValueError,
7020 "not a symbolic link");
7021 return NULL;
7022 }
7023 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7024 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7025
7026 result = PyUnicode_FromWideChar(print_name,
7027 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7028 return result;
7029}
7030
7031#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7032
7033
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007034
Larry Hastings9cf065c2012-06-22 16:30:09 -07007035#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007036
7037#if defined(MS_WINDOWS)
7038
7039/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007040static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007041
Larry Hastings9cf065c2012-06-22 16:30:09 -07007042static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007043check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007044{
7045 HINSTANCE hKernel32;
7046 /* only recheck */
Steve Dowercc16be82016-09-08 10:35:16 -07007047 if (Py_CreateSymbolicLinkW)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007048 return 1;
7049 hKernel32 = GetModuleHandleW(L"KERNEL32");
7050 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7051 "CreateSymbolicLinkW");
Steve Dowercc16be82016-09-08 10:35:16 -07007052 return Py_CreateSymbolicLinkW != NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007053}
7054
Victor Stinner31b3b922013-06-05 01:49:17 +02007055/* Remove the last portion of the path */
7056static void
7057_dirnameW(WCHAR *path)
7058{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007059 WCHAR *ptr;
7060
7061 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007062 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007063 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007064 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007065 }
7066 *ptr = 0;
7067}
7068
Victor Stinner31b3b922013-06-05 01:49:17 +02007069/* Is this path absolute? */
7070static int
7071_is_absW(const WCHAR *path)
7072{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007073 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7074
7075}
7076
Victor Stinner31b3b922013-06-05 01:49:17 +02007077/* join root and rest with a backslash */
7078static void
7079_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7080{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007081 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007082
Victor Stinner31b3b922013-06-05 01:49:17 +02007083 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007084 wcscpy(dest_path, rest);
7085 return;
7086 }
7087
7088 root_len = wcslen(root);
7089
7090 wcscpy(dest_path, root);
7091 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007092 dest_path[root_len] = L'\\';
7093 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007094 }
7095 wcscpy(dest_path+root_len, rest);
7096}
7097
Victor Stinner31b3b922013-06-05 01:49:17 +02007098/* Return True if the path at src relative to dest is a directory */
7099static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007100_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007101{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007102 WIN32_FILE_ATTRIBUTE_DATA src_info;
7103 WCHAR dest_parent[MAX_PATH];
7104 WCHAR src_resolved[MAX_PATH] = L"";
7105
7106 /* dest_parent = os.path.dirname(dest) */
7107 wcscpy(dest_parent, dest);
7108 _dirnameW(dest_parent);
7109 /* src_resolved = os.path.join(dest_parent, src) */
7110 _joinW(src_resolved, dest_parent, src);
7111 return (
7112 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7113 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7114 );
7115}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007117
Larry Hastings2f936352014-08-05 14:04:04 +10007118
7119/*[clinic input]
7120os.symlink
7121 src: path_t
7122 dst: path_t
7123 target_is_directory: bool = False
7124 *
7125 dir_fd: dir_fd(requires='symlinkat')=None
7126
7127# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7128
7129Create a symbolic link pointing to src named dst.
7130
7131target_is_directory is required on Windows if the target is to be
7132 interpreted as a directory. (On Windows, symlink requires
7133 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7134 target_is_directory is ignored on non-Windows platforms.
7135
7136If dir_fd is not None, it should be a file descriptor open to a directory,
7137 and path should be relative; path will then be relative to that directory.
7138dir_fd may not be implemented on your platform.
7139 If it is unavailable, using it will raise a NotImplementedError.
7140
7141[clinic start generated code]*/
7142
Larry Hastings2f936352014-08-05 14:04:04 +10007143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007144os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007145 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007146/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007147{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148#ifdef MS_WINDOWS
7149 DWORD result;
7150#else
7151 int result;
7152#endif
7153
Larry Hastings9cf065c2012-06-22 16:30:09 -07007154#ifdef MS_WINDOWS
7155 if (!check_CreateSymbolicLink()) {
7156 PyErr_SetString(PyExc_NotImplementedError,
7157 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007158 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007159 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007160 if (!win32_can_symlink) {
7161 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007162 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007163 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164#endif
7165
Larry Hastings2f936352014-08-05 14:04:04 +10007166 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007167 PyErr_SetString(PyExc_ValueError,
7168 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007169 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170 }
7171
7172#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007173
Larry Hastings9cf065c2012-06-22 16:30:09 -07007174 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -07007175 /* if src is a directory, ensure target_is_directory==1 */
7176 target_is_directory |= _check_dirW(src->wide, dst->wide);
7177 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
7178 target_is_directory);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007179 Py_END_ALLOW_THREADS
7180
Larry Hastings2f936352014-08-05 14:04:04 +10007181 if (!result)
7182 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007183
7184#else
7185
7186 Py_BEGIN_ALLOW_THREADS
7187#if HAVE_SYMLINKAT
7188 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007189 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190 else
7191#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007192 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007193 Py_END_ALLOW_THREADS
7194
Larry Hastings2f936352014-08-05 14:04:04 +10007195 if (result)
7196 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197#endif
7198
Larry Hastings2f936352014-08-05 14:04:04 +10007199 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007200}
7201#endif /* HAVE_SYMLINK */
7202
Larry Hastings9cf065c2012-06-22 16:30:09 -07007203
Brian Curtind40e6f72010-07-08 21:39:08 +00007204
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007205
Larry Hastings605a62d2012-06-24 04:33:36 -07007206static PyStructSequence_Field times_result_fields[] = {
7207 {"user", "user time"},
7208 {"system", "system time"},
7209 {"children_user", "user time of children"},
7210 {"children_system", "system time of children"},
7211 {"elapsed", "elapsed time since an arbitrary point in the past"},
7212 {NULL}
7213};
7214
7215PyDoc_STRVAR(times_result__doc__,
7216"times_result: Result from os.times().\n\n\
7217This object may be accessed either as a tuple of\n\
7218 (user, system, children_user, children_system, elapsed),\n\
7219or via the attributes user, system, children_user, children_system,\n\
7220and elapsed.\n\
7221\n\
7222See os.times for more information.");
7223
7224static PyStructSequence_Desc times_result_desc = {
7225 "times_result", /* name */
7226 times_result__doc__, /* doc */
7227 times_result_fields,
7228 5
7229};
7230
7231static PyTypeObject TimesResultType;
7232
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007233#ifdef MS_WINDOWS
7234#define HAVE_TIMES /* mandatory, for the method table */
7235#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007236
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007237#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007238
7239static PyObject *
7240build_times_result(double user, double system,
7241 double children_user, double children_system,
7242 double elapsed)
7243{
7244 PyObject *value = PyStructSequence_New(&TimesResultType);
7245 if (value == NULL)
7246 return NULL;
7247
7248#define SET(i, field) \
7249 { \
7250 PyObject *o = PyFloat_FromDouble(field); \
7251 if (!o) { \
7252 Py_DECREF(value); \
7253 return NULL; \
7254 } \
7255 PyStructSequence_SET_ITEM(value, i, o); \
7256 } \
7257
7258 SET(0, user);
7259 SET(1, system);
7260 SET(2, children_user);
7261 SET(3, children_system);
7262 SET(4, elapsed);
7263
7264#undef SET
7265
7266 return value;
7267}
7268
Larry Hastings605a62d2012-06-24 04:33:36 -07007269
Larry Hastings2f936352014-08-05 14:04:04 +10007270#ifndef MS_WINDOWS
7271#define NEED_TICKS_PER_SECOND
7272static long ticks_per_second = -1;
7273#endif /* MS_WINDOWS */
7274
7275/*[clinic input]
7276os.times
7277
7278Return a collection containing process timing information.
7279
7280The object returned behaves like a named tuple with these fields:
7281 (utime, stime, cutime, cstime, elapsed_time)
7282All fields are floating point numbers.
7283[clinic start generated code]*/
7284
Larry Hastings2f936352014-08-05 14:04:04 +10007285static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007286os_times_impl(PyObject *module)
7287/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007288#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007289{
Victor Stinner8c62be82010-05-06 00:08:46 +00007290 FILETIME create, exit, kernel, user;
7291 HANDLE hProc;
7292 hProc = GetCurrentProcess();
7293 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7294 /* The fields of a FILETIME structure are the hi and lo part
7295 of a 64-bit value expressed in 100 nanosecond units.
7296 1e7 is one second in such units; 1e-7 the inverse.
7297 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7298 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007299 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007300 (double)(user.dwHighDateTime*429.4967296 +
7301 user.dwLowDateTime*1e-7),
7302 (double)(kernel.dwHighDateTime*429.4967296 +
7303 kernel.dwLowDateTime*1e-7),
7304 (double)0,
7305 (double)0,
7306 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007307}
Larry Hastings2f936352014-08-05 14:04:04 +10007308#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007309{
Larry Hastings2f936352014-08-05 14:04:04 +10007310
7311
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007312 struct tms t;
7313 clock_t c;
7314 errno = 0;
7315 c = times(&t);
7316 if (c == (clock_t) -1)
7317 return posix_error();
7318 return build_times_result(
7319 (double)t.tms_utime / ticks_per_second,
7320 (double)t.tms_stime / ticks_per_second,
7321 (double)t.tms_cutime / ticks_per_second,
7322 (double)t.tms_cstime / ticks_per_second,
7323 (double)c / ticks_per_second);
7324}
Larry Hastings2f936352014-08-05 14:04:04 +10007325#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007326#endif /* HAVE_TIMES */
7327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007328
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007329#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007330/*[clinic input]
7331os.getsid
7332
7333 pid: pid_t
7334 /
7335
7336Call the system call getsid(pid) and return the result.
7337[clinic start generated code]*/
7338
Larry Hastings2f936352014-08-05 14:04:04 +10007339static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007340os_getsid_impl(PyObject *module, pid_t pid)
7341/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007342{
Victor Stinner8c62be82010-05-06 00:08:46 +00007343 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007344 sid = getsid(pid);
7345 if (sid < 0)
7346 return posix_error();
7347 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007348}
7349#endif /* HAVE_GETSID */
7350
7351
Guido van Rossumb6775db1994-08-01 11:34:53 +00007352#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007353/*[clinic input]
7354os.setsid
7355
7356Call the system call setsid().
7357[clinic start generated code]*/
7358
Larry Hastings2f936352014-08-05 14:04:04 +10007359static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007360os_setsid_impl(PyObject *module)
7361/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007362{
Victor Stinner8c62be82010-05-06 00:08:46 +00007363 if (setsid() < 0)
7364 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007365 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007366}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007367#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007368
Larry Hastings2f936352014-08-05 14:04:04 +10007369
Guido van Rossumb6775db1994-08-01 11:34:53 +00007370#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007371/*[clinic input]
7372os.setpgid
7373
7374 pid: pid_t
7375 pgrp: pid_t
7376 /
7377
7378Call the system call setpgid(pid, pgrp).
7379[clinic start generated code]*/
7380
Larry Hastings2f936352014-08-05 14:04:04 +10007381static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007382os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7383/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007384{
Victor Stinner8c62be82010-05-06 00:08:46 +00007385 if (setpgid(pid, pgrp) < 0)
7386 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007387 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007388}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007389#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007390
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007391
Guido van Rossumb6775db1994-08-01 11:34:53 +00007392#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007393/*[clinic input]
7394os.tcgetpgrp
7395
7396 fd: int
7397 /
7398
7399Return the process group associated with the terminal specified by fd.
7400[clinic start generated code]*/
7401
Larry Hastings2f936352014-08-05 14:04:04 +10007402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007403os_tcgetpgrp_impl(PyObject *module, int fd)
7404/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007405{
7406 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007407 if (pgid < 0)
7408 return posix_error();
7409 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007410}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007411#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007412
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007413
Guido van Rossumb6775db1994-08-01 11:34:53 +00007414#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007415/*[clinic input]
7416os.tcsetpgrp
7417
7418 fd: int
7419 pgid: pid_t
7420 /
7421
7422Set the process group associated with the terminal specified by fd.
7423[clinic start generated code]*/
7424
Larry Hastings2f936352014-08-05 14:04:04 +10007425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007426os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7427/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007428{
Victor Stinner8c62be82010-05-06 00:08:46 +00007429 if (tcsetpgrp(fd, pgid) < 0)
7430 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007431 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007432}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007433#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007434
Guido van Rossum687dd131993-05-17 08:34:16 +00007435/* Functions acting on file descriptors */
7436
Victor Stinnerdaf45552013-08-28 00:53:59 +02007437#ifdef O_CLOEXEC
7438extern int _Py_open_cloexec_works;
7439#endif
7440
Larry Hastings2f936352014-08-05 14:04:04 +10007441
7442/*[clinic input]
7443os.open -> int
7444 path: path_t
7445 flags: int
7446 mode: int = 0o777
7447 *
7448 dir_fd: dir_fd(requires='openat') = None
7449
7450# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7451
7452Open a file for low level IO. Returns a file descriptor (integer).
7453
7454If dir_fd is not None, it should be a file descriptor open to a directory,
7455 and path should be relative; path will then be relative to that directory.
7456dir_fd may not be implemented on your platform.
7457 If it is unavailable, using it will raise a NotImplementedError.
7458[clinic start generated code]*/
7459
Larry Hastings2f936352014-08-05 14:04:04 +10007460static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007461os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7462/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007463{
7464 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007465 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007466
Victor Stinnerdaf45552013-08-28 00:53:59 +02007467#ifdef O_CLOEXEC
7468 int *atomic_flag_works = &_Py_open_cloexec_works;
7469#elif !defined(MS_WINDOWS)
7470 int *atomic_flag_works = NULL;
7471#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007472
Victor Stinnerdaf45552013-08-28 00:53:59 +02007473#ifdef MS_WINDOWS
7474 flags |= O_NOINHERIT;
7475#elif defined(O_CLOEXEC)
7476 flags |= O_CLOEXEC;
7477#endif
7478
Steve Dower8fc89802015-04-12 00:26:27 -04007479 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007480 do {
7481 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007482#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07007483 fd = _wopen(path->wide, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007484#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007485#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007486 if (dir_fd != DEFAULT_DIR_FD)
7487 fd = openat(dir_fd, path->narrow, flags, mode);
7488 else
Steve Dower6230aaf2016-09-09 09:03:15 -07007489#endif /* HAVE_OPENAT */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007490 fd = open(path->narrow, flags, mode);
Steve Dower6230aaf2016-09-09 09:03:15 -07007491#endif /* !MS_WINDOWS */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007492 Py_END_ALLOW_THREADS
7493 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007494 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007495
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007496 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007497 if (!async_err)
7498 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007499 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007500 }
7501
Victor Stinnerdaf45552013-08-28 00:53:59 +02007502#ifndef MS_WINDOWS
7503 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7504 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007505 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007506 }
7507#endif
7508
Larry Hastings2f936352014-08-05 14:04:04 +10007509 return fd;
7510}
7511
7512
7513/*[clinic input]
7514os.close
7515
7516 fd: int
7517
7518Close a file descriptor.
7519[clinic start generated code]*/
7520
Barry Warsaw53699e91996-12-10 23:23:01 +00007521static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007522os_close_impl(PyObject *module, int fd)
7523/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007524{
Larry Hastings2f936352014-08-05 14:04:04 +10007525 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007526 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7527 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7528 * for more details.
7529 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007531 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007533 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007534 Py_END_ALLOW_THREADS
7535 if (res < 0)
7536 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007537 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007538}
7539
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007540
Larry Hastings2f936352014-08-05 14:04:04 +10007541/*[clinic input]
7542os.closerange
7543
7544 fd_low: int
7545 fd_high: int
7546 /
7547
7548Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7549[clinic start generated code]*/
7550
Larry Hastings2f936352014-08-05 14:04:04 +10007551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007552os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7553/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007554{
7555 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007557 _Py_BEGIN_SUPPRESS_IPH
Benjamin Peterson207116b2016-09-08 11:28:06 -07007558 for (i = Py_MAX(fd_low, 0); i < fd_high; i++)
Steve Dower940f33a2016-09-08 11:21:54 -07007559 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007560 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007561 Py_END_ALLOW_THREADS
7562 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007563}
7564
7565
Larry Hastings2f936352014-08-05 14:04:04 +10007566/*[clinic input]
7567os.dup -> int
7568
7569 fd: int
7570 /
7571
7572Return a duplicate of a file descriptor.
7573[clinic start generated code]*/
7574
Larry Hastings2f936352014-08-05 14:04:04 +10007575static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007576os_dup_impl(PyObject *module, int fd)
7577/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007578{
7579 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007580}
7581
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007582
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.dup2
7585 fd: int
7586 fd2: int
7587 inheritable: bool=True
7588
7589Duplicate file descriptor.
7590[clinic start generated code]*/
7591
Larry Hastings2f936352014-08-05 14:04:04 +10007592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007593os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7594/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007595{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007596 int res;
7597#if defined(HAVE_DUP3) && \
7598 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7599 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7600 int dup3_works = -1;
7601#endif
7602
Steve Dower940f33a2016-09-08 11:21:54 -07007603 if (fd < 0 || fd2 < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007605
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007606 /* dup2() can fail with EINTR if the target FD is already open, because it
7607 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7608 * upon close(), and therefore below.
7609 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007610#ifdef MS_WINDOWS
7611 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007612 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007613 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007614 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007615 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 if (res < 0)
7617 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007618
7619 /* Character files like console cannot be make non-inheritable */
7620 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7621 close(fd2);
7622 return NULL;
7623 }
7624
7625#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7626 Py_BEGIN_ALLOW_THREADS
7627 if (!inheritable)
7628 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7629 else
7630 res = dup2(fd, fd2);
7631 Py_END_ALLOW_THREADS
7632 if (res < 0)
7633 return posix_error();
7634
7635#else
7636
7637#ifdef HAVE_DUP3
7638 if (!inheritable && dup3_works != 0) {
7639 Py_BEGIN_ALLOW_THREADS
7640 res = dup3(fd, fd2, O_CLOEXEC);
7641 Py_END_ALLOW_THREADS
7642 if (res < 0) {
7643 if (dup3_works == -1)
7644 dup3_works = (errno != ENOSYS);
7645 if (dup3_works)
7646 return posix_error();
7647 }
7648 }
7649
7650 if (inheritable || dup3_works == 0)
7651 {
7652#endif
7653 Py_BEGIN_ALLOW_THREADS
7654 res = dup2(fd, fd2);
7655 Py_END_ALLOW_THREADS
7656 if (res < 0)
7657 return posix_error();
7658
7659 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7660 close(fd2);
7661 return NULL;
7662 }
7663#ifdef HAVE_DUP3
7664 }
7665#endif
7666
7667#endif
7668
Larry Hastings2f936352014-08-05 14:04:04 +10007669 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007670}
7671
Larry Hastings2f936352014-08-05 14:04:04 +10007672
Ross Lagerwall7807c352011-03-17 20:20:30 +02007673#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007674/*[clinic input]
7675os.lockf
7676
7677 fd: int
7678 An open file descriptor.
7679 command: int
7680 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7681 length: Py_off_t
7682 The number of bytes to lock, starting at the current position.
7683 /
7684
7685Apply, test or remove a POSIX lock on an open file descriptor.
7686
7687[clinic start generated code]*/
7688
Larry Hastings2f936352014-08-05 14:04:04 +10007689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007690os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7691/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007692{
7693 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007694
7695 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007696 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007697 Py_END_ALLOW_THREADS
7698
7699 if (res < 0)
7700 return posix_error();
7701
7702 Py_RETURN_NONE;
7703}
Larry Hastings2f936352014-08-05 14:04:04 +10007704#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007705
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007706
Larry Hastings2f936352014-08-05 14:04:04 +10007707/*[clinic input]
7708os.lseek -> Py_off_t
7709
7710 fd: int
7711 position: Py_off_t
7712 how: int
7713 /
7714
7715Set the position of a file descriptor. Return the new position.
7716
7717Return the new cursor position in number of bytes
7718relative to the beginning of the file.
7719[clinic start generated code]*/
7720
Larry Hastings2f936352014-08-05 14:04:04 +10007721static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007722os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7723/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007724{
7725 Py_off_t result;
7726
Guido van Rossum687dd131993-05-17 08:34:16 +00007727#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007728 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7729 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007730 case 0: how = SEEK_SET; break;
7731 case 1: how = SEEK_CUR; break;
7732 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007734#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007735
Victor Stinner8c62be82010-05-06 00:08:46 +00007736 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007737 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007738
Victor Stinner8c62be82010-05-06 00:08:46 +00007739 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007740 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007741#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007742 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007743#else
Larry Hastings2f936352014-08-05 14:04:04 +10007744 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007745#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007746 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007747 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007748 if (result < 0)
7749 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007750
Larry Hastings2f936352014-08-05 14:04:04 +10007751 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007752}
7753
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007754
Larry Hastings2f936352014-08-05 14:04:04 +10007755/*[clinic input]
7756os.read
7757 fd: int
7758 length: Py_ssize_t
7759 /
7760
7761Read from a file descriptor. Returns a bytes object.
7762[clinic start generated code]*/
7763
Larry Hastings2f936352014-08-05 14:04:04 +10007764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007765os_read_impl(PyObject *module, int fd, Py_ssize_t length)
7766/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007767{
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 Py_ssize_t n;
7769 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10007770
7771 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 errno = EINVAL;
7773 return posix_error();
7774 }
Larry Hastings2f936352014-08-05 14:04:04 +10007775
7776#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01007777 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10007778 if (length > INT_MAX)
7779 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10007780#endif
7781
7782 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 if (buffer == NULL)
7784 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007785
Victor Stinner66aab0c2015-03-19 22:53:20 +01007786 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
7787 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01007789 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 }
Larry Hastings2f936352014-08-05 14:04:04 +10007791
7792 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10007794
Victor Stinner8c62be82010-05-06 00:08:46 +00007795 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00007796}
7797
Ross Lagerwall7807c352011-03-17 20:20:30 +02007798#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
7799 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007800static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007801iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
7802{
7803 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007804 Py_ssize_t blen, total = 0;
7805
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007806 *iov = PyMem_New(struct iovec, cnt);
7807 if (*iov == NULL) {
7808 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007809 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007810 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007811
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007812 *buf = PyMem_New(Py_buffer, cnt);
7813 if (*buf == NULL) {
7814 PyMem_Del(*iov);
7815 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01007816 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007817 }
7818
7819 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007820 PyObject *item = PySequence_GetItem(seq, i);
7821 if (item == NULL)
7822 goto fail;
7823 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
7824 Py_DECREF(item);
7825 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007826 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007827 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007828 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007829 blen = (*buf)[i].len;
7830 (*iov)[i].iov_len = blen;
7831 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007832 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00007833 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02007834
7835fail:
7836 PyMem_Del(*iov);
7837 for (j = 0; j < i; j++) {
7838 PyBuffer_Release(&(*buf)[j]);
7839 }
7840 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01007841 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007842}
7843
7844static void
7845iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
7846{
7847 int i;
7848 PyMem_Del(iov);
7849 for (i = 0; i < cnt; i++) {
7850 PyBuffer_Release(&buf[i]);
7851 }
7852 PyMem_Del(buf);
7853}
7854#endif
7855
Larry Hastings2f936352014-08-05 14:04:04 +10007856
Ross Lagerwall7807c352011-03-17 20:20:30 +02007857#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10007858/*[clinic input]
7859os.readv -> Py_ssize_t
7860
7861 fd: int
7862 buffers: object
7863 /
7864
7865Read from a file descriptor fd into an iterable of buffers.
7866
7867The buffers should be mutable buffers accepting bytes.
7868readv will transfer data into each buffer until it is full
7869and then move on to the next buffer in the sequence to hold
7870the rest of the data.
7871
7872readv returns the total number of bytes read,
7873which may be less than the total capacity of all the buffers.
7874[clinic start generated code]*/
7875
Larry Hastings2f936352014-08-05 14:04:04 +10007876static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007877os_readv_impl(PyObject *module, int fd, PyObject *buffers)
7878/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007879{
7880 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007881 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007882 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007883 struct iovec *iov;
7884 Py_buffer *buf;
7885
Larry Hastings2f936352014-08-05 14:04:04 +10007886 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007887 PyErr_SetString(PyExc_TypeError,
7888 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10007889 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007890 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02007891
Larry Hastings2f936352014-08-05 14:04:04 +10007892 cnt = PySequence_Size(buffers);
7893
7894 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
7895 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007896
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007897 do {
7898 Py_BEGIN_ALLOW_THREADS
7899 n = readv(fd, iov, cnt);
7900 Py_END_ALLOW_THREADS
7901 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007902
7903 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10007904 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007905 if (!async_err)
7906 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007907 return -1;
7908 }
Victor Stinner57ddf782014-01-08 15:21:28 +01007909
Larry Hastings2f936352014-08-05 14:04:04 +10007910 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007911}
Larry Hastings2f936352014-08-05 14:04:04 +10007912#endif /* HAVE_READV */
7913
Ross Lagerwall7807c352011-03-17 20:20:30 +02007914
7915#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10007916/*[clinic input]
7917# TODO length should be size_t! but Python doesn't support parsing size_t yet.
7918os.pread
7919
7920 fd: int
7921 length: int
7922 offset: Py_off_t
7923 /
7924
7925Read a number of bytes from a file descriptor starting at a particular offset.
7926
7927Read length bytes from file descriptor fd, starting at offset bytes from
7928the beginning of the file. The file offset remains unchanged.
7929[clinic start generated code]*/
7930
Larry Hastings2f936352014-08-05 14:04:04 +10007931static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007932os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
7933/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007934{
Ross Lagerwall7807c352011-03-17 20:20:30 +02007935 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007936 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007937 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938
Larry Hastings2f936352014-08-05 14:04:04 +10007939 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940 errno = EINVAL;
7941 return posix_error();
7942 }
Larry Hastings2f936352014-08-05 14:04:04 +10007943 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007944 if (buffer == NULL)
7945 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007946
7947 do {
7948 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007949 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007950 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04007951 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007952 Py_END_ALLOW_THREADS
7953 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7954
Ross Lagerwall7807c352011-03-17 20:20:30 +02007955 if (n < 0) {
7956 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007957 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007958 }
Larry Hastings2f936352014-08-05 14:04:04 +10007959 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02007960 _PyBytes_Resize(&buffer, n);
7961 return buffer;
7962}
Larry Hastings2f936352014-08-05 14:04:04 +10007963#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964
Larry Hastings2f936352014-08-05 14:04:04 +10007965
7966/*[clinic input]
7967os.write -> Py_ssize_t
7968
7969 fd: int
7970 data: Py_buffer
7971 /
7972
7973Write a bytes object to a file descriptor.
7974[clinic start generated code]*/
7975
Larry Hastings2f936352014-08-05 14:04:04 +10007976static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007977os_write_impl(PyObject *module, int fd, Py_buffer *data)
7978/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007979{
Victor Stinner66aab0c2015-03-19 22:53:20 +01007980 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007981}
7982
7983#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007984PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00007985"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00007986sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007987 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00007988Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007989
Larry Hastings2f936352014-08-05 14:04:04 +10007990/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007991static PyObject *
7992posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
7993{
7994 int in, out;
7995 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007996 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00007997 off_t offset;
7998
7999#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8000#ifndef __APPLE__
8001 Py_ssize_t len;
8002#endif
8003 PyObject *headers = NULL, *trailers = NULL;
8004 Py_buffer *hbuf, *tbuf;
8005 off_t sbytes;
8006 struct sf_hdtr sf;
8007 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008008 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008009 static char *keywords[] = {"out", "in",
8010 "offset", "count",
8011 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008012
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008013 sf.headers = NULL;
8014 sf.trailers = NULL;
8015
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008016#ifdef __APPLE__
8017 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008018 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008019#else
8020 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008021 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008022#endif
8023 &headers, &trailers, &flags))
8024 return NULL;
8025 if (headers != NULL) {
8026 if (!PySequence_Check(headers)) {
8027 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008028 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008029 return NULL;
8030 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008031 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008033 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008034 (i = iov_setup(&(sf.headers), &hbuf,
8035 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008036 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008037#ifdef __APPLE__
8038 sbytes += i;
8039#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008040 }
8041 }
8042 if (trailers != NULL) {
8043 if (!PySequence_Check(trailers)) {
8044 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008045 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008046 return NULL;
8047 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008048 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008049 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008050 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008051 (i = iov_setup(&(sf.trailers), &tbuf,
8052 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008054#ifdef __APPLE__
8055 sbytes += i;
8056#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 }
8058 }
8059
Steve Dower8fc89802015-04-12 00:26:27 -04008060 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008061 do {
8062 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008064 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008066 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008067#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008068 Py_END_ALLOW_THREADS
8069 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008070 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071
8072 if (sf.headers != NULL)
8073 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8074 if (sf.trailers != NULL)
8075 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8076
8077 if (ret < 0) {
8078 if ((errno == EAGAIN) || (errno == EBUSY)) {
8079 if (sbytes != 0) {
8080 // some data has been sent
8081 goto done;
8082 }
8083 else {
8084 // no data has been sent; upper application is supposed
8085 // to retry on EAGAIN or EBUSY
8086 return posix_error();
8087 }
8088 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008089 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 }
8091 goto done;
8092
8093done:
8094 #if !defined(HAVE_LARGEFILE_SUPPORT)
8095 return Py_BuildValue("l", sbytes);
8096 #else
8097 return Py_BuildValue("L", sbytes);
8098 #endif
8099
8100#else
8101 Py_ssize_t count;
8102 PyObject *offobj;
8103 static char *keywords[] = {"out", "in",
8104 "offset", "count", NULL};
8105 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8106 keywords, &out, &in, &offobj, &count))
8107 return NULL;
Benjamin Peterson840ef8f2016-09-07 14:45:10 -07008108#ifdef __linux__
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008109 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008110 do {
8111 Py_BEGIN_ALLOW_THREADS
8112 ret = sendfile(out, in, NULL, count);
8113 Py_END_ALLOW_THREADS
8114 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008115 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008116 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008117 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008118 }
8119#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008120 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008121 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008122
8123 do {
8124 Py_BEGIN_ALLOW_THREADS
8125 ret = sendfile(out, in, &offset, count);
8126 Py_END_ALLOW_THREADS
8127 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008128 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008129 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008130 return Py_BuildValue("n", ret);
8131#endif
8132}
Larry Hastings2f936352014-08-05 14:04:04 +10008133#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008134
Larry Hastings2f936352014-08-05 14:04:04 +10008135
8136/*[clinic input]
8137os.fstat
8138
8139 fd : int
8140
8141Perform a stat system call on the given file descriptor.
8142
8143Like stat(), but for an open file descriptor.
8144Equivalent to os.stat(fd).
8145[clinic start generated code]*/
8146
Larry Hastings2f936352014-08-05 14:04:04 +10008147static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008148os_fstat_impl(PyObject *module, int fd)
8149/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008150{
Victor Stinner8c62be82010-05-06 00:08:46 +00008151 STRUCT_STAT st;
8152 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008153 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008154
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008155 do {
8156 Py_BEGIN_ALLOW_THREADS
8157 res = FSTAT(fd, &st);
8158 Py_END_ALLOW_THREADS
8159 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008160 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008161#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008162 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008163#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008164 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008165#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008166 }
Tim Peters5aa91602002-01-30 05:46:57 +00008167
Victor Stinner4195b5c2012-02-08 23:03:19 +01008168 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008169}
8170
Larry Hastings2f936352014-08-05 14:04:04 +10008171
8172/*[clinic input]
8173os.isatty -> bool
8174 fd: int
8175 /
8176
8177Return True if the fd is connected to a terminal.
8178
8179Return True if the file descriptor is an open file descriptor
8180connected to the slave end of a terminal.
8181[clinic start generated code]*/
8182
Larry Hastings2f936352014-08-05 14:04:04 +10008183static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008184os_isatty_impl(PyObject *module, int fd)
8185/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008186{
Steve Dower8fc89802015-04-12 00:26:27 -04008187 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -04008188 _Py_BEGIN_SUPPRESS_IPH
8189 return_value = isatty(fd);
8190 _Py_END_SUPPRESS_IPH
8191 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008192}
8193
8194
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008195#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008196/*[clinic input]
8197os.pipe
8198
8199Create a pipe.
8200
8201Returns a tuple of two file descriptors:
8202 (read_fd, write_fd)
8203[clinic start generated code]*/
8204
Larry Hastings2f936352014-08-05 14:04:04 +10008205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008206os_pipe_impl(PyObject *module)
8207/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008208{
Victor Stinner8c62be82010-05-06 00:08:46 +00008209 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008210#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008211 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008212 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008213 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008214#else
8215 int res;
8216#endif
8217
8218#ifdef MS_WINDOWS
8219 attr.nLength = sizeof(attr);
8220 attr.lpSecurityDescriptor = NULL;
8221 attr.bInheritHandle = FALSE;
8222
8223 Py_BEGIN_ALLOW_THREADS
8224 ok = CreatePipe(&read, &write, &attr, 0);
8225 if (ok) {
Benjamin Petersonca470632016-09-06 13:47:26 -07008226 fds[0] = _open_osfhandle((intptr_t)read, _O_RDONLY);
8227 fds[1] = _open_osfhandle((intptr_t)write, _O_WRONLY);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008228 if (fds[0] == -1 || fds[1] == -1) {
8229 CloseHandle(read);
8230 CloseHandle(write);
8231 ok = 0;
8232 }
8233 }
8234 Py_END_ALLOW_THREADS
8235
Victor Stinner8c62be82010-05-06 00:08:46 +00008236 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008237 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008238#else
8239
8240#ifdef HAVE_PIPE2
8241 Py_BEGIN_ALLOW_THREADS
8242 res = pipe2(fds, O_CLOEXEC);
8243 Py_END_ALLOW_THREADS
8244
8245 if (res != 0 && errno == ENOSYS)
8246 {
8247#endif
8248 Py_BEGIN_ALLOW_THREADS
8249 res = pipe(fds);
8250 Py_END_ALLOW_THREADS
8251
8252 if (res == 0) {
8253 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8254 close(fds[0]);
8255 close(fds[1]);
8256 return NULL;
8257 }
8258 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8259 close(fds[0]);
8260 close(fds[1]);
8261 return NULL;
8262 }
8263 }
8264#ifdef HAVE_PIPE2
8265 }
8266#endif
8267
8268 if (res != 0)
8269 return PyErr_SetFromErrno(PyExc_OSError);
8270#endif /* !MS_WINDOWS */
8271 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008272}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008273#endif /* HAVE_PIPE */
8274
Larry Hastings2f936352014-08-05 14:04:04 +10008275
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008276#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008277/*[clinic input]
8278os.pipe2
8279
8280 flags: int
8281 /
8282
8283Create a pipe with flags set atomically.
8284
8285Returns a tuple of two file descriptors:
8286 (read_fd, write_fd)
8287
8288flags can be constructed by ORing together one or more of these values:
8289O_NONBLOCK, O_CLOEXEC.
8290[clinic start generated code]*/
8291
Larry Hastings2f936352014-08-05 14:04:04 +10008292static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008293os_pipe2_impl(PyObject *module, int flags)
8294/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008295{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008296 int fds[2];
8297 int res;
8298
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008299 res = pipe2(fds, flags);
8300 if (res != 0)
8301 return posix_error();
8302 return Py_BuildValue("(ii)", fds[0], fds[1]);
8303}
8304#endif /* HAVE_PIPE2 */
8305
Larry Hastings2f936352014-08-05 14:04:04 +10008306
Ross Lagerwall7807c352011-03-17 20:20:30 +02008307#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008308/*[clinic input]
8309os.writev -> Py_ssize_t
8310 fd: int
8311 buffers: object
8312 /
8313
8314Iterate over buffers, and write the contents of each to a file descriptor.
8315
8316Returns the total number of bytes written.
8317buffers must be a sequence of bytes-like objects.
8318[clinic start generated code]*/
8319
Larry Hastings2f936352014-08-05 14:04:04 +10008320static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008321os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8322/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008323{
8324 int cnt;
8325 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008326 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008327 struct iovec *iov;
8328 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008329
8330 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008331 PyErr_SetString(PyExc_TypeError,
8332 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008333 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008334 }
Larry Hastings2f936352014-08-05 14:04:04 +10008335 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008336
Larry Hastings2f936352014-08-05 14:04:04 +10008337 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8338 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008339 }
8340
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008341 do {
8342 Py_BEGIN_ALLOW_THREADS
8343 result = writev(fd, iov, cnt);
8344 Py_END_ALLOW_THREADS
8345 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008346
8347 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008348 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008349 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008350
Georg Brandl306336b2012-06-24 12:55:33 +02008351 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008352}
Larry Hastings2f936352014-08-05 14:04:04 +10008353#endif /* HAVE_WRITEV */
8354
8355
8356#ifdef HAVE_PWRITE
8357/*[clinic input]
8358os.pwrite -> Py_ssize_t
8359
8360 fd: int
8361 buffer: Py_buffer
8362 offset: Py_off_t
8363 /
8364
8365Write bytes to a file descriptor starting at a particular offset.
8366
8367Write buffer to fd, starting at offset bytes from the beginning of
8368the file. Returns the number of bytes writte. Does not change the
8369current file offset.
8370[clinic start generated code]*/
8371
Larry Hastings2f936352014-08-05 14:04:04 +10008372static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008373os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8374/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008375{
8376 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008377 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008378
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008379 do {
8380 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008381 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008382 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008383 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008384 Py_END_ALLOW_THREADS
8385 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008386
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008387 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008388 posix_error();
8389 return size;
8390}
8391#endif /* HAVE_PWRITE */
8392
8393
8394#ifdef HAVE_MKFIFO
8395/*[clinic input]
8396os.mkfifo
8397
8398 path: path_t
8399 mode: int=0o666
8400 *
8401 dir_fd: dir_fd(requires='mkfifoat')=None
8402
8403Create a "fifo" (a POSIX named pipe).
8404
8405If dir_fd is not None, it should be a file descriptor open to a directory,
8406 and path should be relative; path will then be relative to that directory.
8407dir_fd may not be implemented on your platform.
8408 If it is unavailable, using it will raise a NotImplementedError.
8409[clinic start generated code]*/
8410
Larry Hastings2f936352014-08-05 14:04:04 +10008411static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008412os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8413/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008414{
8415 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008416 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008417
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008418 do {
8419 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008420#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008421 if (dir_fd != DEFAULT_DIR_FD)
8422 result = mkfifoat(dir_fd, path->narrow, mode);
8423 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008424#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008425 result = mkfifo(path->narrow, mode);
8426 Py_END_ALLOW_THREADS
8427 } while (result != 0 && errno == EINTR &&
8428 !(async_err = PyErr_CheckSignals()));
8429 if (result != 0)
8430 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008431
8432 Py_RETURN_NONE;
8433}
8434#endif /* HAVE_MKFIFO */
8435
8436
8437#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8438/*[clinic input]
8439os.mknod
8440
8441 path: path_t
8442 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008443 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008444 *
8445 dir_fd: dir_fd(requires='mknodat')=None
8446
8447Create a node in the file system.
8448
8449Create a node in the file system (file, device special file or named pipe)
8450at path. mode specifies both the permissions to use and the
8451type of node to be created, being combined (bitwise OR) with one of
8452S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8453device defines the newly created device special file (probably using
8454os.makedev()). Otherwise device is ignored.
8455
8456If dir_fd is not None, it should be a file descriptor open to a directory,
8457 and path should be relative; path will then be relative to that directory.
8458dir_fd may not be implemented on your platform.
8459 If it is unavailable, using it will raise a NotImplementedError.
8460[clinic start generated code]*/
8461
Larry Hastings2f936352014-08-05 14:04:04 +10008462static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008463os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008464 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008465/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008466{
8467 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008468 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008469
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008470 do {
8471 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008472#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008473 if (dir_fd != DEFAULT_DIR_FD)
8474 result = mknodat(dir_fd, path->narrow, mode, device);
8475 else
Larry Hastings2f936352014-08-05 14:04:04 +10008476#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008477 result = mknod(path->narrow, mode, device);
8478 Py_END_ALLOW_THREADS
8479 } while (result != 0 && errno == EINTR &&
8480 !(async_err = PyErr_CheckSignals()));
8481 if (result != 0)
8482 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008483
8484 Py_RETURN_NONE;
8485}
8486#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8487
8488
8489#ifdef HAVE_DEVICE_MACROS
8490/*[clinic input]
8491os.major -> unsigned_int
8492
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008493 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008494 /
8495
8496Extracts a device major number from a raw device number.
8497[clinic start generated code]*/
8498
Larry Hastings2f936352014-08-05 14:04:04 +10008499static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008500os_major_impl(PyObject *module, dev_t device)
8501/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008502{
8503 return major(device);
8504}
8505
8506
8507/*[clinic input]
8508os.minor -> unsigned_int
8509
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008510 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008511 /
8512
8513Extracts a device minor number from a raw device number.
8514[clinic start generated code]*/
8515
Larry Hastings2f936352014-08-05 14:04:04 +10008516static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008517os_minor_impl(PyObject *module, dev_t device)
8518/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008519{
8520 return minor(device);
8521}
8522
8523
8524/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008525os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008526
8527 major: int
8528 minor: int
8529 /
8530
8531Composes a raw device number from the major and minor device numbers.
8532[clinic start generated code]*/
8533
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008534static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008535os_makedev_impl(PyObject *module, int major, int minor)
8536/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008537{
8538 return makedev(major, minor);
8539}
8540#endif /* HAVE_DEVICE_MACROS */
8541
8542
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008543#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008544/*[clinic input]
8545os.ftruncate
8546
8547 fd: int
8548 length: Py_off_t
8549 /
8550
8551Truncate a file, specified by file descriptor, to a specific length.
8552[clinic start generated code]*/
8553
Larry Hastings2f936352014-08-05 14:04:04 +10008554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008555os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8556/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008557{
8558 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008559 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008560
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008561 do {
8562 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008563 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008564#ifdef MS_WINDOWS
8565 result = _chsize_s(fd, length);
8566#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008567 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008568#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008569 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008570 Py_END_ALLOW_THREADS
8571 } while (result != 0 && errno == EINTR &&
8572 !(async_err = PyErr_CheckSignals()));
8573 if (result != 0)
8574 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008575 Py_RETURN_NONE;
8576}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008577#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008578
8579
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008580#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008581/*[clinic input]
8582os.truncate
8583 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8584 length: Py_off_t
8585
8586Truncate a file, specified by path, to a specific length.
8587
8588On some platforms, path may also be specified as an open file descriptor.
8589 If this functionality is unavailable, using it raises an exception.
8590[clinic start generated code]*/
8591
Larry Hastings2f936352014-08-05 14:04:04 +10008592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008593os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8594/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008595{
8596 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008597#ifdef MS_WINDOWS
8598 int fd;
8599#endif
8600
8601 if (path->fd != -1)
8602 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008603
8604 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008605 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008606#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -07008607 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008608 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008609 result = -1;
8610 else {
8611 result = _chsize_s(fd, length);
8612 close(fd);
8613 if (result < 0)
8614 errno = result;
8615 }
8616#else
8617 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008618#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008619 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008620 Py_END_ALLOW_THREADS
8621 if (result < 0)
8622 return path_error(path);
8623
8624 Py_RETURN_NONE;
8625}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008626#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008627
Ross Lagerwall7807c352011-03-17 20:20:30 +02008628
Victor Stinnerd6b17692014-09-30 12:20:05 +02008629/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8630 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8631 defined, which is the case in Python on AIX. AIX bug report:
8632 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8633#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8634# define POSIX_FADVISE_AIX_BUG
8635#endif
8636
Victor Stinnerec39e262014-09-30 12:35:58 +02008637
Victor Stinnerd6b17692014-09-30 12:20:05 +02008638#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008639/*[clinic input]
8640os.posix_fallocate
8641
8642 fd: int
8643 offset: Py_off_t
8644 length: Py_off_t
8645 /
8646
8647Ensure a file has allocated at least a particular number of bytes on disk.
8648
8649Ensure that the file specified by fd encompasses a range of bytes
8650starting at offset bytes from the beginning and continuing for length bytes.
8651[clinic start generated code]*/
8652
Larry Hastings2f936352014-08-05 14:04:04 +10008653static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008654os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008655 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008656/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008657{
8658 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008659 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008660
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008661 do {
8662 Py_BEGIN_ALLOW_THREADS
8663 result = posix_fallocate(fd, offset, length);
8664 Py_END_ALLOW_THREADS
8665 } while (result != 0 && errno == EINTR &&
8666 !(async_err = PyErr_CheckSignals()));
8667 if (result != 0)
8668 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008669 Py_RETURN_NONE;
8670}
Victor Stinnerec39e262014-09-30 12:35:58 +02008671#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008672
Ross Lagerwall7807c352011-03-17 20:20:30 +02008673
Victor Stinnerd6b17692014-09-30 12:20:05 +02008674#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008675/*[clinic input]
8676os.posix_fadvise
8677
8678 fd: int
8679 offset: Py_off_t
8680 length: Py_off_t
8681 advice: int
8682 /
8683
8684Announce an intention to access data in a specific pattern.
8685
8686Announce an intention to access data in a specific pattern, thus allowing
8687the kernel to make optimizations.
8688The advice applies to the region of the file specified by fd starting at
8689offset and continuing for length bytes.
8690advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8691POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8692POSIX_FADV_DONTNEED.
8693[clinic start generated code]*/
8694
Larry Hastings2f936352014-08-05 14:04:04 +10008695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008696os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008697 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008698/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008699{
8700 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008701 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008702
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008703 do {
8704 Py_BEGIN_ALLOW_THREADS
8705 result = posix_fadvise(fd, offset, length, advice);
8706 Py_END_ALLOW_THREADS
8707 } while (result != 0 && errno == EINTR &&
8708 !(async_err = PyErr_CheckSignals()));
8709 if (result != 0)
8710 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008711 Py_RETURN_NONE;
8712}
Victor Stinnerec39e262014-09-30 12:35:58 +02008713#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008714
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008715#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008716
Fred Drake762e2061999-08-26 17:23:54 +00008717/* Save putenv() parameters as values here, so we can collect them when they
8718 * get re-set with another call for the same key. */
8719static PyObject *posix_putenv_garbage;
8720
Larry Hastings2f936352014-08-05 14:04:04 +10008721static void
8722posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008723{
Larry Hastings2f936352014-08-05 14:04:04 +10008724 /* Install the first arg and newstr in posix_putenv_garbage;
8725 * this will cause previous value to be collected. This has to
8726 * happen after the real putenv() call because the old value
8727 * was still accessible until then. */
8728 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8729 /* really not much we can do; just leak */
8730 PyErr_Clear();
8731 else
8732 Py_DECREF(value);
8733}
8734
8735
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008736#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008737/*[clinic input]
8738os.putenv
8739
8740 name: unicode
8741 value: unicode
8742 /
8743
8744Change or add an environment variable.
8745[clinic start generated code]*/
8746
Larry Hastings2f936352014-08-05 14:04:04 +10008747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008748os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8749/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008750{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008751 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10008752
8753 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8754 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008755 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10008756 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00008757 }
Larry Hastings2f936352014-08-05 14:04:04 +10008758 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01008759 PyErr_Format(PyExc_ValueError,
8760 "the environment variable is longer than %u characters",
8761 _MAX_ENV);
8762 goto error;
8763 }
8764
Larry Hastings2f936352014-08-05 14:04:04 +10008765 env = PyUnicode_AsUnicode(unicode);
8766 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02008767 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10008768 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008769 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00008770 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00008771 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008772
Larry Hastings2f936352014-08-05 14:04:04 +10008773 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008774 Py_RETURN_NONE;
8775
8776error:
Larry Hastings2f936352014-08-05 14:04:04 +10008777 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00008778 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008779}
Larry Hastings2f936352014-08-05 14:04:04 +10008780#else /* MS_WINDOWS */
8781/*[clinic input]
8782os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00008783
Larry Hastings2f936352014-08-05 14:04:04 +10008784 name: FSConverter
8785 value: FSConverter
8786 /
8787
8788Change or add an environment variable.
8789[clinic start generated code]*/
8790
Larry Hastings2f936352014-08-05 14:04:04 +10008791static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008792os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
8793/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008794{
8795 PyObject *bytes = NULL;
8796 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03008797 const char *name_string = PyBytes_AsString(name);
8798 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10008799
8800 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
8801 if (bytes == NULL) {
8802 PyErr_NoMemory();
8803 return NULL;
8804 }
8805
8806 env = PyBytes_AS_STRING(bytes);
8807 if (putenv(env)) {
8808 Py_DECREF(bytes);
8809 return posix_error();
8810 }
8811
8812 posix_putenv_garbage_setitem(name, bytes);
8813 Py_RETURN_NONE;
8814}
8815#endif /* MS_WINDOWS */
8816#endif /* HAVE_PUTENV */
8817
8818
8819#ifdef HAVE_UNSETENV
8820/*[clinic input]
8821os.unsetenv
8822 name: FSConverter
8823 /
8824
8825Delete an environment variable.
8826[clinic start generated code]*/
8827
Larry Hastings2f936352014-08-05 14:04:04 +10008828static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008829os_unsetenv_impl(PyObject *module, PyObject *name)
8830/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008831{
Victor Stinner984890f2011-11-24 13:53:38 +01008832#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01008833 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01008834#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00008835
Victor Stinner984890f2011-11-24 13:53:38 +01008836#ifdef HAVE_BROKEN_UNSETENV
8837 unsetenv(PyBytes_AS_STRING(name));
8838#else
Victor Stinner65170952011-11-22 22:16:17 +01008839 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10008840 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01008841 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01008842#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00008843
Victor Stinner8c62be82010-05-06 00:08:46 +00008844 /* Remove the key from posix_putenv_garbage;
8845 * this will cause it to be collected. This has to
8846 * happen after the real unsetenv() call because the
8847 * old value was still accessible until then.
8848 */
Victor Stinner65170952011-11-22 22:16:17 +01008849 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008850 /* really not much we can do; just leak */
8851 PyErr_Clear();
8852 }
Victor Stinner84ae1182010-05-06 22:05:07 +00008853 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00008854}
Larry Hastings2f936352014-08-05 14:04:04 +10008855#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00008856
Larry Hastings2f936352014-08-05 14:04:04 +10008857
8858/*[clinic input]
8859os.strerror
8860
8861 code: int
8862 /
8863
8864Translate an error code to a message string.
8865[clinic start generated code]*/
8866
Larry Hastings2f936352014-08-05 14:04:04 +10008867static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008868os_strerror_impl(PyObject *module, int code)
8869/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008870{
8871 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00008872 if (message == NULL) {
8873 PyErr_SetString(PyExc_ValueError,
8874 "strerror() argument out of range");
8875 return NULL;
8876 }
Victor Stinner1b579672011-12-17 05:47:23 +01008877 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00008878}
Guido van Rossumb6a47161997-09-15 22:54:34 +00008879
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008880
Guido van Rossumc9641791998-08-04 15:26:23 +00008881#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00008882#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10008883/*[clinic input]
8884os.WCOREDUMP -> bool
8885
8886 status: int
8887 /
8888
8889Return True if the process returning status was dumped to a core file.
8890[clinic start generated code]*/
8891
Larry Hastings2f936352014-08-05 14:04:04 +10008892static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008893os_WCOREDUMP_impl(PyObject *module, int status)
8894/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008895{
8896 WAIT_TYPE wait_status;
8897 WAIT_STATUS_INT(wait_status) = status;
8898 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008899}
8900#endif /* WCOREDUMP */
8901
Larry Hastings2f936352014-08-05 14:04:04 +10008902
Fred Drake106c1a02002-04-23 15:58:02 +00008903#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10008904/*[clinic input]
8905os.WIFCONTINUED -> bool
8906
8907 status: int
8908
8909Return True if a particular process was continued from a job control stop.
8910
8911Return True if the process returning status was continued from a
8912job control stop.
8913[clinic start generated code]*/
8914
Larry Hastings2f936352014-08-05 14:04:04 +10008915static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008916os_WIFCONTINUED_impl(PyObject *module, int status)
8917/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008918{
8919 WAIT_TYPE wait_status;
8920 WAIT_STATUS_INT(wait_status) = status;
8921 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00008922}
8923#endif /* WIFCONTINUED */
8924
Larry Hastings2f936352014-08-05 14:04:04 +10008925
Guido van Rossumc9641791998-08-04 15:26:23 +00008926#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10008927/*[clinic input]
8928os.WIFSTOPPED -> bool
8929
8930 status: int
8931
8932Return True if the process returning status was stopped.
8933[clinic start generated code]*/
8934
Larry Hastings2f936352014-08-05 14:04:04 +10008935static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008936os_WIFSTOPPED_impl(PyObject *module, int status)
8937/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008938{
8939 WAIT_TYPE wait_status;
8940 WAIT_STATUS_INT(wait_status) = status;
8941 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008942}
8943#endif /* WIFSTOPPED */
8944
Larry Hastings2f936352014-08-05 14:04:04 +10008945
Guido van Rossumc9641791998-08-04 15:26:23 +00008946#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10008947/*[clinic input]
8948os.WIFSIGNALED -> bool
8949
8950 status: int
8951
8952Return True if the process returning status was terminated by a signal.
8953[clinic start generated code]*/
8954
Larry Hastings2f936352014-08-05 14:04:04 +10008955static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008956os_WIFSIGNALED_impl(PyObject *module, int status)
8957/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008958{
8959 WAIT_TYPE wait_status;
8960 WAIT_STATUS_INT(wait_status) = status;
8961 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008962}
8963#endif /* WIFSIGNALED */
8964
Larry Hastings2f936352014-08-05 14:04:04 +10008965
Guido van Rossumc9641791998-08-04 15:26:23 +00008966#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10008967/*[clinic input]
8968os.WIFEXITED -> bool
8969
8970 status: int
8971
8972Return True if the process returning status exited via the exit() system call.
8973[clinic start generated code]*/
8974
Larry Hastings2f936352014-08-05 14:04:04 +10008975static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008976os_WIFEXITED_impl(PyObject *module, int status)
8977/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008978{
8979 WAIT_TYPE wait_status;
8980 WAIT_STATUS_INT(wait_status) = status;
8981 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00008982}
8983#endif /* WIFEXITED */
8984
Larry Hastings2f936352014-08-05 14:04:04 +10008985
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00008986#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10008987/*[clinic input]
8988os.WEXITSTATUS -> int
8989
8990 status: int
8991
8992Return the process return code from status.
8993[clinic start generated code]*/
8994
Larry Hastings2f936352014-08-05 14:04:04 +10008995static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008996os_WEXITSTATUS_impl(PyObject *module, int status)
8997/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008998{
8999 WAIT_TYPE wait_status;
9000 WAIT_STATUS_INT(wait_status) = status;
9001 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009002}
9003#endif /* WEXITSTATUS */
9004
Larry Hastings2f936352014-08-05 14:04:04 +10009005
Guido van Rossumc9641791998-08-04 15:26:23 +00009006#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009007/*[clinic input]
9008os.WTERMSIG -> int
9009
9010 status: int
9011
9012Return the signal that terminated the process that provided the status value.
9013[clinic start generated code]*/
9014
Larry Hastings2f936352014-08-05 14:04:04 +10009015static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009016os_WTERMSIG_impl(PyObject *module, int status)
9017/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009018{
9019 WAIT_TYPE wait_status;
9020 WAIT_STATUS_INT(wait_status) = status;
9021 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009022}
9023#endif /* WTERMSIG */
9024
Larry Hastings2f936352014-08-05 14:04:04 +10009025
Guido van Rossumc9641791998-08-04 15:26:23 +00009026#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009027/*[clinic input]
9028os.WSTOPSIG -> int
9029
9030 status: int
9031
9032Return the signal that stopped the process that provided the status value.
9033[clinic start generated code]*/
9034
Larry Hastings2f936352014-08-05 14:04:04 +10009035static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009036os_WSTOPSIG_impl(PyObject *module, int status)
9037/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009038{
9039 WAIT_TYPE wait_status;
9040 WAIT_STATUS_INT(wait_status) = status;
9041 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009042}
9043#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009044#endif /* HAVE_SYS_WAIT_H */
9045
9046
Thomas Wouters477c8d52006-05-27 19:21:47 +00009047#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009048#ifdef _SCO_DS
9049/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9050 needed definitions in sys/statvfs.h */
9051#define _SVID3
9052#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009053#include <sys/statvfs.h>
9054
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009055static PyObject*
9056_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9058 if (v == NULL)
9059 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009060
9061#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009062 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9063 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9064 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9065 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9066 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9067 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9068 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9069 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9070 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9071 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009072#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009073 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9074 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9075 PyStructSequence_SET_ITEM(v, 2,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009076 PyLong_FromLongLong((long long) st.f_blocks));
Victor Stinner8c62be82010-05-06 00:08:46 +00009077 PyStructSequence_SET_ITEM(v, 3,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009078 PyLong_FromLongLong((long long) st.f_bfree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009079 PyStructSequence_SET_ITEM(v, 4,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009080 PyLong_FromLongLong((long long) st.f_bavail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009081 PyStructSequence_SET_ITEM(v, 5,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009082 PyLong_FromLongLong((long long) st.f_files));
Victor Stinner8c62be82010-05-06 00:08:46 +00009083 PyStructSequence_SET_ITEM(v, 6,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009084 PyLong_FromLongLong((long long) st.f_ffree));
Victor Stinner8c62be82010-05-06 00:08:46 +00009085 PyStructSequence_SET_ITEM(v, 7,
Benjamin Petersonaf580df2016-09-06 10:46:49 -07009086 PyLong_FromLongLong((long long) st.f_favail));
Victor Stinner8c62be82010-05-06 00:08:46 +00009087 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9088 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009089#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009090 if (PyErr_Occurred()) {
9091 Py_DECREF(v);
9092 return NULL;
9093 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009094
Victor Stinner8c62be82010-05-06 00:08:46 +00009095 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009096}
9097
Larry Hastings2f936352014-08-05 14:04:04 +10009098
9099/*[clinic input]
9100os.fstatvfs
9101 fd: int
9102 /
9103
9104Perform an fstatvfs system call on the given fd.
9105
9106Equivalent to statvfs(fd).
9107[clinic start generated code]*/
9108
Larry Hastings2f936352014-08-05 14:04:04 +10009109static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009110os_fstatvfs_impl(PyObject *module, int fd)
9111/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009112{
9113 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009114 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009116
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009117 do {
9118 Py_BEGIN_ALLOW_THREADS
9119 result = fstatvfs(fd, &st);
9120 Py_END_ALLOW_THREADS
9121 } while (result != 0 && errno == EINTR &&
9122 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009123 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009124 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009127}
Larry Hastings2f936352014-08-05 14:04:04 +10009128#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009129
9130
Thomas Wouters477c8d52006-05-27 19:21:47 +00009131#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009132#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009133/*[clinic input]
9134os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009135
Larry Hastings2f936352014-08-05 14:04:04 +10009136 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9137
9138Perform a statvfs system call on the given path.
9139
9140path may always be specified as a string.
9141On some platforms, path may also be specified as an open file descriptor.
9142 If this functionality is unavailable, using it raises an exception.
9143[clinic start generated code]*/
9144
Larry Hastings2f936352014-08-05 14:04:04 +10009145static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009146os_statvfs_impl(PyObject *module, path_t *path)
9147/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009148{
9149 int result;
9150 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009151
9152 Py_BEGIN_ALLOW_THREADS
9153#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009154 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009155#ifdef __APPLE__
9156 /* handle weak-linking on Mac OS X 10.3 */
9157 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009158 fd_specified("statvfs", path->fd);
9159 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009160 }
9161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009162 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009163 }
9164 else
9165#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009166 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009167 Py_END_ALLOW_THREADS
9168
9169 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009170 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009171 }
9172
Larry Hastings2f936352014-08-05 14:04:04 +10009173 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009174}
Larry Hastings2f936352014-08-05 14:04:04 +10009175#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9176
Guido van Rossum94f6f721999-01-06 18:42:14 +00009177
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009178#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009179/*[clinic input]
9180os._getdiskusage
9181
9182 path: Py_UNICODE
9183
9184Return disk usage statistics about the given path as a (total, free) tuple.
9185[clinic start generated code]*/
9186
Larry Hastings2f936352014-08-05 14:04:04 +10009187static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009188os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9189/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009190{
9191 BOOL retval;
9192 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009193
9194 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009195 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009196 Py_END_ALLOW_THREADS
9197 if (retval == 0)
9198 return PyErr_SetFromWindowsErr(0);
9199
9200 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9201}
Larry Hastings2f936352014-08-05 14:04:04 +10009202#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009203
9204
Fred Drakec9680921999-12-13 16:37:25 +00009205/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9206 * It maps strings representing configuration variable names to
9207 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009208 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009209 * rarely-used constants. There are three separate tables that use
9210 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009211 *
9212 * This code is always included, even if none of the interfaces that
9213 * need it are included. The #if hackery needed to avoid it would be
9214 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009215 */
9216struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009217 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009218 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009219};
9220
Fred Drake12c6e2d1999-12-14 21:25:03 +00009221static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009222conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009223 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009224{
Christian Heimes217cfd12007-12-02 14:31:20 +00009225 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009226 int value = _PyLong_AsInt(arg);
9227 if (value == -1 && PyErr_Occurred())
9228 return 0;
9229 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009230 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009231 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009232 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009233 /* look up the value in the table using a binary search */
9234 size_t lo = 0;
9235 size_t mid;
9236 size_t hi = tablesize;
9237 int cmp;
9238 const char *confname;
9239 if (!PyUnicode_Check(arg)) {
9240 PyErr_SetString(PyExc_TypeError,
9241 "configuration names must be strings or integers");
9242 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009243 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009244 confname = _PyUnicode_AsString(arg);
9245 if (confname == NULL)
9246 return 0;
9247 while (lo < hi) {
9248 mid = (lo + hi) / 2;
9249 cmp = strcmp(confname, table[mid].name);
9250 if (cmp < 0)
9251 hi = mid;
9252 else if (cmp > 0)
9253 lo = mid + 1;
9254 else {
9255 *valuep = table[mid].value;
9256 return 1;
9257 }
9258 }
9259 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9260 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009261 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009262}
9263
9264
9265#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9266static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009267#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009268 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009269#endif
9270#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009271 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009272#endif
Fred Drakec9680921999-12-13 16:37:25 +00009273#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009274 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009275#endif
9276#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009277 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009278#endif
9279#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009280 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009281#endif
9282#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009283 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009284#endif
9285#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009286 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009287#endif
9288#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009289 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009290#endif
9291#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009292 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009293#endif
9294#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009295 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009296#endif
9297#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009298 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009299#endif
9300#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009302#endif
9303#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009304 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009305#endif
9306#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009307 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009308#endif
9309#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009310 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009311#endif
9312#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009313 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009314#endif
9315#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009316 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009317#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009318#ifdef _PC_ACL_ENABLED
9319 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9320#endif
9321#ifdef _PC_MIN_HOLE_SIZE
9322 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9323#endif
9324#ifdef _PC_ALLOC_SIZE_MIN
9325 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9326#endif
9327#ifdef _PC_REC_INCR_XFER_SIZE
9328 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9329#endif
9330#ifdef _PC_REC_MAX_XFER_SIZE
9331 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9332#endif
9333#ifdef _PC_REC_MIN_XFER_SIZE
9334 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9335#endif
9336#ifdef _PC_REC_XFER_ALIGN
9337 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9338#endif
9339#ifdef _PC_SYMLINK_MAX
9340 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9341#endif
9342#ifdef _PC_XATTR_ENABLED
9343 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9344#endif
9345#ifdef _PC_XATTR_EXISTS
9346 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9347#endif
9348#ifdef _PC_TIMESTAMP_RESOLUTION
9349 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9350#endif
Fred Drakec9680921999-12-13 16:37:25 +00009351};
9352
Fred Drakec9680921999-12-13 16:37:25 +00009353static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009354conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009355{
9356 return conv_confname(arg, valuep, posix_constants_pathconf,
9357 sizeof(posix_constants_pathconf)
9358 / sizeof(struct constdef));
9359}
9360#endif
9361
Larry Hastings2f936352014-08-05 14:04:04 +10009362
Fred Drakec9680921999-12-13 16:37:25 +00009363#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009364/*[clinic input]
9365os.fpathconf -> long
9366
9367 fd: int
9368 name: path_confname
9369 /
9370
9371Return the configuration limit name for the file descriptor fd.
9372
9373If there is no limit, return -1.
9374[clinic start generated code]*/
9375
Larry Hastings2f936352014-08-05 14:04:04 +10009376static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009377os_fpathconf_impl(PyObject *module, int fd, int name)
9378/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009379{
9380 long limit;
9381
9382 errno = 0;
9383 limit = fpathconf(fd, name);
9384 if (limit == -1 && errno != 0)
9385 posix_error();
9386
9387 return limit;
9388}
9389#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009390
9391
9392#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009393/*[clinic input]
9394os.pathconf -> long
9395 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9396 name: path_confname
9397
9398Return the configuration limit name for the file or directory path.
9399
9400If there is no limit, return -1.
9401On some platforms, path may also be specified as an open file descriptor.
9402 If this functionality is unavailable, using it raises an exception.
9403[clinic start generated code]*/
9404
Larry Hastings2f936352014-08-05 14:04:04 +10009405static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009406os_pathconf_impl(PyObject *module, path_t *path, int name)
9407/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009408{
Victor Stinner8c62be82010-05-06 00:08:46 +00009409 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009410
Victor Stinner8c62be82010-05-06 00:08:46 +00009411 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009412#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009413 if (path->fd != -1)
9414 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009415 else
9416#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009417 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009418 if (limit == -1 && errno != 0) {
9419 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009420 /* could be a path or name problem */
9421 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009422 else
Larry Hastings2f936352014-08-05 14:04:04 +10009423 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009424 }
Larry Hastings2f936352014-08-05 14:04:04 +10009425
9426 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009427}
Larry Hastings2f936352014-08-05 14:04:04 +10009428#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009429
9430#ifdef HAVE_CONFSTR
9431static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009432#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009433 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009434#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009435#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009436 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009437#endif
9438#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009439 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009440#endif
Fred Draked86ed291999-12-15 15:34:33 +00009441#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009442 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009443#endif
9444#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009445 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009446#endif
9447#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009448 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009449#endif
9450#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009451 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009452#endif
Fred Drakec9680921999-12-13 16:37:25 +00009453#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009454 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009455#endif
9456#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009457 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009458#endif
9459#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009460 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009461#endif
9462#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009463 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009464#endif
9465#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009466 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009467#endif
9468#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009469 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009470#endif
9471#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009472 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009473#endif
9474#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009475 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009476#endif
Fred Draked86ed291999-12-15 15:34:33 +00009477#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009478 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009479#endif
Fred Drakec9680921999-12-13 16:37:25 +00009480#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009482#endif
Fred Draked86ed291999-12-15 15:34:33 +00009483#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009485#endif
9486#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009487 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009488#endif
9489#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009490 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009491#endif
9492#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009493 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009494#endif
Fred Drakec9680921999-12-13 16:37:25 +00009495#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009496 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009497#endif
9498#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009499 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009500#endif
9501#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009503#endif
9504#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009505 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009506#endif
9507#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009509#endif
9510#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009512#endif
9513#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009514 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009515#endif
9516#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009517 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009518#endif
9519#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009520 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009521#endif
9522#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009523 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009524#endif
9525#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009527#endif
9528#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009530#endif
9531#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009533#endif
9534#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009536#endif
9537#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
Fred Draked86ed291999-12-15 15:34:33 +00009543#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009545#endif
9546#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009548#endif
9549#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009551#endif
9552#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009554#endif
9555#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009557#endif
9558#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009560#endif
9561#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009563#endif
9564#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009566#endif
9567#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009569#endif
9570#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009572#endif
9573#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009575#endif
9576#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009578#endif
9579#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009581#endif
Fred Drakec9680921999-12-13 16:37:25 +00009582};
9583
9584static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009585conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009586{
9587 return conv_confname(arg, valuep, posix_constants_confstr,
9588 sizeof(posix_constants_confstr)
9589 / sizeof(struct constdef));
9590}
9591
Larry Hastings2f936352014-08-05 14:04:04 +10009592
9593/*[clinic input]
9594os.confstr
9595
9596 name: confstr_confname
9597 /
9598
9599Return a string-valued system configuration variable.
9600[clinic start generated code]*/
9601
Larry Hastings2f936352014-08-05 14:04:04 +10009602static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009603os_confstr_impl(PyObject *module, int name)
9604/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009605{
9606 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009607 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009608 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009609
Victor Stinnercb043522010-09-10 23:49:04 +00009610 errno = 0;
9611 len = confstr(name, buffer, sizeof(buffer));
9612 if (len == 0) {
9613 if (errno) {
9614 posix_error();
9615 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009616 }
9617 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009618 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009619 }
9620 }
Victor Stinnercb043522010-09-10 23:49:04 +00009621
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009622 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009623 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009624 char *buf = PyMem_Malloc(len);
9625 if (buf == NULL)
9626 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009627 len2 = confstr(name, buf, len);
9628 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009629 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009630 PyMem_Free(buf);
9631 }
9632 else
9633 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009634 return result;
9635}
Larry Hastings2f936352014-08-05 14:04:04 +10009636#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009637
9638
9639#ifdef HAVE_SYSCONF
9640static struct constdef posix_constants_sysconf[] = {
9641#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009642 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009643#endif
9644#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009645 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009646#endif
9647#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009648 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009649#endif
9650#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009651 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009652#endif
9653#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009654 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009655#endif
9656#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009657 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009658#endif
9659#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009660 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009661#endif
9662#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009663 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009664#endif
9665#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009666 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009667#endif
9668#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009669 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009670#endif
Fred Draked86ed291999-12-15 15:34:33 +00009671#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009672 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009673#endif
9674#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009676#endif
Fred Drakec9680921999-12-13 16:37:25 +00009677#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009678 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009679#endif
Fred Drakec9680921999-12-13 16:37:25 +00009680#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009682#endif
9683#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009685#endif
9686#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009687 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009688#endif
9689#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009691#endif
9692#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009694#endif
Fred Draked86ed291999-12-15 15:34:33 +00009695#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009697#endif
Fred Drakec9680921999-12-13 16:37:25 +00009698#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009700#endif
9701#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009703#endif
9704#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009706#endif
9707#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009709#endif
9710#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009712#endif
Fred Draked86ed291999-12-15 15:34:33 +00009713#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009715#endif
Fred Drakec9680921999-12-13 16:37:25 +00009716#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009718#endif
9719#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
9761#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
Fred Draked86ed291999-12-15 15:34:33 +00009785#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +00009787#endif
Fred Drakec9680921999-12-13 16:37:25 +00009788#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
Fred Draked86ed291999-12-15 15:34:33 +00009797#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
Fred Drakec9680921999-12-13 16:37:25 +00009800#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
Fred Draked86ed291999-12-15 15:34:33 +00009803#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +00009805#endif
9806#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +00009808#endif
Fred Drakec9680921999-12-13 16:37:25 +00009809#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
Fred Draked86ed291999-12-15 15:34:33 +00009821#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +00009823#endif
Fred Drakec9680921999-12-13 16:37:25 +00009824#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
Fred Draked86ed291999-12-15 15:34:33 +00009845#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
Fred Drakec9680921999-12-13 16:37:25 +00009848#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
Fred Draked86ed291999-12-15 15:34:33 +00009854#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009856#endif
Fred Drakec9680921999-12-13 16:37:25 +00009857#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009859#endif
9860#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009862#endif
9863#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009865#endif
9866#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009868#endif
9869#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009871#endif
9872#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009874#endif
9875#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +00009877#endif
9878#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +00009880#endif
9881#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +00009883#endif
Fred Draked86ed291999-12-15 15:34:33 +00009884#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +00009886#endif
9887#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
Fred Drakec9680921999-12-13 16:37:25 +00009890#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +00009892#endif
9893#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009894 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009895#endif
9896#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009897 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009898#endif
9899#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00009900 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +00009901#endif
9902#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009903 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009904#endif
9905#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
9959#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
9962#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
9977#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +00009979#endif
9980#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
Fred Draked86ed291999-12-15 15:34:33 +00009995#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +00009997#endif
Fred Drakec9680921999-12-13 16:37:25 +00009998#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
10067#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010069#endif
10070#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
10085#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010087#endif
10088#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133};
10134
10135static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010136conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010137{
10138 return conv_confname(arg, valuep, posix_constants_sysconf,
10139 sizeof(posix_constants_sysconf)
10140 / sizeof(struct constdef));
10141}
10142
Larry Hastings2f936352014-08-05 14:04:04 +100010143
10144/*[clinic input]
10145os.sysconf -> long
10146 name: sysconf_confname
10147 /
10148
10149Return an integer-valued system configuration variable.
10150[clinic start generated code]*/
10151
Larry Hastings2f936352014-08-05 14:04:04 +100010152static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010153os_sysconf_impl(PyObject *module, int name)
10154/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010155{
10156 long value;
10157
10158 errno = 0;
10159 value = sysconf(name);
10160 if (value == -1 && errno != 0)
10161 posix_error();
10162 return value;
10163}
10164#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010165
10166
Fred Drakebec628d1999-12-15 18:31:10 +000010167/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010168 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010169 * the exported dictionaries that are used to publish information about the
10170 * names available on the host platform.
10171 *
10172 * Sorting the table at runtime ensures that the table is properly ordered
10173 * when used, even for platforms we're not able to test on. It also makes
10174 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010175 */
Fred Drakebec628d1999-12-15 18:31:10 +000010176
10177static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010178cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010179{
10180 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010182 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010184
10185 return strcmp(c1->name, c2->name);
10186}
10187
10188static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010189setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010190 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010191{
Fred Drakebec628d1999-12-15 18:31:10 +000010192 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010193 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010194
10195 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10196 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010197 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010199
Barry Warsaw3155db32000-04-13 15:20:40 +000010200 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 PyObject *o = PyLong_FromLong(table[i].value);
10202 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10203 Py_XDECREF(o);
10204 Py_DECREF(d);
10205 return -1;
10206 }
10207 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010208 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010209 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010210}
10211
Fred Drakebec628d1999-12-15 18:31:10 +000010212/* Return -1 on failure, 0 on success. */
10213static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010214setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010215{
10216#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010217 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010218 sizeof(posix_constants_pathconf)
10219 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010220 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010221 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010222#endif
10223#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010224 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010225 sizeof(posix_constants_confstr)
10226 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010227 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010228 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010229#endif
10230#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010231 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010232 sizeof(posix_constants_sysconf)
10233 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010234 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010235 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010236#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010237 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010238}
Fred Draked86ed291999-12-15 15:34:33 +000010239
10240
Larry Hastings2f936352014-08-05 14:04:04 +100010241/*[clinic input]
10242os.abort
10243
10244Abort the interpreter immediately.
10245
10246This function 'dumps core' or otherwise fails in the hardest way possible
10247on the hosting operating system. This function never returns.
10248[clinic start generated code]*/
10249
Larry Hastings2f936352014-08-05 14:04:04 +100010250static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010251os_abort_impl(PyObject *module)
10252/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010253{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010254 abort();
10255 /*NOTREACHED*/
10256 Py_FatalError("abort() called from Python code didn't abort!");
10257 return NULL;
10258}
Fred Drakebec628d1999-12-15 18:31:10 +000010259
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010260#ifdef MS_WINDOWS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010261/* Grab ShellExecute dynamically from shell32 */
10262static int has_ShellExecute = -1;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010263static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10264 LPCWSTR, INT);
10265static int
10266check_ShellExecute()
10267{
10268 HINSTANCE hShell32;
10269
10270 /* only recheck */
10271 if (-1 == has_ShellExecute) {
10272 Py_BEGIN_ALLOW_THREADS
10273 hShell32 = LoadLibraryW(L"SHELL32");
10274 Py_END_ALLOW_THREADS
10275 if (hShell32) {
Steve Dower7d0e0c92015-01-24 08:18:24 -080010276 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10277 "ShellExecuteW");
Steve Dowercc16be82016-09-08 10:35:16 -070010278 has_ShellExecute = Py_ShellExecuteW != NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010279 } else {
10280 has_ShellExecute = 0;
10281 }
10282 }
10283 return has_ShellExecute;
10284}
10285
10286
Steve Dowercc16be82016-09-08 10:35:16 -070010287/*[clinic input]
10288os.startfile
10289 filepath: path_t
10290 operation: Py_UNICODE = NULL
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010291
Steve Dowercc16be82016-09-08 10:35:16 -070010292startfile(filepath [, operation])
10293
10294Start a file with its associated application.
10295
10296When "operation" is not specified or "open", this acts like
10297double-clicking the file in Explorer, or giving the file name as an
10298argument to the DOS "start" command: the file is opened with whatever
10299application (if any) its extension is associated.
10300When another "operation" is given, it specifies what should be done with
10301the file. A typical operation is "print".
10302
10303startfile returns as soon as the associated application is launched.
10304There is no option to wait for the application to close, and no way
10305to retrieve the application's exit status.
10306
10307The filepath is relative to the current directory. If you want to use
10308an absolute path, make sure the first character is not a slash ("/");
10309the underlying Win32 ShellExecute function doesn't work if it is.
10310[clinic start generated code]*/
10311
10312static PyObject *
10313os_startfile_impl(PyObject *module, path_t *filepath, Py_UNICODE *operation)
10314/*[clinic end generated code: output=912ceba79acfa1c9 input=63950bf2986380d0]*/
10315{
10316 HINSTANCE rc;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010317
10318 if(!check_ShellExecute()) {
10319 /* If the OS doesn't have ShellExecute, return a
10320 NotImplementedError. */
10321 return PyErr_Format(PyExc_NotImplementedError,
10322 "startfile not available on this platform");
10323 }
10324
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 Py_BEGIN_ALLOW_THREADS
Steve Dowercc16be82016-09-08 10:35:16 -070010326 rc = Py_ShellExecuteW((HWND)0, operation, filepath->wide,
Steve Dower7d0e0c92015-01-24 08:18:24 -080010327 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 Py_END_ALLOW_THREADS
10329
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 if (rc <= (HINSTANCE)32) {
Steve Dowercc16be82016-09-08 10:35:16 -070010331 win32_error_object("startfile", filepath->object);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010332 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 }
Steve Dowercc16be82016-09-08 10:35:16 -070010334 Py_RETURN_NONE;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010335}
Larry Hastings2f936352014-08-05 14:04:04 +100010336#endif /* MS_WINDOWS */
10337
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010338
Martin v. Löwis438b5342002-12-27 10:16:42 +000010339#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010340/*[clinic input]
10341os.getloadavg
10342
10343Return average recent system load information.
10344
10345Return the number of processes in the system run queue averaged over
10346the last 1, 5, and 15 minutes as a tuple of three floats.
10347Raises OSError if the load average was unobtainable.
10348[clinic start generated code]*/
10349
Larry Hastings2f936352014-08-05 14:04:04 +100010350static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010351os_getloadavg_impl(PyObject *module)
10352/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010353{
10354 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010355 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010356 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10357 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010358 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010359 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010360}
Larry Hastings2f936352014-08-05 14:04:04 +100010361#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010362
Larry Hastings2f936352014-08-05 14:04:04 +100010363
10364/*[clinic input]
10365os.device_encoding
10366 fd: int
10367
10368Return a string describing the encoding of a terminal's file descriptor.
10369
10370The file descriptor must be attached to a terminal.
10371If the device is not a terminal, return None.
10372[clinic start generated code]*/
10373
Larry Hastings2f936352014-08-05 14:04:04 +100010374static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010375os_device_encoding_impl(PyObject *module, int fd)
10376/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010377{
Brett Cannonefb00c02012-02-29 18:31:31 -050010378 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010379}
10380
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010381
Larry Hastings2f936352014-08-05 14:04:04 +100010382#ifdef HAVE_SETRESUID
10383/*[clinic input]
10384os.setresuid
10385
10386 ruid: uid_t
10387 euid: uid_t
10388 suid: uid_t
10389 /
10390
10391Set the current process's real, effective, and saved user ids.
10392[clinic start generated code]*/
10393
Larry Hastings2f936352014-08-05 14:04:04 +100010394static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010395os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10396/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010397{
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 if (setresuid(ruid, euid, suid) < 0)
10399 return posix_error();
10400 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010401}
Larry Hastings2f936352014-08-05 14:04:04 +100010402#endif /* HAVE_SETRESUID */
10403
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010404
10405#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010406/*[clinic input]
10407os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010408
Larry Hastings2f936352014-08-05 14:04:04 +100010409 rgid: gid_t
10410 egid: gid_t
10411 sgid: gid_t
10412 /
10413
10414Set the current process's real, effective, and saved group ids.
10415[clinic start generated code]*/
10416
Larry Hastings2f936352014-08-05 14:04:04 +100010417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010418os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10419/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010420{
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 if (setresgid(rgid, egid, sgid) < 0)
10422 return posix_error();
10423 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010424}
Larry Hastings2f936352014-08-05 14:04:04 +100010425#endif /* HAVE_SETRESGID */
10426
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010427
10428#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010429/*[clinic input]
10430os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010431
Larry Hastings2f936352014-08-05 14:04:04 +100010432Return a tuple of the current process's real, effective, and saved user ids.
10433[clinic start generated code]*/
10434
Larry Hastings2f936352014-08-05 14:04:04 +100010435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010436os_getresuid_impl(PyObject *module)
10437/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010438{
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010440 if (getresuid(&ruid, &euid, &suid) < 0)
10441 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010442 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10443 _PyLong_FromUid(euid),
10444 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010445}
Larry Hastings2f936352014-08-05 14:04:04 +100010446#endif /* HAVE_GETRESUID */
10447
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010448
10449#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010450/*[clinic input]
10451os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010452
Larry Hastings2f936352014-08-05 14:04:04 +100010453Return a tuple of the current process's real, effective, and saved group ids.
10454[clinic start generated code]*/
10455
Larry Hastings2f936352014-08-05 14:04:04 +100010456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010457os_getresgid_impl(PyObject *module)
10458/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010459{
10460 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010461 if (getresgid(&rgid, &egid, &sgid) < 0)
10462 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010463 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10464 _PyLong_FromGid(egid),
10465 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010466}
Larry Hastings2f936352014-08-05 14:04:04 +100010467#endif /* HAVE_GETRESGID */
10468
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010469
Benjamin Peterson9428d532011-09-14 11:45:52 -040010470#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010471/*[clinic input]
10472os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010473
Larry Hastings2f936352014-08-05 14:04:04 +100010474 path: path_t(allow_fd=True)
10475 attribute: path_t
10476 *
10477 follow_symlinks: bool = True
10478
10479Return the value of extended attribute attribute on path.
10480
10481path may be either a string or an open file descriptor.
10482If follow_symlinks is False, and the last element of the path is a symbolic
10483 link, getxattr will examine the symbolic link itself instead of the file
10484 the link points to.
10485
10486[clinic start generated code]*/
10487
Larry Hastings2f936352014-08-05 14:04:04 +100010488static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010489os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010490 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010491/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010492{
10493 Py_ssize_t i;
10494 PyObject *buffer = NULL;
10495
10496 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10497 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010498
Larry Hastings9cf065c2012-06-22 16:30:09 -070010499 for (i = 0; ; i++) {
10500 void *ptr;
10501 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010502 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010503 Py_ssize_t buffer_size = buffer_sizes[i];
10504 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010505 path_error(path);
10506 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010507 }
10508 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10509 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010510 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010511 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010512
Larry Hastings9cf065c2012-06-22 16:30:09 -070010513 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010514 if (path->fd >= 0)
10515 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010516 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010517 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010518 else
Larry Hastings2f936352014-08-05 14:04:04 +100010519 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010520 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010521
Larry Hastings9cf065c2012-06-22 16:30:09 -070010522 if (result < 0) {
10523 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010524 if (errno == ERANGE)
10525 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010526 path_error(path);
10527 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010528 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010529
Larry Hastings9cf065c2012-06-22 16:30:09 -070010530 if (result != buffer_size) {
10531 /* Can only shrink. */
10532 _PyBytes_Resize(&buffer, result);
10533 }
10534 break;
10535 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010536
Larry Hastings9cf065c2012-06-22 16:30:09 -070010537 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010538}
10539
Larry Hastings2f936352014-08-05 14:04:04 +100010540
10541/*[clinic input]
10542os.setxattr
10543
10544 path: path_t(allow_fd=True)
10545 attribute: path_t
10546 value: Py_buffer
10547 flags: int = 0
10548 *
10549 follow_symlinks: bool = True
10550
10551Set extended attribute attribute on path to value.
10552
10553path may be either a string or an open file descriptor.
10554If follow_symlinks is False, and the last element of the path is a symbolic
10555 link, setxattr will modify the symbolic link itself instead of the file
10556 the link points to.
10557
10558[clinic start generated code]*/
10559
Benjamin Peterson799bd802011-08-31 22:15:17 -040010560static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010561os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010562 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010563/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010564{
Larry Hastings2f936352014-08-05 14:04:04 +100010565 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010566
Larry Hastings2f936352014-08-05 14:04:04 +100010567 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010568 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010569
Benjamin Peterson799bd802011-08-31 22:15:17 -040010570 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010571 if (path->fd > -1)
10572 result = fsetxattr(path->fd, attribute->narrow,
10573 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010574 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010575 result = setxattr(path->narrow, attribute->narrow,
10576 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010577 else
Larry Hastings2f936352014-08-05 14:04:04 +100010578 result = lsetxattr(path->narrow, attribute->narrow,
10579 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010580 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010581
Larry Hastings9cf065c2012-06-22 16:30:09 -070010582 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010583 path_error(path);
10584 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010585 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010586
Larry Hastings2f936352014-08-05 14:04:04 +100010587 Py_RETURN_NONE;
10588}
10589
10590
10591/*[clinic input]
10592os.removexattr
10593
10594 path: path_t(allow_fd=True)
10595 attribute: path_t
10596 *
10597 follow_symlinks: bool = True
10598
10599Remove extended attribute attribute on path.
10600
10601path may be either a string or an open file descriptor.
10602If follow_symlinks is False, and the last element of the path is a symbolic
10603 link, removexattr will modify the symbolic link itself instead of the file
10604 the link points to.
10605
10606[clinic start generated code]*/
10607
Larry Hastings2f936352014-08-05 14:04:04 +100010608static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010609os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010610 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010611/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010612{
10613 ssize_t result;
10614
10615 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10616 return NULL;
10617
10618 Py_BEGIN_ALLOW_THREADS;
10619 if (path->fd > -1)
10620 result = fremovexattr(path->fd, attribute->narrow);
10621 else if (follow_symlinks)
10622 result = removexattr(path->narrow, attribute->narrow);
10623 else
10624 result = lremovexattr(path->narrow, attribute->narrow);
10625 Py_END_ALLOW_THREADS;
10626
10627 if (result) {
10628 return path_error(path);
10629 }
10630
10631 Py_RETURN_NONE;
10632}
10633
10634
10635/*[clinic input]
10636os.listxattr
10637
10638 path: path_t(allow_fd=True, nullable=True) = None
10639 *
10640 follow_symlinks: bool = True
10641
10642Return a list of extended attributes on path.
10643
10644path may be either None, a string, or an open file descriptor.
10645if path is None, listxattr will examine the current directory.
10646If follow_symlinks is False, and the last element of the path is a symbolic
10647 link, listxattr will examine the symbolic link itself instead of the file
10648 the link points to.
10649[clinic start generated code]*/
10650
Larry Hastings2f936352014-08-05 14:04:04 +100010651static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010652os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10653/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010654{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010655 Py_ssize_t i;
10656 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010657 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010658 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010659
Larry Hastings2f936352014-08-05 14:04:04 +100010660 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010661 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010662
Larry Hastings2f936352014-08-05 14:04:04 +100010663 name = path->narrow ? path->narrow : ".";
10664
Larry Hastings9cf065c2012-06-22 16:30:09 -070010665 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010666 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010667 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010668 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010669 Py_ssize_t buffer_size = buffer_sizes[i];
10670 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010671 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010672 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010673 break;
10674 }
10675 buffer = PyMem_MALLOC(buffer_size);
10676 if (!buffer) {
10677 PyErr_NoMemory();
10678 break;
10679 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010680
Larry Hastings9cf065c2012-06-22 16:30:09 -070010681 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010682 if (path->fd > -1)
10683 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010684 else if (follow_symlinks)
10685 length = listxattr(name, buffer, buffer_size);
10686 else
10687 length = llistxattr(name, buffer, buffer_size);
10688 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010689
Larry Hastings9cf065c2012-06-22 16:30:09 -070010690 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010691 if (errno == ERANGE) {
10692 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010693 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010694 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010695 }
Larry Hastings2f936352014-08-05 14:04:04 +100010696 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010697 break;
10698 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010699
Larry Hastings9cf065c2012-06-22 16:30:09 -070010700 result = PyList_New(0);
10701 if (!result) {
10702 goto exit;
10703 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010704
Larry Hastings9cf065c2012-06-22 16:30:09 -070010705 end = buffer + length;
10706 for (trace = start = buffer; trace != end; trace++) {
10707 if (!*trace) {
10708 int error;
10709 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
10710 trace - start);
10711 if (!attribute) {
10712 Py_DECREF(result);
10713 result = NULL;
10714 goto exit;
10715 }
10716 error = PyList_Append(result, attribute);
10717 Py_DECREF(attribute);
10718 if (error) {
10719 Py_DECREF(result);
10720 result = NULL;
10721 goto exit;
10722 }
10723 start = trace + 1;
10724 }
10725 }
10726 break;
10727 }
10728exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070010729 if (buffer)
10730 PyMem_FREE(buffer);
10731 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010732}
Benjamin Peterson9428d532011-09-14 11:45:52 -040010733#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040010734
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010735
Larry Hastings2f936352014-08-05 14:04:04 +100010736/*[clinic input]
10737os.urandom
10738
10739 size: Py_ssize_t
10740 /
10741
10742Return a bytes object containing random bytes suitable for cryptographic use.
10743[clinic start generated code]*/
10744
Larry Hastings2f936352014-08-05 14:04:04 +100010745static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010746os_urandom_impl(PyObject *module, Py_ssize_t size)
10747/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010748{
10749 PyObject *bytes;
10750 int result;
10751
Georg Brandl2fb477c2012-02-21 00:33:36 +010010752 if (size < 0)
10753 return PyErr_Format(PyExc_ValueError,
10754 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100010755 bytes = PyBytes_FromStringAndSize(NULL, size);
10756 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010010757 return NULL;
10758
Victor Stinnere66987e2016-09-06 16:33:52 -070010759 result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
Larry Hastings2f936352014-08-05 14:04:04 +100010760 if (result == -1) {
10761 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010010762 return NULL;
10763 }
Larry Hastings2f936352014-08-05 14:04:04 +100010764 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010010765}
10766
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010767/* Terminal size querying */
10768
10769static PyTypeObject TerminalSizeType;
10770
10771PyDoc_STRVAR(TerminalSize_docstring,
10772 "A tuple of (columns, lines) for holding terminal window size");
10773
10774static PyStructSequence_Field TerminalSize_fields[] = {
10775 {"columns", "width of the terminal window in characters"},
10776 {"lines", "height of the terminal window in characters"},
10777 {NULL, NULL}
10778};
10779
10780static PyStructSequence_Desc TerminalSize_desc = {
10781 "os.terminal_size",
10782 TerminalSize_docstring,
10783 TerminalSize_fields,
10784 2,
10785};
10786
10787#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100010788/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010010789PyDoc_STRVAR(termsize__doc__,
10790 "Return the size of the terminal window as (columns, lines).\n" \
10791 "\n" \
10792 "The optional argument fd (default standard output) specifies\n" \
10793 "which file descriptor should be queried.\n" \
10794 "\n" \
10795 "If the file descriptor is not connected to a terminal, an OSError\n" \
10796 "is thrown.\n" \
10797 "\n" \
10798 "This function will only be defined if an implementation is\n" \
10799 "available for this system.\n" \
10800 "\n" \
10801 "shutil.get_terminal_size is the high-level function which should \n" \
10802 "normally be used, os.get_terminal_size is the low-level implementation.");
10803
10804static PyObject*
10805get_terminal_size(PyObject *self, PyObject *args)
10806{
10807 int columns, lines;
10808 PyObject *termsize;
10809
10810 int fd = fileno(stdout);
10811 /* Under some conditions stdout may not be connected and
10812 * fileno(stdout) may point to an invalid file descriptor. For example
10813 * GUI apps don't have valid standard streams by default.
10814 *
10815 * If this happens, and the optional fd argument is not present,
10816 * the ioctl below will fail returning EBADF. This is what we want.
10817 */
10818
10819 if (!PyArg_ParseTuple(args, "|i", &fd))
10820 return NULL;
10821
10822#ifdef TERMSIZE_USE_IOCTL
10823 {
10824 struct winsize w;
10825 if (ioctl(fd, TIOCGWINSZ, &w))
10826 return PyErr_SetFromErrno(PyExc_OSError);
10827 columns = w.ws_col;
10828 lines = w.ws_row;
10829 }
10830#endif /* TERMSIZE_USE_IOCTL */
10831
10832#ifdef TERMSIZE_USE_CONIO
10833 {
10834 DWORD nhandle;
10835 HANDLE handle;
10836 CONSOLE_SCREEN_BUFFER_INFO csbi;
10837 switch (fd) {
10838 case 0: nhandle = STD_INPUT_HANDLE;
10839 break;
10840 case 1: nhandle = STD_OUTPUT_HANDLE;
10841 break;
10842 case 2: nhandle = STD_ERROR_HANDLE;
10843 break;
10844 default:
10845 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
10846 }
10847 handle = GetStdHandle(nhandle);
10848 if (handle == NULL)
10849 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
10850 if (handle == INVALID_HANDLE_VALUE)
10851 return PyErr_SetFromWindowsErr(0);
10852
10853 if (!GetConsoleScreenBufferInfo(handle, &csbi))
10854 return PyErr_SetFromWindowsErr(0);
10855
10856 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
10857 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
10858 }
10859#endif /* TERMSIZE_USE_CONIO */
10860
10861 termsize = PyStructSequence_New(&TerminalSizeType);
10862 if (termsize == NULL)
10863 return NULL;
10864 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
10865 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
10866 if (PyErr_Occurred()) {
10867 Py_DECREF(termsize);
10868 return NULL;
10869 }
10870 return termsize;
10871}
10872#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
10873
Larry Hastings2f936352014-08-05 14:04:04 +100010874
10875/*[clinic input]
10876os.cpu_count
10877
Charles-François Natali80d62e62015-08-13 20:37:08 +010010878Return the number of CPUs in the system; return None if indeterminable.
10879
10880This number is not equivalent to the number of CPUs the current process can
10881use. The number of usable CPUs can be obtained with
10882``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100010883[clinic start generated code]*/
10884
Larry Hastings2f936352014-08-05 14:04:04 +100010885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010886os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030010887/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010888{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010889 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010890#ifdef MS_WINDOWS
10891 SYSTEM_INFO sysinfo;
10892 GetSystemInfo(&sysinfo);
10893 ncpu = sysinfo.dwNumberOfProcessors;
10894#elif defined(__hpux)
10895 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
10896#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
10897 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010898#elif defined(__DragonFly__) || \
10899 defined(__OpenBSD__) || \
10900 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020010901 defined(__NetBSD__) || \
10902 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020010903 int mib[2];
10904 size_t len = sizeof(ncpu);
10905 mib[0] = CTL_HW;
10906 mib[1] = HW_NCPU;
10907 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
10908 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020010909#endif
10910 if (ncpu >= 1)
10911 return PyLong_FromLong(ncpu);
10912 else
10913 Py_RETURN_NONE;
10914}
10915
Victor Stinnerdaf45552013-08-28 00:53:59 +020010916
Larry Hastings2f936352014-08-05 14:04:04 +100010917/*[clinic input]
10918os.get_inheritable -> bool
10919
10920 fd: int
10921 /
10922
10923Get the close-on-exe flag of the specified file descriptor.
10924[clinic start generated code]*/
10925
Larry Hastings2f936352014-08-05 14:04:04 +100010926static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010927os_get_inheritable_impl(PyObject *module, int fd)
10928/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010929{
Steve Dower8fc89802015-04-12 00:26:27 -040010930 int return_value;
Steve Dower8fc89802015-04-12 00:26:27 -040010931 _Py_BEGIN_SUPPRESS_IPH
10932 return_value = _Py_get_inheritable(fd);
10933 _Py_END_SUPPRESS_IPH
10934 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100010935}
10936
10937
10938/*[clinic input]
10939os.set_inheritable
10940 fd: int
10941 inheritable: int
10942 /
10943
10944Set the inheritable flag of the specified file descriptor.
10945[clinic start generated code]*/
10946
Larry Hastings2f936352014-08-05 14:04:04 +100010947static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010948os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
10949/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020010950{
Steve Dower8fc89802015-04-12 00:26:27 -040010951 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010952
Steve Dower8fc89802015-04-12 00:26:27 -040010953 _Py_BEGIN_SUPPRESS_IPH
10954 result = _Py_set_inheritable(fd, inheritable, NULL);
10955 _Py_END_SUPPRESS_IPH
10956 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020010957 return NULL;
10958 Py_RETURN_NONE;
10959}
10960
10961
10962#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010963/*[clinic input]
10964os.get_handle_inheritable -> bool
Benjamin Petersonca470632016-09-06 13:47:26 -070010965 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100010966 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020010967
Larry Hastings2f936352014-08-05 14:04:04 +100010968Get the close-on-exe flag of the specified file descriptor.
10969[clinic start generated code]*/
10970
Larry Hastings2f936352014-08-05 14:04:04 +100010971static int
Benjamin Petersonca470632016-09-06 13:47:26 -070010972os_get_handle_inheritable_impl(PyObject *module, intptr_t handle)
Victor Stinner581139c2016-09-06 15:54:20 -070010973/*[clinic end generated code: output=36be5afca6ea84d8 input=cfe99f9c05c70ad1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010974{
10975 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010976
10977 if (!GetHandleInformation((HANDLE)handle, &flags)) {
10978 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100010979 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010980 }
10981
Larry Hastings2f936352014-08-05 14:04:04 +100010982 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020010983}
10984
Victor Stinnerdaf45552013-08-28 00:53:59 +020010985
Larry Hastings2f936352014-08-05 14:04:04 +100010986/*[clinic input]
10987os.set_handle_inheritable
Benjamin Petersonca470632016-09-06 13:47:26 -070010988 handle: intptr_t
Larry Hastings2f936352014-08-05 14:04:04 +100010989 inheritable: bool
10990 /
10991
10992Set the inheritable flag of the specified handle.
10993[clinic start generated code]*/
10994
Larry Hastings2f936352014-08-05 14:04:04 +100010995static PyObject *
Benjamin Petersonca470632016-09-06 13:47:26 -070010996os_set_handle_inheritable_impl(PyObject *module, intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040010997 int inheritable)
Victor Stinner581139c2016-09-06 15:54:20 -070010998/*[clinic end generated code: output=021d74fe6c96baa3 input=7a7641390d8364fc]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010999{
11000 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011001 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11002 PyErr_SetFromWindowsErr(0);
11003 return NULL;
11004 }
11005 Py_RETURN_NONE;
11006}
Larry Hastings2f936352014-08-05 14:04:04 +100011007#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011008
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011009#ifndef MS_WINDOWS
11010PyDoc_STRVAR(get_blocking__doc__,
11011 "get_blocking(fd) -> bool\n" \
11012 "\n" \
11013 "Get the blocking mode of the file descriptor:\n" \
11014 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11015
11016static PyObject*
11017posix_get_blocking(PyObject *self, PyObject *args)
11018{
11019 int fd;
11020 int blocking;
11021
11022 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11023 return NULL;
11024
Steve Dower8fc89802015-04-12 00:26:27 -040011025 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011026 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011027 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011028 if (blocking < 0)
11029 return NULL;
11030 return PyBool_FromLong(blocking);
11031}
11032
11033PyDoc_STRVAR(set_blocking__doc__,
11034 "set_blocking(fd, blocking)\n" \
11035 "\n" \
11036 "Set the blocking mode of the specified file descriptor.\n" \
11037 "Set the O_NONBLOCK flag if blocking is False,\n" \
11038 "clear the O_NONBLOCK flag otherwise.");
11039
11040static PyObject*
11041posix_set_blocking(PyObject *self, PyObject *args)
11042{
Steve Dower8fc89802015-04-12 00:26:27 -040011043 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011044
11045 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11046 return NULL;
11047
Steve Dower8fc89802015-04-12 00:26:27 -040011048 _Py_BEGIN_SUPPRESS_IPH
11049 result = _Py_set_blocking(fd, blocking);
11050 _Py_END_SUPPRESS_IPH
11051 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011052 return NULL;
11053 Py_RETURN_NONE;
11054}
11055#endif /* !MS_WINDOWS */
11056
11057
Victor Stinner6036e442015-03-08 01:58:04 +010011058PyDoc_STRVAR(posix_scandir__doc__,
11059"scandir(path='.') -> iterator of DirEntry objects for given path");
11060
11061static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11062
11063typedef struct {
11064 PyObject_HEAD
11065 PyObject *name;
11066 PyObject *path;
11067 PyObject *stat;
11068 PyObject *lstat;
11069#ifdef MS_WINDOWS
11070 struct _Py_stat_struct win32_lstat;
11071 __int64 win32_file_index;
11072 int got_file_index;
11073#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011074#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011075 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011076#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011077 ino_t d_ino;
11078#endif
11079} DirEntry;
11080
11081static void
11082DirEntry_dealloc(DirEntry *entry)
11083{
11084 Py_XDECREF(entry->name);
11085 Py_XDECREF(entry->path);
11086 Py_XDECREF(entry->stat);
11087 Py_XDECREF(entry->lstat);
11088 Py_TYPE(entry)->tp_free((PyObject *)entry);
11089}
11090
11091/* Forward reference */
11092static int
11093DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11094
11095/* Set exception and return -1 on error, 0 for False, 1 for True */
11096static int
11097DirEntry_is_symlink(DirEntry *self)
11098{
11099#ifdef MS_WINDOWS
11100 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011101#elif defined(HAVE_DIRENT_D_TYPE)
11102 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011103 if (self->d_type != DT_UNKNOWN)
11104 return self->d_type == DT_LNK;
11105 else
11106 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011107#else
11108 /* POSIX without d_type */
11109 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011110#endif
11111}
11112
11113static PyObject *
11114DirEntry_py_is_symlink(DirEntry *self)
11115{
11116 int result;
11117
11118 result = DirEntry_is_symlink(self);
11119 if (result == -1)
11120 return NULL;
11121 return PyBool_FromLong(result);
11122}
11123
11124static PyObject *
11125DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11126{
11127 int result;
11128 struct _Py_stat_struct st;
11129
11130#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011131 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011132
11133 path = PyUnicode_AsUnicode(self->path);
11134 if (!path)
11135 return NULL;
11136
11137 if (follow_symlinks)
Steve Dowercc16be82016-09-08 10:35:16 -070011138 result = win32_stat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011139 else
Steve Dowercc16be82016-09-08 10:35:16 -070011140 result = win32_lstat(path, &st);
Victor Stinner6036e442015-03-08 01:58:04 +010011141
11142 if (result != 0) {
11143 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11144 0, self->path);
11145 }
11146#else /* POSIX */
11147 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011148 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011149
11150 if (!PyUnicode_FSConverter(self->path, &bytes))
11151 return NULL;
11152 path = PyBytes_AS_STRING(bytes);
11153
11154 if (follow_symlinks)
11155 result = STAT(path, &st);
11156 else
11157 result = LSTAT(path, &st);
11158 Py_DECREF(bytes);
11159
11160 if (result != 0)
11161 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11162#endif
11163
11164 return _pystat_fromstructstat(&st);
11165}
11166
11167static PyObject *
11168DirEntry_get_lstat(DirEntry *self)
11169{
11170 if (!self->lstat) {
11171#ifdef MS_WINDOWS
11172 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11173#else /* POSIX */
11174 self->lstat = DirEntry_fetch_stat(self, 0);
11175#endif
11176 }
11177 Py_XINCREF(self->lstat);
11178 return self->lstat;
11179}
11180
11181static PyObject *
11182DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11183{
11184 if (!follow_symlinks)
11185 return DirEntry_get_lstat(self);
11186
11187 if (!self->stat) {
11188 int result = DirEntry_is_symlink(self);
11189 if (result == -1)
11190 return NULL;
11191 else if (result)
11192 self->stat = DirEntry_fetch_stat(self, 1);
11193 else
11194 self->stat = DirEntry_get_lstat(self);
11195 }
11196
11197 Py_XINCREF(self->stat);
11198 return self->stat;
11199}
11200
11201static PyObject *
11202DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11203{
11204 int follow_symlinks = 1;
11205
11206 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11207 follow_symlinks_keywords, &follow_symlinks))
11208 return NULL;
11209
11210 return DirEntry_get_stat(self, follow_symlinks);
11211}
11212
11213/* Set exception and return -1 on error, 0 for False, 1 for True */
11214static int
11215DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11216{
11217 PyObject *stat = NULL;
11218 PyObject *st_mode = NULL;
11219 long mode;
11220 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011221#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011222 int is_symlink;
11223 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011224#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011225#ifdef MS_WINDOWS
11226 unsigned long dir_bits;
11227#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011228 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011229
11230#ifdef MS_WINDOWS
11231 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11232 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011233#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011234 is_symlink = self->d_type == DT_LNK;
11235 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11236#endif
11237
Victor Stinner35a97c02015-03-08 02:59:09 +010011238#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011239 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011240#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011241 stat = DirEntry_get_stat(self, follow_symlinks);
11242 if (!stat) {
11243 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11244 /* If file doesn't exist (anymore), then return False
11245 (i.e., say it's not a file/directory) */
11246 PyErr_Clear();
11247 return 0;
11248 }
11249 goto error;
11250 }
11251 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11252 if (!st_mode)
11253 goto error;
11254
11255 mode = PyLong_AsLong(st_mode);
11256 if (mode == -1 && PyErr_Occurred())
11257 goto error;
11258 Py_CLEAR(st_mode);
11259 Py_CLEAR(stat);
11260 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011261#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011262 }
11263 else if (is_symlink) {
11264 assert(mode_bits != S_IFLNK);
11265 result = 0;
11266 }
11267 else {
11268 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11269#ifdef MS_WINDOWS
11270 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11271 if (mode_bits == S_IFDIR)
11272 result = dir_bits != 0;
11273 else
11274 result = dir_bits == 0;
11275#else /* POSIX */
11276 if (mode_bits == S_IFDIR)
11277 result = self->d_type == DT_DIR;
11278 else
11279 result = self->d_type == DT_REG;
11280#endif
11281 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011282#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011283
11284 return result;
11285
11286error:
11287 Py_XDECREF(st_mode);
11288 Py_XDECREF(stat);
11289 return -1;
11290}
11291
11292static PyObject *
11293DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11294{
11295 int result;
11296
11297 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11298 if (result == -1)
11299 return NULL;
11300 return PyBool_FromLong(result);
11301}
11302
11303static PyObject *
11304DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11305{
11306 int follow_symlinks = 1;
11307
11308 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11309 follow_symlinks_keywords, &follow_symlinks))
11310 return NULL;
11311
11312 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11313}
11314
11315static PyObject *
11316DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11317{
11318 int follow_symlinks = 1;
11319
11320 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11321 follow_symlinks_keywords, &follow_symlinks))
11322 return NULL;
11323
11324 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11325}
11326
11327static PyObject *
11328DirEntry_inode(DirEntry *self)
11329{
11330#ifdef MS_WINDOWS
11331 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011332 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011333 struct _Py_stat_struct stat;
11334
11335 path = PyUnicode_AsUnicode(self->path);
11336 if (!path)
11337 return NULL;
11338
Steve Dowercc16be82016-09-08 10:35:16 -070011339 if (win32_lstat(path, &stat) != 0) {
Victor Stinner6036e442015-03-08 01:58:04 +010011340 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11341 0, self->path);
11342 }
11343
11344 self->win32_file_index = stat.st_ino;
11345 self->got_file_index = 1;
11346 }
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011347 return PyLong_FromLongLong((long long)self->win32_file_index);
Victor Stinner6036e442015-03-08 01:58:04 +010011348#else /* POSIX */
11349#ifdef HAVE_LARGEFILE_SUPPORT
Benjamin Petersonaf580df2016-09-06 10:46:49 -070011350 return PyLong_FromLongLong((long long)self->d_ino);
Victor Stinner6036e442015-03-08 01:58:04 +010011351#else
11352 return PyLong_FromLong((long)self->d_ino);
11353#endif
11354#endif
11355}
11356
11357static PyObject *
11358DirEntry_repr(DirEntry *self)
11359{
11360 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11361}
11362
Brett Cannon96881cd2016-06-10 14:37:21 -070011363static PyObject *
11364DirEntry_fspath(DirEntry *self)
11365{
11366 Py_INCREF(self->path);
11367 return self->path;
11368}
11369
Victor Stinner6036e442015-03-08 01:58:04 +010011370static PyMemberDef DirEntry_members[] = {
11371 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11372 "the entry's base filename, relative to scandir() \"path\" argument"},
11373 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11374 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11375 {NULL}
11376};
11377
11378static PyMethodDef DirEntry_methods[] = {
11379 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11380 "return True if the entry is a directory; cached per entry"
11381 },
11382 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11383 "return True if the entry is a file; cached per entry"
11384 },
11385 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11386 "return True if the entry is a symbolic link; cached per entry"
11387 },
11388 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11389 "return stat_result object for the entry; cached per entry"
11390 },
11391 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11392 "return inode of the entry; cached per entry",
11393 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011394 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11395 "returns the path for the entry",
11396 },
Victor Stinner6036e442015-03-08 01:58:04 +010011397 {NULL}
11398};
11399
Benjamin Peterson5646de42015-04-12 17:56:34 -040011400static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011401 PyVarObject_HEAD_INIT(NULL, 0)
11402 MODNAME ".DirEntry", /* tp_name */
11403 sizeof(DirEntry), /* tp_basicsize */
11404 0, /* tp_itemsize */
11405 /* methods */
11406 (destructor)DirEntry_dealloc, /* tp_dealloc */
11407 0, /* tp_print */
11408 0, /* tp_getattr */
11409 0, /* tp_setattr */
11410 0, /* tp_compare */
11411 (reprfunc)DirEntry_repr, /* tp_repr */
11412 0, /* tp_as_number */
11413 0, /* tp_as_sequence */
11414 0, /* tp_as_mapping */
11415 0, /* tp_hash */
11416 0, /* tp_call */
11417 0, /* tp_str */
11418 0, /* tp_getattro */
11419 0, /* tp_setattro */
11420 0, /* tp_as_buffer */
11421 Py_TPFLAGS_DEFAULT, /* tp_flags */
11422 0, /* tp_doc */
11423 0, /* tp_traverse */
11424 0, /* tp_clear */
11425 0, /* tp_richcompare */
11426 0, /* tp_weaklistoffset */
11427 0, /* tp_iter */
11428 0, /* tp_iternext */
11429 DirEntry_methods, /* tp_methods */
11430 DirEntry_members, /* tp_members */
11431};
11432
11433#ifdef MS_WINDOWS
11434
11435static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011436join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011437{
11438 Py_ssize_t path_len;
11439 Py_ssize_t size;
11440 wchar_t *result;
11441 wchar_t ch;
11442
11443 if (!path_wide) { /* Default arg: "." */
11444 path_wide = L".";
11445 path_len = 1;
11446 }
11447 else {
11448 path_len = wcslen(path_wide);
11449 }
11450
11451 /* The +1's are for the path separator and the NUL */
11452 size = path_len + 1 + wcslen(filename) + 1;
11453 result = PyMem_New(wchar_t, size);
11454 if (!result) {
11455 PyErr_NoMemory();
11456 return NULL;
11457 }
11458 wcscpy(result, path_wide);
11459 if (path_len > 0) {
11460 ch = result[path_len - 1];
11461 if (ch != SEP && ch != ALTSEP && ch != L':')
11462 result[path_len++] = SEP;
11463 wcscpy(result + path_len, filename);
11464 }
11465 return result;
11466}
11467
11468static PyObject *
11469DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11470{
11471 DirEntry *entry;
11472 BY_HANDLE_FILE_INFORMATION file_info;
11473 ULONG reparse_tag;
11474 wchar_t *joined_path;
11475
11476 entry = PyObject_New(DirEntry, &DirEntryType);
11477 if (!entry)
11478 return NULL;
11479 entry->name = NULL;
11480 entry->path = NULL;
11481 entry->stat = NULL;
11482 entry->lstat = NULL;
11483 entry->got_file_index = 0;
11484
11485 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11486 if (!entry->name)
11487 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011488 if (path->narrow) {
11489 Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
11490 if (!entry->name)
11491 goto error;
11492 }
Victor Stinner6036e442015-03-08 01:58:04 +010011493
11494 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11495 if (!joined_path)
11496 goto error;
11497
11498 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11499 PyMem_Free(joined_path);
11500 if (!entry->path)
11501 goto error;
Steve Dowercc16be82016-09-08 10:35:16 -070011502 if (path->narrow) {
11503 Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
11504 if (!entry->path)
11505 goto error;
11506 }
Victor Stinner6036e442015-03-08 01:58:04 +010011507
Steve Dowercc16be82016-09-08 10:35:16 -070011508 find_data_to_file_info(dataW, &file_info, &reparse_tag);
Victor Stinner6036e442015-03-08 01:58:04 +010011509 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11510
11511 return (PyObject *)entry;
11512
11513error:
11514 Py_DECREF(entry);
11515 return NULL;
11516}
11517
11518#else /* POSIX */
11519
11520static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011521join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011522{
11523 Py_ssize_t path_len;
11524 Py_ssize_t size;
11525 char *result;
11526
11527 if (!path_narrow) { /* Default arg: "." */
11528 path_narrow = ".";
11529 path_len = 1;
11530 }
11531 else {
11532 path_len = strlen(path_narrow);
11533 }
11534
11535 if (filename_len == -1)
11536 filename_len = strlen(filename);
11537
11538 /* The +1's are for the path separator and the NUL */
11539 size = path_len + 1 + filename_len + 1;
11540 result = PyMem_New(char, size);
11541 if (!result) {
11542 PyErr_NoMemory();
11543 return NULL;
11544 }
11545 strcpy(result, path_narrow);
11546 if (path_len > 0 && result[path_len - 1] != '/')
11547 result[path_len++] = '/';
11548 strcpy(result + path_len, filename);
11549 return result;
11550}
11551
11552static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011553DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011554 ino_t d_ino
11555#ifdef HAVE_DIRENT_D_TYPE
11556 , unsigned char d_type
11557#endif
11558 )
Victor Stinner6036e442015-03-08 01:58:04 +010011559{
11560 DirEntry *entry;
11561 char *joined_path;
11562
11563 entry = PyObject_New(DirEntry, &DirEntryType);
11564 if (!entry)
11565 return NULL;
11566 entry->name = NULL;
11567 entry->path = NULL;
11568 entry->stat = NULL;
11569 entry->lstat = NULL;
11570
11571 joined_path = join_path_filename(path->narrow, name, name_len);
11572 if (!joined_path)
11573 goto error;
11574
11575 if (!path->narrow || !PyBytes_Check(path->object)) {
11576 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11577 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11578 }
11579 else {
11580 entry->name = PyBytes_FromStringAndSize(name, name_len);
11581 entry->path = PyBytes_FromString(joined_path);
11582 }
11583 PyMem_Free(joined_path);
11584 if (!entry->name || !entry->path)
11585 goto error;
11586
Victor Stinner35a97c02015-03-08 02:59:09 +010011587#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011588 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011589#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011590 entry->d_ino = d_ino;
11591
11592 return (PyObject *)entry;
11593
11594error:
11595 Py_XDECREF(entry);
11596 return NULL;
11597}
11598
11599#endif
11600
11601
11602typedef struct {
11603 PyObject_HEAD
11604 path_t path;
11605#ifdef MS_WINDOWS
11606 HANDLE handle;
11607 WIN32_FIND_DATAW file_data;
11608 int first_time;
11609#else /* POSIX */
11610 DIR *dirp;
11611#endif
11612} ScandirIterator;
11613
11614#ifdef MS_WINDOWS
11615
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011616static int
11617ScandirIterator_is_closed(ScandirIterator *iterator)
11618{
11619 return iterator->handle == INVALID_HANDLE_VALUE;
11620}
11621
Victor Stinner6036e442015-03-08 01:58:04 +010011622static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011623ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011624{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011625 HANDLE handle = iterator->handle;
11626
11627 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011628 return;
11629
Victor Stinner6036e442015-03-08 01:58:04 +010011630 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011631 Py_BEGIN_ALLOW_THREADS
11632 FindClose(handle);
11633 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011634}
11635
11636static PyObject *
11637ScandirIterator_iternext(ScandirIterator *iterator)
11638{
11639 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11640 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011641 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011642
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011643 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011644 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011645 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011646
11647 while (1) {
11648 if (!iterator->first_time) {
11649 Py_BEGIN_ALLOW_THREADS
11650 success = FindNextFileW(iterator->handle, file_data);
11651 Py_END_ALLOW_THREADS
11652 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011653 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011654 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011655 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011656 break;
11657 }
11658 }
11659 iterator->first_time = 0;
11660
11661 /* Skip over . and .. */
11662 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011663 wcscmp(file_data->cFileName, L"..") != 0) {
11664 entry = DirEntry_from_find_data(&iterator->path, file_data);
11665 if (!entry)
11666 break;
11667 return entry;
11668 }
Victor Stinner6036e442015-03-08 01:58:04 +010011669
11670 /* Loop till we get a non-dot directory or finish iterating */
11671 }
11672
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011673 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011674 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011675 return NULL;
11676}
11677
11678#else /* POSIX */
11679
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011680static int
11681ScandirIterator_is_closed(ScandirIterator *iterator)
11682{
11683 return !iterator->dirp;
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 DIR *dirp = iterator->dirp;
11690
11691 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011692 return;
11693
Victor Stinner6036e442015-03-08 01:58:04 +010011694 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011695 Py_BEGIN_ALLOW_THREADS
11696 closedir(dirp);
11697 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011698 return;
11699}
11700
11701static PyObject *
11702ScandirIterator_iternext(ScandirIterator *iterator)
11703{
11704 struct dirent *direntp;
11705 Py_ssize_t name_len;
11706 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011707 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011708
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011709 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011710 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011711 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011712
11713 while (1) {
11714 errno = 0;
11715 Py_BEGIN_ALLOW_THREADS
11716 direntp = readdir(iterator->dirp);
11717 Py_END_ALLOW_THREADS
11718
11719 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011720 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011721 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011722 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011723 break;
11724 }
11725
11726 /* Skip over . and .. */
11727 name_len = NAMLEN(direntp);
11728 is_dot = direntp->d_name[0] == '.' &&
11729 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11730 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011731 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010011732 name_len, direntp->d_ino
11733#ifdef HAVE_DIRENT_D_TYPE
11734 , direntp->d_type
11735#endif
11736 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011737 if (!entry)
11738 break;
11739 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011740 }
11741
11742 /* Loop till we get a non-dot directory or finish iterating */
11743 }
11744
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011745 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011746 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011747 return NULL;
11748}
11749
11750#endif
11751
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011752static PyObject *
11753ScandirIterator_close(ScandirIterator *self, PyObject *args)
11754{
11755 ScandirIterator_closedir(self);
11756 Py_RETURN_NONE;
11757}
11758
11759static PyObject *
11760ScandirIterator_enter(PyObject *self, PyObject *args)
11761{
11762 Py_INCREF(self);
11763 return self;
11764}
11765
11766static PyObject *
11767ScandirIterator_exit(ScandirIterator *self, PyObject *args)
11768{
11769 ScandirIterator_closedir(self);
11770 Py_RETURN_NONE;
11771}
11772
Victor Stinner6036e442015-03-08 01:58:04 +010011773static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010011774ScandirIterator_finalize(ScandirIterator *iterator)
11775{
11776 PyObject *error_type, *error_value, *error_traceback;
11777
11778 /* Save the current exception, if any. */
11779 PyErr_Fetch(&error_type, &error_value, &error_traceback);
11780
11781 if (!ScandirIterator_is_closed(iterator)) {
11782 ScandirIterator_closedir(iterator);
11783
11784 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
11785 "unclosed scandir iterator %R", iterator)) {
11786 /* Spurious errors can appear at shutdown */
11787 if (PyErr_ExceptionMatches(PyExc_Warning)) {
11788 PyErr_WriteUnraisable((PyObject *) iterator);
11789 }
11790 }
11791 }
11792
11793 Py_CLEAR(iterator->path.object);
11794 path_cleanup(&iterator->path);
11795
11796 /* Restore the saved exception. */
11797 PyErr_Restore(error_type, error_value, error_traceback);
11798}
11799
11800static void
Victor Stinner6036e442015-03-08 01:58:04 +010011801ScandirIterator_dealloc(ScandirIterator *iterator)
11802{
Victor Stinner7bfa4092016-03-23 00:43:54 +010011803 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
11804 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011805
Victor Stinner6036e442015-03-08 01:58:04 +010011806 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
11807}
11808
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011809static PyMethodDef ScandirIterator_methods[] = {
11810 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
11811 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
11812 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
11813 {NULL}
11814};
11815
Benjamin Peterson5646de42015-04-12 17:56:34 -040011816static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011817 PyVarObject_HEAD_INIT(NULL, 0)
11818 MODNAME ".ScandirIterator", /* tp_name */
11819 sizeof(ScandirIterator), /* tp_basicsize */
11820 0, /* tp_itemsize */
11821 /* methods */
11822 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
11823 0, /* tp_print */
11824 0, /* tp_getattr */
11825 0, /* tp_setattr */
11826 0, /* tp_compare */
11827 0, /* tp_repr */
11828 0, /* tp_as_number */
11829 0, /* tp_as_sequence */
11830 0, /* tp_as_mapping */
11831 0, /* tp_hash */
11832 0, /* tp_call */
11833 0, /* tp_str */
11834 0, /* tp_getattro */
11835 0, /* tp_setattro */
11836 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011837 Py_TPFLAGS_DEFAULT
11838 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010011839 0, /* tp_doc */
11840 0, /* tp_traverse */
11841 0, /* tp_clear */
11842 0, /* tp_richcompare */
11843 0, /* tp_weaklistoffset */
11844 PyObject_SelfIter, /* tp_iter */
11845 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011846 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010011847 0, /* tp_members */
11848 0, /* tp_getset */
11849 0, /* tp_base */
11850 0, /* tp_dict */
11851 0, /* tp_descr_get */
11852 0, /* tp_descr_set */
11853 0, /* tp_dictoffset */
11854 0, /* tp_init */
11855 0, /* tp_alloc */
11856 0, /* tp_new */
11857 0, /* tp_free */
11858 0, /* tp_is_gc */
11859 0, /* tp_bases */
11860 0, /* tp_mro */
11861 0, /* tp_cache */
11862 0, /* tp_subclasses */
11863 0, /* tp_weaklist */
11864 0, /* tp_del */
11865 0, /* tp_version_tag */
11866 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010011867};
11868
11869static PyObject *
11870posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
11871{
11872 ScandirIterator *iterator;
11873 static char *keywords[] = {"path", NULL};
11874#ifdef MS_WINDOWS
11875 wchar_t *path_strW;
11876#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011877 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011878#endif
11879
11880 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
11881 if (!iterator)
11882 return NULL;
11883 memset(&iterator->path, 0, sizeof(path_t));
11884 iterator->path.function_name = "scandir";
11885 iterator->path.nullable = 1;
11886
11887#ifdef MS_WINDOWS
11888 iterator->handle = INVALID_HANDLE_VALUE;
11889#else
11890 iterator->dirp = NULL;
11891#endif
11892
11893 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
11894 path_converter, &iterator->path))
11895 goto error;
11896
11897 /* path_converter doesn't keep path.object around, so do it
11898 manually for the lifetime of the iterator here (the refcount
11899 is decremented in ScandirIterator_dealloc)
11900 */
11901 Py_XINCREF(iterator->path.object);
11902
11903#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +010011904 iterator->first_time = 1;
11905
11906 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
11907 if (!path_strW)
11908 goto error;
11909
11910 Py_BEGIN_ALLOW_THREADS
11911 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
11912 Py_END_ALLOW_THREADS
11913
11914 PyMem_Free(path_strW);
11915
11916 if (iterator->handle == INVALID_HANDLE_VALUE) {
11917 path_error(&iterator->path);
11918 goto error;
11919 }
11920#else /* POSIX */
11921 if (iterator->path.narrow)
11922 path = iterator->path.narrow;
11923 else
11924 path = ".";
11925
11926 errno = 0;
11927 Py_BEGIN_ALLOW_THREADS
11928 iterator->dirp = opendir(path);
11929 Py_END_ALLOW_THREADS
11930
11931 if (!iterator->dirp) {
11932 path_error(&iterator->path);
11933 goto error;
11934 }
11935#endif
11936
11937 return (PyObject *)iterator;
11938
11939error:
11940 Py_DECREF(iterator);
11941 return NULL;
11942}
11943
Ethan Furman410ef8e2016-06-04 12:06:26 -070011944/*
11945 Return the file system path representation of the object.
11946
11947 If the object is str or bytes, then allow it to pass through with
11948 an incremented refcount. If the object defines __fspath__(), then
11949 return the result of that method. All other types raise a TypeError.
11950*/
11951PyObject *
11952PyOS_FSPath(PyObject *path)
11953{
Brett Cannon3f9183b2016-08-26 14:44:48 -070011954 /* For error message reasons, this function is manually inlined in
11955 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070011956 _Py_IDENTIFIER(__fspath__);
11957 PyObject *func = NULL;
11958 PyObject *path_repr = NULL;
11959
11960 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
11961 Py_INCREF(path);
11962 return path;
11963 }
11964
11965 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
11966 if (NULL == func) {
11967 return PyErr_Format(PyExc_TypeError,
11968 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070011969 "not %.200s",
11970 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070011971 }
11972
11973 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
11974 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070011975 if (NULL == path_repr) {
11976 return NULL;
11977 }
11978
Brett Cannonc78ca1e2016-06-24 12:03:43 -070011979 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
11980 PyErr_Format(PyExc_TypeError,
11981 "expected %.200s.__fspath__() to return str or bytes, "
11982 "not %.200s", Py_TYPE(path)->tp_name,
11983 Py_TYPE(path_repr)->tp_name);
11984 Py_DECREF(path_repr);
11985 return NULL;
11986 }
11987
Ethan Furman410ef8e2016-06-04 12:06:26 -070011988 return path_repr;
11989}
11990
11991/*[clinic input]
11992os.fspath
11993
11994 path: object
11995
11996Return the file system path representation of the object.
11997
Brett Cannonb4f43e92016-06-09 14:32:08 -070011998If the object is str or bytes, then allow it to pass through as-is. If the
11999object defines __fspath__(), then return the result of that method. All other
12000types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012001[clinic start generated code]*/
12002
12003static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012004os_fspath_impl(PyObject *module, PyObject *path)
12005/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012006{
12007 return PyOS_FSPath(path);
12008}
Victor Stinner6036e442015-03-08 01:58:04 +010012009
Victor Stinner9b1f4742016-09-06 16:18:52 -070012010#ifdef HAVE_GETRANDOM_SYSCALL
12011/*[clinic input]
12012os.getrandom
12013
12014 size: Py_ssize_t
12015 flags: int=0
12016
12017Obtain a series of random bytes.
12018[clinic start generated code]*/
12019
12020static PyObject *
12021os_getrandom_impl(PyObject *module, Py_ssize_t size, int flags)
12022/*[clinic end generated code: output=b3a618196a61409c input=59bafac39c594947]*/
12023{
12024 char *buffer;
12025 Py_ssize_t n;
12026 PyObject *bytes;
12027
12028 if (size < 0) {
12029 errno = EINVAL;
12030 return posix_error();
12031 }
12032
12033 buffer = PyMem_Malloc(size);
12034 if (buffer == NULL) {
12035 PyErr_NoMemory();
12036 return NULL;
12037 }
12038
12039 while (1) {
12040 n = syscall(SYS_getrandom, buffer, size, flags);
12041 if (n < 0 && errno == EINTR) {
12042 if (PyErr_CheckSignals() < 0) {
12043 return NULL;
12044 }
12045 continue;
12046 }
12047 break;
12048 }
12049
12050 if (n < 0) {
12051 PyMem_Free(buffer);
12052 PyErr_SetFromErrno(PyExc_OSError);
12053 return NULL;
12054 }
12055
12056 bytes = PyBytes_FromStringAndSize(buffer, n);
12057 PyMem_Free(buffer);
12058
12059 return bytes;
12060}
12061#endif /* HAVE_GETRANDOM_SYSCALL */
12062
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012063#include "clinic/posixmodule.c.h"
12064
Larry Hastings7726ac92014-01-31 22:03:12 -080012065/*[clinic input]
12066dump buffer
12067[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012068/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012069
Larry Hastings31826802013-10-19 00:09:25 -070012070
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012071static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012072
12073 OS_STAT_METHODDEF
12074 OS_ACCESS_METHODDEF
12075 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012076 OS_CHDIR_METHODDEF
12077 OS_CHFLAGS_METHODDEF
12078 OS_CHMOD_METHODDEF
12079 OS_FCHMOD_METHODDEF
12080 OS_LCHMOD_METHODDEF
12081 OS_CHOWN_METHODDEF
12082 OS_FCHOWN_METHODDEF
12083 OS_LCHOWN_METHODDEF
12084 OS_LCHFLAGS_METHODDEF
12085 OS_CHROOT_METHODDEF
12086 OS_CTERMID_METHODDEF
12087 OS_GETCWD_METHODDEF
12088 OS_GETCWDB_METHODDEF
12089 OS_LINK_METHODDEF
12090 OS_LISTDIR_METHODDEF
12091 OS_LSTAT_METHODDEF
12092 OS_MKDIR_METHODDEF
12093 OS_NICE_METHODDEF
12094 OS_GETPRIORITY_METHODDEF
12095 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012096#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012097 {"readlink", (PyCFunction)posix_readlink,
12098 METH_VARARGS | METH_KEYWORDS,
12099 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012100#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012101#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012102 {"readlink", (PyCFunction)win_readlink,
12103 METH_VARARGS | METH_KEYWORDS,
12104 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012105#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012106 OS_RENAME_METHODDEF
12107 OS_REPLACE_METHODDEF
12108 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012109 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012110 OS_SYMLINK_METHODDEF
12111 OS_SYSTEM_METHODDEF
12112 OS_UMASK_METHODDEF
12113 OS_UNAME_METHODDEF
12114 OS_UNLINK_METHODDEF
12115 OS_REMOVE_METHODDEF
12116 OS_UTIME_METHODDEF
12117 OS_TIMES_METHODDEF
12118 OS__EXIT_METHODDEF
12119 OS_EXECV_METHODDEF
12120 OS_EXECVE_METHODDEF
12121 OS_SPAWNV_METHODDEF
12122 OS_SPAWNVE_METHODDEF
12123 OS_FORK1_METHODDEF
12124 OS_FORK_METHODDEF
12125 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12126 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12127 OS_SCHED_GETPARAM_METHODDEF
12128 OS_SCHED_GETSCHEDULER_METHODDEF
12129 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12130 OS_SCHED_SETPARAM_METHODDEF
12131 OS_SCHED_SETSCHEDULER_METHODDEF
12132 OS_SCHED_YIELD_METHODDEF
12133 OS_SCHED_SETAFFINITY_METHODDEF
12134 OS_SCHED_GETAFFINITY_METHODDEF
12135 OS_OPENPTY_METHODDEF
12136 OS_FORKPTY_METHODDEF
12137 OS_GETEGID_METHODDEF
12138 OS_GETEUID_METHODDEF
12139 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012140#ifdef HAVE_GETGROUPLIST
12141 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12142#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012143 OS_GETGROUPS_METHODDEF
12144 OS_GETPID_METHODDEF
12145 OS_GETPGRP_METHODDEF
12146 OS_GETPPID_METHODDEF
12147 OS_GETUID_METHODDEF
12148 OS_GETLOGIN_METHODDEF
12149 OS_KILL_METHODDEF
12150 OS_KILLPG_METHODDEF
12151 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012152#ifdef MS_WINDOWS
Steve Dowercc16be82016-09-08 10:35:16 -070012153 OS_STARTFILE_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012154#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012155 OS_SETUID_METHODDEF
12156 OS_SETEUID_METHODDEF
12157 OS_SETREUID_METHODDEF
12158 OS_SETGID_METHODDEF
12159 OS_SETEGID_METHODDEF
12160 OS_SETREGID_METHODDEF
12161 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012162#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012163 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012164#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012165 OS_GETPGID_METHODDEF
12166 OS_SETPGRP_METHODDEF
12167 OS_WAIT_METHODDEF
12168 OS_WAIT3_METHODDEF
12169 OS_WAIT4_METHODDEF
12170 OS_WAITID_METHODDEF
12171 OS_WAITPID_METHODDEF
12172 OS_GETSID_METHODDEF
12173 OS_SETSID_METHODDEF
12174 OS_SETPGID_METHODDEF
12175 OS_TCGETPGRP_METHODDEF
12176 OS_TCSETPGRP_METHODDEF
12177 OS_OPEN_METHODDEF
12178 OS_CLOSE_METHODDEF
12179 OS_CLOSERANGE_METHODDEF
12180 OS_DEVICE_ENCODING_METHODDEF
12181 OS_DUP_METHODDEF
12182 OS_DUP2_METHODDEF
12183 OS_LOCKF_METHODDEF
12184 OS_LSEEK_METHODDEF
12185 OS_READ_METHODDEF
12186 OS_READV_METHODDEF
12187 OS_PREAD_METHODDEF
12188 OS_WRITE_METHODDEF
12189 OS_WRITEV_METHODDEF
12190 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012191#ifdef HAVE_SENDFILE
12192 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12193 posix_sendfile__doc__},
12194#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012195 OS_FSTAT_METHODDEF
12196 OS_ISATTY_METHODDEF
12197 OS_PIPE_METHODDEF
12198 OS_PIPE2_METHODDEF
12199 OS_MKFIFO_METHODDEF
12200 OS_MKNOD_METHODDEF
12201 OS_MAJOR_METHODDEF
12202 OS_MINOR_METHODDEF
12203 OS_MAKEDEV_METHODDEF
12204 OS_FTRUNCATE_METHODDEF
12205 OS_TRUNCATE_METHODDEF
12206 OS_POSIX_FALLOCATE_METHODDEF
12207 OS_POSIX_FADVISE_METHODDEF
12208 OS_PUTENV_METHODDEF
12209 OS_UNSETENV_METHODDEF
12210 OS_STRERROR_METHODDEF
12211 OS_FCHDIR_METHODDEF
12212 OS_FSYNC_METHODDEF
12213 OS_SYNC_METHODDEF
12214 OS_FDATASYNC_METHODDEF
12215 OS_WCOREDUMP_METHODDEF
12216 OS_WIFCONTINUED_METHODDEF
12217 OS_WIFSTOPPED_METHODDEF
12218 OS_WIFSIGNALED_METHODDEF
12219 OS_WIFEXITED_METHODDEF
12220 OS_WEXITSTATUS_METHODDEF
12221 OS_WTERMSIG_METHODDEF
12222 OS_WSTOPSIG_METHODDEF
12223 OS_FSTATVFS_METHODDEF
12224 OS_STATVFS_METHODDEF
12225 OS_CONFSTR_METHODDEF
12226 OS_SYSCONF_METHODDEF
12227 OS_FPATHCONF_METHODDEF
12228 OS_PATHCONF_METHODDEF
12229 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012230 OS__GETFULLPATHNAME_METHODDEF
12231 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012232 OS__GETDISKUSAGE_METHODDEF
12233 OS__GETFINALPATHNAME_METHODDEF
12234 OS__GETVOLUMEPATHNAME_METHODDEF
12235 OS_GETLOADAVG_METHODDEF
12236 OS_URANDOM_METHODDEF
12237 OS_SETRESUID_METHODDEF
12238 OS_SETRESGID_METHODDEF
12239 OS_GETRESUID_METHODDEF
12240 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012241
Larry Hastings2f936352014-08-05 14:04:04 +100012242 OS_GETXATTR_METHODDEF
12243 OS_SETXATTR_METHODDEF
12244 OS_REMOVEXATTR_METHODDEF
12245 OS_LISTXATTR_METHODDEF
12246
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012247#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12248 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12249#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012250 OS_CPU_COUNT_METHODDEF
12251 OS_GET_INHERITABLE_METHODDEF
12252 OS_SET_INHERITABLE_METHODDEF
12253 OS_GET_HANDLE_INHERITABLE_METHODDEF
12254 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012255#ifndef MS_WINDOWS
12256 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12257 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12258#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012259 {"scandir", (PyCFunction)posix_scandir,
12260 METH_VARARGS | METH_KEYWORDS,
12261 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012262 OS_FSPATH_METHODDEF
Victor Stinner9b1f4742016-09-06 16:18:52 -070012263 OS_GETRANDOM_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012264 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012265};
12266
12267
Brian Curtin52173d42010-12-02 18:29:18 +000012268#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012269static int
Brian Curtin52173d42010-12-02 18:29:18 +000012270enable_symlink()
12271{
12272 HANDLE tok;
12273 TOKEN_PRIVILEGES tok_priv;
12274 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012275
12276 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012277 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012278
12279 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012280 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012281
12282 tok_priv.PrivilegeCount = 1;
12283 tok_priv.Privileges[0].Luid = luid;
12284 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12285
12286 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12287 sizeof(TOKEN_PRIVILEGES),
12288 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012289 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012290
Brian Curtin3b4499c2010-12-28 14:31:47 +000012291 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12292 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012293}
12294#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12295
Barry Warsaw4a342091996-12-19 23:50:02 +000012296static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012297all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012298{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012299#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012300 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012301#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012302#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012303 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012304#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012305#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012306 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012307#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012308#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012309 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012310#endif
Fred Drakec9680921999-12-13 16:37:25 +000012311#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012312 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012313#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012314#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012315 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012316#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012317#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012318 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012319#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012320#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012321 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012322#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012323#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012324 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012325#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012326#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012327 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012328#endif
12329#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012330 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012331#endif
12332#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012333 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012334#endif
12335#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012336 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012337#endif
12338#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012339 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012340#endif
12341#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012342 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012343#endif
12344#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012345 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012346#endif
12347#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012348 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012349#endif
12350#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012351 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012352#endif
12353#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012354 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012355#endif
12356#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012357 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012358#endif
12359#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012360 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012361#endif
12362#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012363 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012364#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012365#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012366 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012367#endif
12368#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012369 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012370#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012371#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012372 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012373#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012374#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012375 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012376#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012377#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012378#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012379 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012380#endif
12381#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012382 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012383#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012384#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012385#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012386 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012387#endif
12388#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012389 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012390#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012391#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012392 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012393#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012394#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012395 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012396#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012397#ifdef O_TMPFILE
12398 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12399#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012400#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012401 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012402#endif
12403#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012404 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012405#endif
12406#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012407 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012408#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012409#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012410 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012411#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012412#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012413 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012414#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012415
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012416
Jesus Cea94363612012-06-22 18:32:07 +020012417#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012419#endif
12420#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012422#endif
12423
Tim Peters5aa91602002-01-30 05:46:57 +000012424/* MS Windows */
12425#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012426 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012428#endif
12429#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012430 /* Optimize for short life (keep in memory). */
12431 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012433#endif
12434#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012435 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012437#endif
12438#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012439 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012441#endif
12442#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012443 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012445#endif
12446
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012447/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012448#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012449 /* Send a SIGIO signal whenever input or output
12450 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012452#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012453#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012454 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012456#endif
12457#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012458 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012460#endif
12461#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012462 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012463 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012464#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012465#ifdef O_NOLINKS
12466 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012468#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012469#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012470 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012472#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012473
Victor Stinner8c62be82010-05-06 00:08:46 +000012474 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012475#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012477#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012478#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012480#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012481#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012483#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012484#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012486#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012487#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012489#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012490#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012492#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012493#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012494 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012495#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012496#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012498#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012499#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012501#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012502#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012503 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012504#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012505#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012507#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012508#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012509 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012510#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012511#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012512 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012513#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012514#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012516#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012517#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012518 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012519#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012520#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012522#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012523#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012525#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012526
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012527 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012528#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012530#endif /* ST_RDONLY */
12531#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012532 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012533#endif /* ST_NOSUID */
12534
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012535 /* GNU extensions */
12536#ifdef ST_NODEV
12537 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12538#endif /* ST_NODEV */
12539#ifdef ST_NOEXEC
12540 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12541#endif /* ST_NOEXEC */
12542#ifdef ST_SYNCHRONOUS
12543 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12544#endif /* ST_SYNCHRONOUS */
12545#ifdef ST_MANDLOCK
12546 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12547#endif /* ST_MANDLOCK */
12548#ifdef ST_WRITE
12549 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12550#endif /* ST_WRITE */
12551#ifdef ST_APPEND
12552 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12553#endif /* ST_APPEND */
12554#ifdef ST_NOATIME
12555 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12556#endif /* ST_NOATIME */
12557#ifdef ST_NODIRATIME
12558 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12559#endif /* ST_NODIRATIME */
12560#ifdef ST_RELATIME
12561 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12562#endif /* ST_RELATIME */
12563
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012564 /* FreeBSD sendfile() constants */
12565#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012567#endif
12568#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012569 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012570#endif
12571#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012573#endif
12574
Ross Lagerwall7807c352011-03-17 20:20:30 +020012575 /* constants for posix_fadvise */
12576#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012577 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012578#endif
12579#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012580 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012581#endif
12582#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012583 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012584#endif
12585#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012587#endif
12588#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012589 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012590#endif
12591#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012592 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012593#endif
12594
12595 /* constants for waitid */
12596#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12598 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12599 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012600#endif
12601#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012603#endif
12604#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012606#endif
12607#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012609#endif
12610#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012612#endif
12613#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012615#endif
12616#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012618#endif
12619#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012621#endif
12622
12623 /* constants for lockf */
12624#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012626#endif
12627#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012629#endif
12630#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012632#endif
12633#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012635#endif
12636
Guido van Rossum246bc171999-02-01 23:54:31 +000012637#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12639 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12640 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12641 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12642 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012643#endif
12644
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012645#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012646#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012648#endif
12649#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012651#endif
12652#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012654#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012655#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012657#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012658#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012660#endif
12661#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012663#endif
12664#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012666#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012667#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012669#endif
12670#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012672#endif
12673#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012675#endif
12676#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012678#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012679#endif
12680
Benjamin Peterson9428d532011-09-14 11:45:52 -040012681#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012682 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12683 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12684 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012685#endif
12686
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012687#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012689#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012690#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012692#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012693#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012695#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012696#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012698#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012699#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012701#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012702#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012704#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012705#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012707#endif
12708
Victor Stinner9b1f4742016-09-06 16:18:52 -070012709#ifdef HAVE_GETRANDOM_SYSCALL
12710 if (PyModule_AddIntMacro(m, GRND_RANDOM)) return -1;
12711 if (PyModule_AddIntMacro(m, GRND_NONBLOCK)) return -1;
12712#endif
12713
Victor Stinner8c62be82010-05-06 00:08:46 +000012714 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012715}
12716
12717
Martin v. Löwis1a214512008-06-11 05:26:20 +000012718static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012719 PyModuleDef_HEAD_INIT,
12720 MODNAME,
12721 posix__doc__,
12722 -1,
12723 posix_methods,
12724 NULL,
12725 NULL,
12726 NULL,
12727 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012728};
12729
12730
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012731static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012732
12733#ifdef HAVE_FACCESSAT
12734 "HAVE_FACCESSAT",
12735#endif
12736
12737#ifdef HAVE_FCHDIR
12738 "HAVE_FCHDIR",
12739#endif
12740
12741#ifdef HAVE_FCHMOD
12742 "HAVE_FCHMOD",
12743#endif
12744
12745#ifdef HAVE_FCHMODAT
12746 "HAVE_FCHMODAT",
12747#endif
12748
12749#ifdef HAVE_FCHOWN
12750 "HAVE_FCHOWN",
12751#endif
12752
Larry Hastings00964ed2013-08-12 13:49:30 -040012753#ifdef HAVE_FCHOWNAT
12754 "HAVE_FCHOWNAT",
12755#endif
12756
Larry Hastings9cf065c2012-06-22 16:30:09 -070012757#ifdef HAVE_FEXECVE
12758 "HAVE_FEXECVE",
12759#endif
12760
12761#ifdef HAVE_FDOPENDIR
12762 "HAVE_FDOPENDIR",
12763#endif
12764
Georg Brandl306336b2012-06-24 12:55:33 +020012765#ifdef HAVE_FPATHCONF
12766 "HAVE_FPATHCONF",
12767#endif
12768
Larry Hastings9cf065c2012-06-22 16:30:09 -070012769#ifdef HAVE_FSTATAT
12770 "HAVE_FSTATAT",
12771#endif
12772
12773#ifdef HAVE_FSTATVFS
12774 "HAVE_FSTATVFS",
12775#endif
12776
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012777#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012778 "HAVE_FTRUNCATE",
12779#endif
12780
Larry Hastings9cf065c2012-06-22 16:30:09 -070012781#ifdef HAVE_FUTIMENS
12782 "HAVE_FUTIMENS",
12783#endif
12784
12785#ifdef HAVE_FUTIMES
12786 "HAVE_FUTIMES",
12787#endif
12788
12789#ifdef HAVE_FUTIMESAT
12790 "HAVE_FUTIMESAT",
12791#endif
12792
12793#ifdef HAVE_LINKAT
12794 "HAVE_LINKAT",
12795#endif
12796
12797#ifdef HAVE_LCHFLAGS
12798 "HAVE_LCHFLAGS",
12799#endif
12800
12801#ifdef HAVE_LCHMOD
12802 "HAVE_LCHMOD",
12803#endif
12804
12805#ifdef HAVE_LCHOWN
12806 "HAVE_LCHOWN",
12807#endif
12808
12809#ifdef HAVE_LSTAT
12810 "HAVE_LSTAT",
12811#endif
12812
12813#ifdef HAVE_LUTIMES
12814 "HAVE_LUTIMES",
12815#endif
12816
12817#ifdef HAVE_MKDIRAT
12818 "HAVE_MKDIRAT",
12819#endif
12820
12821#ifdef HAVE_MKFIFOAT
12822 "HAVE_MKFIFOAT",
12823#endif
12824
12825#ifdef HAVE_MKNODAT
12826 "HAVE_MKNODAT",
12827#endif
12828
12829#ifdef HAVE_OPENAT
12830 "HAVE_OPENAT",
12831#endif
12832
12833#ifdef HAVE_READLINKAT
12834 "HAVE_READLINKAT",
12835#endif
12836
12837#ifdef HAVE_RENAMEAT
12838 "HAVE_RENAMEAT",
12839#endif
12840
12841#ifdef HAVE_SYMLINKAT
12842 "HAVE_SYMLINKAT",
12843#endif
12844
12845#ifdef HAVE_UNLINKAT
12846 "HAVE_UNLINKAT",
12847#endif
12848
12849#ifdef HAVE_UTIMENSAT
12850 "HAVE_UTIMENSAT",
12851#endif
12852
12853#ifdef MS_WINDOWS
12854 "MS_WINDOWS",
12855#endif
12856
12857 NULL
12858};
12859
12860
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012861PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012862INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012863{
Victor Stinner8c62be82010-05-06 00:08:46 +000012864 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012865 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012866 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012867
Brian Curtin52173d42010-12-02 18:29:18 +000012868#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012869 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012870#endif
12871
Victor Stinner8c62be82010-05-06 00:08:46 +000012872 m = PyModule_Create(&posixmodule);
12873 if (m == NULL)
12874 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012875
Victor Stinner8c62be82010-05-06 00:08:46 +000012876 /* Initialize environ dictionary */
12877 v = convertenviron();
12878 Py_XINCREF(v);
12879 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12880 return NULL;
12881 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012882
Victor Stinner8c62be82010-05-06 00:08:46 +000012883 if (all_ins(m))
12884 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012885
Victor Stinner8c62be82010-05-06 00:08:46 +000012886 if (setup_confname_tables(m))
12887 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012888
Victor Stinner8c62be82010-05-06 00:08:46 +000012889 Py_INCREF(PyExc_OSError);
12890 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012891
Guido van Rossumb3d39562000-01-31 18:41:26 +000012892#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012893 if (posix_putenv_garbage == NULL)
12894 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012895#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012896
Victor Stinner8c62be82010-05-06 00:08:46 +000012897 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012898#if defined(HAVE_WAITID) && !defined(__APPLE__)
12899 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012900 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12901 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012902#endif
12903
Christian Heimes25827622013-10-12 01:27:08 +020012904 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012905 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12906 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12907 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012908 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12909 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012910 structseq_new = StatResultType.tp_new;
12911 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012912
Christian Heimes25827622013-10-12 01:27:08 +020012913 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012914 if (PyStructSequence_InitType2(&StatVFSResultType,
12915 &statvfs_result_desc) < 0)
12916 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012917#ifdef NEED_TICKS_PER_SECOND
12918# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012919 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012920# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012921 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012922# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012923 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012924# endif
12925#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012926
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012927#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012928 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012929 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12930 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012931 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012932#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012933
12934 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012935 if (PyStructSequence_InitType2(&TerminalSizeType,
12936 &TerminalSize_desc) < 0)
12937 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012938
12939 /* initialize scandir types */
12940 if (PyType_Ready(&ScandirIteratorType) < 0)
12941 return NULL;
12942 if (PyType_Ready(&DirEntryType) < 0)
12943 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012944 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020012945#if defined(HAVE_WAITID) && !defined(__APPLE__)
12946 Py_INCREF((PyObject*) &WaitidResultType);
12947 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
12948#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000012949 Py_INCREF((PyObject*) &StatResultType);
12950 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
12951 Py_INCREF((PyObject*) &StatVFSResultType);
12952 PyModule_AddObject(m, "statvfs_result",
12953 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012954
12955#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012956 Py_INCREF(&SchedParamType);
12957 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050012958#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000012959
Larry Hastings605a62d2012-06-24 04:33:36 -070012960 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012961 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
12962 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012963 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
12964
12965 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012966 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
12967 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070012968 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
12969
Thomas Wouters477c8d52006-05-27 19:21:47 +000012970#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000012971 /*
12972 * Step 2 of weak-linking support on Mac OS X.
12973 *
12974 * The code below removes functions that are not available on the
12975 * currently active platform.
12976 *
12977 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070012978 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 * OSX 10.4.
12980 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000012981#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 if (fstatvfs == NULL) {
12983 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
12984 return NULL;
12985 }
12986 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012987#endif /* HAVE_FSTATVFS */
12988
12989#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000012990 if (statvfs == NULL) {
12991 if (PyObject_DelAttrString(m, "statvfs") == -1) {
12992 return NULL;
12993 }
12994 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000012995#endif /* HAVE_STATVFS */
12996
12997# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000012998 if (lchown == NULL) {
12999 if (PyObject_DelAttrString(m, "lchown") == -1) {
13000 return NULL;
13001 }
13002 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013003#endif /* HAVE_LCHOWN */
13004
13005
13006#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013007
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013008 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013009 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13010
Larry Hastings6fe20b32012-04-19 15:07:49 -070013011 billion = PyLong_FromLong(1000000000);
13012 if (!billion)
13013 return NULL;
13014
Larry Hastings9cf065c2012-06-22 16:30:09 -070013015 /* suppress "function not used" warnings */
13016 {
13017 int ignored;
13018 fd_specified("", -1);
13019 follow_symlinks_specified("", 1);
13020 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13021 dir_fd_converter(Py_None, &ignored);
13022 dir_fd_unavailable(Py_None, &ignored);
13023 }
13024
13025 /*
13026 * provide list of locally available functions
13027 * so os.py can populate support_* lists
13028 */
13029 list = PyList_New(0);
13030 if (!list)
13031 return NULL;
13032 for (trace = have_functions; *trace; trace++) {
13033 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13034 if (!unicode)
13035 return NULL;
13036 if (PyList_Append(list, unicode))
13037 return NULL;
13038 Py_DECREF(unicode);
13039 }
13040 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013041
13042 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013043 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013044
13045 initialized = 1;
13046
Victor Stinner8c62be82010-05-06 00:08:46 +000013047 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013048}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013049
13050#ifdef __cplusplus
13051}
13052#endif