blob: f9693e8d579a3401e9266171a0c1d8e2e9513ec1 [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
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100136#if defined(MS_WINDOWS)
137# define TERMSIZE_USE_CONIO
138#elif defined(HAVE_SYS_IOCTL_H)
139# include <sys/ioctl.h>
140# if defined(HAVE_TERMIOS_H)
141# include <termios.h>
142# endif
143# if defined(TIOCGWINSZ)
144# define TERMSIZE_USE_IOCTL
145# endif
146#endif /* MS_WINDOWS */
147
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000148/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000149/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#include <process.h>
154#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000156#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000157#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#define HAVE_EXECV 1
160#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SYSTEM 1
162#define HAVE_CWAIT 1
163#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000164#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000165#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166/* Unix functions that the configure script doesn't check for */
167#define HAVE_EXECV 1
168#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000170#define HAVE_FORK1 1
171#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_GETEGID 1
173#define HAVE_GETEUID 1
174#define HAVE_GETGID 1
175#define HAVE_GETPPID 1
176#define HAVE_GETUID 1
177#define HAVE_KILL 1
178#define HAVE_OPENDIR 1
179#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000182#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000184#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000185
Victor Stinnera2f7c002012-02-08 03:36:25 +0100186
Larry Hastings61272b72014-01-07 12:41:53 -0800187/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000188# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800189module os
Larry Hastings61272b72014-01-07 12:41:53 -0800190[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000191/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100192
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000194
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000195#if defined(__sgi)&&_COMPILER_VERSION>=700
196/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
197 (default) */
198extern char *ctermid_r(char *);
199#endif
200
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000201#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000205#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#endif
211#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(char *);
213extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int chdir(const char *);
216extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000217#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000219/*#ifdef HAVE_FCHMOD
220extern int fchmod(int, mode_t);
221#endif*/
222/*#ifdef HAVE_LCHMOD
223extern int lchmod(const char *, mode_t);
224#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chown(const char *, uid_t, gid_t);
226extern char *getcwd(char *, int);
227extern char *strerror(int);
228extern int link(const char *, const char *);
229extern int rename(const char *, const char *);
230extern int stat(const char *, struct stat *);
231extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000234#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_UTIME_H
243#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000246#ifdef HAVE_SYS_UTIME_H
247#include <sys/utime.h>
248#define HAVE_UTIME_H /* pretend we do for the rest of this file */
249#endif /* HAVE_SYS_UTIME_H */
250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_SYS_TIMES_H
252#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_PARAM_H
256#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_UTSNAME_H
260#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000267#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#include <direct.h>
269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000285#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
292#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100304#ifndef IO_REPARSE_TAG_MOUNT_POINT
305#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
306#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000307#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000308#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000309#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000310#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000311#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000312#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
313#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000314static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000315#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000316#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000317
Tim Petersbc2e10e2002-03-03 23:17:02 +0000318#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319#if defined(PATH_MAX) && PATH_MAX > 1024
320#define MAXPATHLEN PATH_MAX
321#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000322#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#endif /* MAXPATHLEN */
325
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000326#ifdef UNION_WAIT
327/* Emulate some macros on systems that have a union instead of macros */
328
329#ifndef WIFEXITED
330#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
331#endif
332
333#ifndef WEXITSTATUS
334#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
335#endif
336
337#ifndef WTERMSIG
338#define WTERMSIG(u_wait) ((u_wait).w_termsig)
339#endif
340
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000341#define WAIT_TYPE union wait
342#define WAIT_STATUS_INT(s) (s.w_status)
343
344#else /* !UNION_WAIT */
345#define WAIT_TYPE int
346#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#endif /* UNION_WAIT */
348
Greg Wardb48bc172000-03-01 21:51:56 +0000349/* Don't use the "_r" form if we don't need it (also, won't have a
350 prototype for it, at least on Solaris -- maybe others as well?). */
351#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
352#define USE_CTERMID_R
353#endif
354
Fred Drake699f3522000-06-29 21:12:41 +0000355/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000356#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000357#undef FSTAT
358#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200359#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000360# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700361# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200362# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800363# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000364#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700366# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define FSTAT fstat
368# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000369#endif
370
Tim Peters11b23062003-04-23 02:39:17 +0000371#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#include <sys/mkdev.h>
373#else
374#if defined(MAJOR_IN_SYSMACROS)
375#include <sys/sysmacros.h>
376#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000377#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
378#include <sys/mkdev.h>
379#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000380#endif
Fred Drake699f3522000-06-29 21:12:41 +0000381
Victor Stinner6edddfa2013-11-24 19:22:57 +0100382#define DWORD_MAX 4294967295U
383
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200384#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100385#define INITFUNC PyInit_nt
386#define MODNAME "nt"
387#else
388#define INITFUNC PyInit_posix
389#define MODNAME "posix"
390#endif
391
392#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393/* defined in fileutils.c */
394PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
395PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
396 ULONG, struct _Py_stat_struct *);
397#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700398
399#ifdef MS_WINDOWS
400static int
401win32_warn_bytes_api()
402{
403 return PyErr_WarnEx(PyExc_DeprecationWarning,
404 "The Windows bytes API has been deprecated, "
405 "use Unicode filenames instead",
406 1);
407}
408#endif
409
410
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200411#ifndef MS_WINDOWS
412PyObject *
413_PyLong_FromUid(uid_t uid)
414{
415 if (uid == (uid_t)-1)
416 return PyLong_FromLong(-1);
417 return PyLong_FromUnsignedLong(uid);
418}
419
420PyObject *
421_PyLong_FromGid(gid_t gid)
422{
423 if (gid == (gid_t)-1)
424 return PyLong_FromLong(-1);
425 return PyLong_FromUnsignedLong(gid);
426}
427
428int
429_Py_Uid_Converter(PyObject *obj, void *p)
430{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700431 uid_t uid;
432 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200433 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200434 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700435 unsigned long uresult;
436
437 index = PyNumber_Index(obj);
438 if (index == NULL) {
439 PyErr_Format(PyExc_TypeError,
440 "uid should be integer, not %.200s",
441 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200442 return 0;
443 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444
445 /*
446 * Handling uid_t is complicated for two reasons:
447 * * Although uid_t is (always?) unsigned, it still
448 * accepts -1.
449 * * We don't know its size in advance--it may be
450 * bigger than an int, or it may be smaller than
451 * a long.
452 *
453 * So a bit of defensive programming is in order.
454 * Start with interpreting the value passed
455 * in as a signed long and see if it works.
456 */
457
458 result = PyLong_AsLongAndOverflow(index, &overflow);
459
460 if (!overflow) {
461 uid = (uid_t)result;
462
463 if (result == -1) {
464 if (PyErr_Occurred())
465 goto fail;
466 /* It's a legitimate -1, we're done. */
467 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200468 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700469
470 /* Any other negative number is disallowed. */
471 if (result < 0)
472 goto underflow;
473
474 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200475 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700476 (long)uid != result)
477 goto underflow;
478 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200479 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700480
481 if (overflow < 0)
482 goto underflow;
483
484 /*
485 * Okay, the value overflowed a signed long. If it
486 * fits in an *unsigned* long, it may still be okay,
487 * as uid_t may be unsigned long on this platform.
488 */
489 uresult = PyLong_AsUnsignedLong(index);
490 if (PyErr_Occurred()) {
491 if (PyErr_ExceptionMatches(PyExc_OverflowError))
492 goto overflow;
493 goto fail;
494 }
495
496 uid = (uid_t)uresult;
497
498 /*
499 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
500 * but this value would get interpreted as (uid_t)-1 by chown
501 * and its siblings. That's not what the user meant! So we
502 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100503 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504 */
505 if (uid == (uid_t)-1)
506 goto overflow;
507
508 /* Ensure the value wasn't truncated. */
509 if (sizeof(uid_t) < sizeof(long) &&
510 (unsigned long)uid != uresult)
511 goto overflow;
512 /* fallthrough */
513
514success:
515 Py_DECREF(index);
516 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517 return 1;
518
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700519underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200520 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700521 "uid is less than minimum");
522 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200523
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200525 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 "uid is greater than maximum");
527 /* fallthrough */
528
529fail:
530 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200531 return 0;
532}
533
534int
535_Py_Gid_Converter(PyObject *obj, void *p)
536{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537 gid_t gid;
538 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200539 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200540 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541 unsigned long uresult;
542
543 index = PyNumber_Index(obj);
544 if (index == NULL) {
545 PyErr_Format(PyExc_TypeError,
546 "gid should be integer, not %.200s",
547 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200548 return 0;
549 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550
551 /*
552 * Handling gid_t is complicated for two reasons:
553 * * Although gid_t is (always?) unsigned, it still
554 * accepts -1.
555 * * We don't know its size in advance--it may be
556 * bigger than an int, or it may be smaller than
557 * a long.
558 *
559 * So a bit of defensive programming is in order.
560 * Start with interpreting the value passed
561 * in as a signed long and see if it works.
562 */
563
564 result = PyLong_AsLongAndOverflow(index, &overflow);
565
566 if (!overflow) {
567 gid = (gid_t)result;
568
569 if (result == -1) {
570 if (PyErr_Occurred())
571 goto fail;
572 /* It's a legitimate -1, we're done. */
573 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575
576 /* Any other negative number is disallowed. */
577 if (result < 0) {
578 goto underflow;
579 }
580
581 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200582 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700583 (long)gid != result)
584 goto underflow;
585 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200586 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700587
588 if (overflow < 0)
589 goto underflow;
590
591 /*
592 * Okay, the value overflowed a signed long. If it
593 * fits in an *unsigned* long, it may still be okay,
594 * as gid_t may be unsigned long on this platform.
595 */
596 uresult = PyLong_AsUnsignedLong(index);
597 if (PyErr_Occurred()) {
598 if (PyErr_ExceptionMatches(PyExc_OverflowError))
599 goto overflow;
600 goto fail;
601 }
602
603 gid = (gid_t)uresult;
604
605 /*
606 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
607 * but this value would get interpreted as (gid_t)-1 by chown
608 * and its siblings. That's not what the user meant! So we
609 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100610 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611 */
612 if (gid == (gid_t)-1)
613 goto overflow;
614
615 /* Ensure the value wasn't truncated. */
616 if (sizeof(gid_t) < sizeof(long) &&
617 (unsigned long)gid != uresult)
618 goto overflow;
619 /* fallthrough */
620
621success:
622 Py_DECREF(index);
623 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 return 1;
625
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700626underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200627 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700628 "gid is less than minimum");
629 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700631overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700633 "gid is greater than maximum");
634 /* fallthrough */
635
636fail:
637 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200638 return 0;
639}
640#endif /* MS_WINDOWS */
641
642
Gregory P. Smith702dada2015-01-28 16:07:52 -0800643#ifdef HAVE_LONG_LONG
644# define _PyLong_FromDev PyLong_FromLongLong
645#else
646# define _PyLong_FromDev PyLong_FromLong
647#endif
648
649
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200650#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
651static int
652_Py_Dev_Converter(PyObject *obj, void *p)
653{
654#ifdef HAVE_LONG_LONG
655 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
656#else
657 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
658#endif
659 if (PyErr_Occurred())
660 return 0;
661 return 1;
662}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800663#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200664
665
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400667/*
668 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
669 * without the int cast, the value gets interpreted as uint (4291925331),
670 * which doesn't play nicely with all the initializer lines in this file that
671 * look like this:
672 * int dir_fd = DEFAULT_DIR_FD;
673 */
674#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700675#else
676#define DEFAULT_DIR_FD (-100)
677#endif
678
679static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300680_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200681{
682 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700683 long long_value;
684
685 PyObject *index = PyNumber_Index(o);
686 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700687 return 0;
688 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300690 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700691 long_value = PyLong_AsLongAndOverflow(index, &overflow);
692 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300693 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700697 return 0;
698 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200699 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700700 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700701 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700702 return 0;
703 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700704
Larry Hastings9cf065c2012-06-22 16:30:09 -0700705 *p = (int)long_value;
706 return 1;
707}
708
709static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200710dir_fd_converter(PyObject *o, void *p)
711{
712 if (o == Py_None) {
713 *(int *)p = DEFAULT_DIR_FD;
714 return 1;
715 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300716 else if (PyIndex_Check(o)) {
717 return _fd_converter(o, (int *)p);
718 }
719 else {
720 PyErr_Format(PyExc_TypeError,
721 "argument should be integer or None, not %.200s",
722 Py_TYPE(o)->tp_name);
723 return 0;
724 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700725}
726
727
Larry Hastings9cf065c2012-06-22 16:30:09 -0700728/*
729 * A PyArg_ParseTuple "converter" function
730 * that handles filesystem paths in the manner
731 * preferred by the os module.
732 *
733 * path_converter accepts (Unicode) strings and their
734 * subclasses, and bytes and their subclasses. What
735 * it does with the argument depends on the platform:
736 *
737 * * On Windows, if we get a (Unicode) string we
738 * extract the wchar_t * and return it; if we get
739 * bytes we extract the char * and return that.
740 *
741 * * On all other platforms, strings are encoded
742 * to bytes using PyUnicode_FSConverter, then we
743 * extract the char * from the bytes object and
744 * return that.
745 *
746 * path_converter also optionally accepts signed
747 * integers (representing open file descriptors) instead
748 * of path strings.
749 *
750 * Input fields:
751 * path.nullable
752 * If nonzero, the path is permitted to be None.
753 * path.allow_fd
754 * If nonzero, the path is permitted to be a file handle
755 * (a signed int) instead of a string.
756 * path.function_name
757 * If non-NULL, path_converter will use that as the name
758 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700759 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760 * path.argument_name
761 * If non-NULL, path_converter will use that as the name
762 * of the parameter in error messages.
763 * (If path.argument_name is NULL it uses "path".)
764 *
765 * Output fields:
766 * path.wide
767 * Points to the path if it was expressed as Unicode
768 * and was not encoded. (Only used on Windows.)
769 * path.narrow
770 * Points to the path if it was expressed as bytes,
771 * or it was Unicode and was encoded to bytes.
772 * path.fd
773 * Contains a file descriptor if path.accept_fd was true
774 * and the caller provided a signed integer instead of any
775 * sort of string.
776 *
777 * WARNING: if your "path" parameter is optional, and is
778 * unspecified, path_converter will never get called.
779 * So if you set allow_fd, you *MUST* initialize path.fd = -1
780 * yourself!
781 * path.length
782 * The length of the path in characters, if specified as
783 * a string.
784 * path.object
785 * The original object passed in.
786 * path.cleanup
787 * For internal use only. May point to a temporary object.
788 * (Pay no attention to the man behind the curtain.)
789 *
790 * At most one of path.wide or path.narrow will be non-NULL.
791 * If path was None and path.nullable was set,
792 * or if path was an integer and path.allow_fd was set,
793 * both path.wide and path.narrow will be NULL
794 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200795 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 * path_converter takes care to not write to the path_t
797 * unless it's successful. However it must reset the
798 * "cleanup" field each time it's called.
799 *
800 * Use as follows:
801 * path_t path;
802 * memset(&path, 0, sizeof(path));
803 * PyArg_ParseTuple(args, "O&", path_converter, &path);
804 * // ... use values from path ...
805 * path_cleanup(&path);
806 *
807 * (Note that if PyArg_Parse fails you don't need to call
808 * path_cleanup(). However it is safe to do so.)
809 */
810typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100811 const char *function_name;
812 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813 int nullable;
814 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300815 const wchar_t *wide;
816 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817 int fd;
818 Py_ssize_t length;
819 PyObject *object;
820 PyObject *cleanup;
821} path_t;
822
Larry Hastings2f936352014-08-05 14:04:04 +1000823#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
824 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700825
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826static void
827path_cleanup(path_t *path) {
828 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200829 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700830 }
831}
832
833static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300834path_converter(PyObject *o, void *p)
835{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700836 path_t *path = (path_t *)p;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700837 PyObject *bytes, *to_cleanup = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838 Py_ssize_t length;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700839 int is_index, is_buffer, is_bytes, is_unicode;
840 /* Default to failure, forcing explicit signaling of succcess. */
841 int ret = 0;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300842 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700843
844#define FORMAT_EXCEPTION(exc, fmt) \
845 PyErr_Format(exc, "%s%s" fmt, \
846 path->function_name ? path->function_name : "", \
847 path->function_name ? ": " : "", \
848 path->argument_name ? path->argument_name : "path")
849
850 /* Py_CLEANUP_SUPPORTED support */
851 if (o == NULL) {
852 path_cleanup(path);
853 return 1;
854 }
855
Brett Cannon3f9183b2016-08-26 14:44:48 -0700856 /* Ensure it's always safe to call path_cleanup(). */
Larry Hastings9cf065c2012-06-22 16:30:09 -0700857 path->cleanup = NULL;
858
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300859 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700860 path->wide = NULL;
861 path->narrow = NULL;
862 path->length = 0;
863 path->object = o;
864 path->fd = -1;
865 return 1;
866 }
867
Brett Cannon3f9183b2016-08-26 14:44:48 -0700868 /* Only call this here so that we don't treat the return value of
869 os.fspath() as an fd or buffer. */
870 is_index = path->allow_fd && PyIndex_Check(o);
871 is_buffer = PyObject_CheckBuffer(o);
872 is_bytes = PyBytes_Check(o);
873 is_unicode = PyUnicode_Check(o);
874
875 if (!is_index && !is_buffer && !is_unicode && !is_bytes) {
876 /* Inline PyOS_FSPath() for better error messages. */
877 _Py_IDENTIFIER(__fspath__);
878 PyObject *func = NULL;
879
880 func = _PyObject_LookupSpecial(o, &PyId___fspath__);
881 if (NULL == func) {
882 goto error_exit;
883 }
884
885 o = to_cleanup = PyObject_CallFunctionObjArgs(func, NULL);
886 Py_DECREF(func);
887 if (NULL == o) {
888 goto error_exit;
889 }
890 else if (PyUnicode_Check(o)) {
891 is_unicode = 1;
892 }
893 else if (PyBytes_Check(o)) {
894 is_bytes = 1;
895 }
896 else {
897 goto error_exit;
898 }
899 }
900
901 if (is_unicode) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700902#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300903 const wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100904
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300905 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100906 if (!wide) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700907 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700908 }
Victor Stinner59799a82013-11-13 14:17:30 +0100909 if (length > 32767) {
910 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700911 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700912 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300913 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300914 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Brett Cannon3f9183b2016-08-26 14:44:48 -0700915 goto exit;
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300916 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700917
918 path->wide = wide;
919 path->narrow = NULL;
920 path->length = length;
921 path->object = o;
922 path->fd = -1;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700923 ret = 1;
924 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300926 if (!PyUnicode_FSConverter(o, &bytes)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700927 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300928 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929#endif
930 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700931 else if (is_bytes) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300932#ifdef MS_WINDOWS
933 if (win32_warn_bytes_api()) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700934 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300935 }
936#endif
937 bytes = o;
938 Py_INCREF(bytes);
939 }
Brett Cannon3f9183b2016-08-26 14:44:48 -0700940 else if (is_buffer) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300941 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
942 "%s%s%s should be %s, not %.200s",
943 path->function_name ? path->function_name : "",
944 path->function_name ? ": " : "",
945 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700946 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
947 "integer or None" :
948 path->allow_fd ? "string, bytes, os.PathLike or integer" :
949 path->nullable ? "string, bytes, os.PathLike or None" :
950 "string, bytes or os.PathLike",
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300951 Py_TYPE(o)->tp_name)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700952 goto exit;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300953 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300954#ifdef MS_WINDOWS
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300955 if (win32_warn_bytes_api()) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700956 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300957 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300958#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300959 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960 if (!bytes) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700961 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700962 }
963 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300964 else if (path->allow_fd && PyIndex_Check(o)) {
965 if (!_fd_converter(o, &path->fd)) {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700966 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300967 }
968 path->wide = NULL;
969 path->narrow = NULL;
970 path->length = 0;
971 path->object = o;
Brett Cannon3f9183b2016-08-26 14:44:48 -0700972 ret = 1;
973 goto exit;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300974 }
975 else {
Brett Cannon3f9183b2016-08-26 14:44:48 -0700976 error_exit:
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300977 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
978 path->function_name ? path->function_name : "",
979 path->function_name ? ": " : "",
980 path->argument_name ? path->argument_name : "path",
Brett Cannon3f9183b2016-08-26 14:44:48 -0700981 path->allow_fd && path->nullable ? "string, bytes, os.PathLike, "
982 "integer or None" :
983 path->allow_fd ? "string, bytes, os.PathLike or integer" :
984 path->nullable ? "string, bytes, os.PathLike or None" :
985 "string, bytes or os.PathLike",
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300986 Py_TYPE(o)->tp_name);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700987 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700988 }
989
Larry Hastings9cf065c2012-06-22 16:30:09 -0700990 length = PyBytes_GET_SIZE(bytes);
991#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100992 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700993 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
994 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -0700995 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700996 }
997#endif
998
999 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +02001000 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +03001001 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001003 goto exit;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001004 }
1005
1006 path->wide = NULL;
1007 path->narrow = narrow;
1008 path->length = length;
1009 path->object = o;
1010 path->fd = -1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001011 if (bytes == o) {
1012 Py_DECREF(bytes);
Brett Cannon3f9183b2016-08-26 14:44:48 -07001013 ret = 1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001014 }
1015 else {
1016 path->cleanup = bytes;
Brett Cannon3f9183b2016-08-26 14:44:48 -07001017 ret = Py_CLEANUP_SUPPORTED;
Serhiy Storchakad73c3182016-08-06 23:22:08 +03001018 }
Brett Cannon3f9183b2016-08-26 14:44:48 -07001019 exit:
1020 Py_XDECREF(to_cleanup);
1021 return ret;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001022}
1023
1024static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001025argument_unavailable_error(const char *function_name, const char *argument_name)
1026{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 PyErr_Format(PyExc_NotImplementedError,
1028 "%s%s%s unavailable on this platform",
1029 (function_name != NULL) ? function_name : "",
1030 (function_name != NULL) ? ": ": "",
1031 argument_name);
1032}
1033
1034static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001035dir_fd_unavailable(PyObject *o, void *p)
1036{
1037 int dir_fd;
1038 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -07001039 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +02001040 if (dir_fd != DEFAULT_DIR_FD) {
1041 argument_unavailable_error(NULL, "dir_fd");
1042 return 0;
1043 }
1044 *(int *)p = dir_fd;
1045 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001046}
1047
1048static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001049fd_specified(const char *function_name, int fd)
1050{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001051 if (fd == -1)
1052 return 0;
1053
1054 argument_unavailable_error(function_name, "fd");
1055 return 1;
1056}
1057
1058static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001059follow_symlinks_specified(const char *function_name, int follow_symlinks)
1060{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001061 if (follow_symlinks)
1062 return 0;
1063
1064 argument_unavailable_error(function_name, "follow_symlinks");
1065 return 1;
1066}
1067
1068static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001069path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1070{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001071 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
1072 PyErr_Format(PyExc_ValueError,
1073 "%s: can't specify dir_fd without matching path",
1074 function_name);
1075 return 1;
1076 }
1077 return 0;
1078}
1079
1080static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001081dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1082{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001083 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1084 PyErr_Format(PyExc_ValueError,
1085 "%s: can't specify both dir_fd and fd",
1086 function_name);
1087 return 1;
1088 }
1089 return 0;
1090}
1091
1092static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001093fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1094 int follow_symlinks)
1095{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001096 if ((fd > 0) && (!follow_symlinks)) {
1097 PyErr_Format(PyExc_ValueError,
1098 "%s: cannot use fd and follow_symlinks together",
1099 function_name);
1100 return 1;
1101 }
1102 return 0;
1103}
1104
1105static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001106dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1107 int follow_symlinks)
1108{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001109 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1110 PyErr_Format(PyExc_ValueError,
1111 "%s: cannot use dir_fd and follow_symlinks together",
1112 function_name);
1113 return 1;
1114 }
1115 return 0;
1116}
1117
Larry Hastings2f936352014-08-05 14:04:04 +10001118#ifdef MS_WINDOWS
1119 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001120#else
Larry Hastings2f936352014-08-05 14:04:04 +10001121 typedef off_t Py_off_t;
1122#endif
1123
1124static int
1125Py_off_t_converter(PyObject *arg, void *addr)
1126{
1127#ifdef HAVE_LARGEFILE_SUPPORT
1128 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1129#else
1130 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001131#endif
1132 if (PyErr_Occurred())
1133 return 0;
1134 return 1;
1135}
Larry Hastings2f936352014-08-05 14:04:04 +10001136
1137static PyObject *
1138PyLong_FromPy_off_t(Py_off_t offset)
1139{
1140#ifdef HAVE_LARGEFILE_SUPPORT
1141 return PyLong_FromLongLong(offset);
1142#else
1143 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001144#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001145}
1146
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001147
Steve Dowerd81431f2015-03-06 14:47:02 -08001148#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1149/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1150 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001151 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001152#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001153#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001154#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001155#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001156#define _NO_CONSOLE_FILENO (intptr_t)-2
1157
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001158/* the special case of checking dup2. The target fd must be in a sensible range */
1159static int
1160_PyVerify_fd_dup2(int fd1, int fd2)
1161{
Victor Stinner8c62be82010-05-06 00:08:46 +00001162 if (!_PyVerify_fd(fd1))
1163 return 0;
1164 if (fd2 == _NO_CONSOLE_FILENO)
1165 return 0;
1166 if ((unsigned)fd2 < _NHANDLE_)
1167 return 1;
1168 else
1169 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001170}
1171#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001172#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001173#endif
1174
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001175#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001176
1177static int
Brian Curtind25aef52011-06-13 15:16:04 -05001178win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001179{
Martin Panter70214ad2016-08-04 02:38:59 +00001180 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1181 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001182 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001183
1184 if (0 == DeviceIoControl(
1185 reparse_point_handle,
1186 FSCTL_GET_REPARSE_POINT,
1187 NULL, 0, /* in buffer */
1188 target_buffer, sizeof(target_buffer),
1189 &n_bytes_returned,
1190 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001191 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001192
1193 if (reparse_tag)
1194 *reparse_tag = rdb->ReparseTag;
1195
Brian Curtind25aef52011-06-13 15:16:04 -05001196 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001197}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001198
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001199#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001200
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001201/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001202#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001203/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001204** environ directly, we must obtain it with _NSGetEnviron(). See also
1205** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001206*/
1207#include <crt_externs.h>
1208static char **environ;
1209#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001210extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001211#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001212
Barry Warsaw53699e91996-12-10 23:23:01 +00001213static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001214convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215{
Victor Stinner8c62be82010-05-06 00:08:46 +00001216 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001217#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001218 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001219#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001221#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001222
Victor Stinner8c62be82010-05-06 00:08:46 +00001223 d = PyDict_New();
1224 if (d == NULL)
1225 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001226#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 if (environ == NULL)
1228 environ = *_NSGetEnviron();
1229#endif
1230#ifdef MS_WINDOWS
1231 /* _wenviron must be initialized in this way if the program is started
1232 through main() instead of wmain(). */
1233 _wgetenv(L"");
1234 if (_wenviron == NULL)
1235 return d;
1236 /* This part ignores errors */
1237 for (e = _wenviron; *e != NULL; e++) {
1238 PyObject *k;
1239 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001240 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001241 if (p == NULL)
1242 continue;
1243 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1244 if (k == NULL) {
1245 PyErr_Clear();
1246 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001247 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001248 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1249 if (v == NULL) {
1250 PyErr_Clear();
1251 Py_DECREF(k);
1252 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001253 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 if (PyDict_GetItem(d, k) == NULL) {
1255 if (PyDict_SetItem(d, k, v) != 0)
1256 PyErr_Clear();
1257 }
1258 Py_DECREF(k);
1259 Py_DECREF(v);
1260 }
1261#else
1262 if (environ == NULL)
1263 return d;
1264 /* This part ignores errors */
1265 for (e = environ; *e != NULL; e++) {
1266 PyObject *k;
1267 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001268 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001269 if (p == NULL)
1270 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001271 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001272 if (k == NULL) {
1273 PyErr_Clear();
1274 continue;
1275 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001276 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001277 if (v == NULL) {
1278 PyErr_Clear();
1279 Py_DECREF(k);
1280 continue;
1281 }
1282 if (PyDict_GetItem(d, k) == NULL) {
1283 if (PyDict_SetItem(d, k, v) != 0)
1284 PyErr_Clear();
1285 }
1286 Py_DECREF(k);
1287 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001288 }
1289#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001291}
1292
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001293/* Set a POSIX-specific error from errno, and return NULL */
1294
Barry Warsawd58d7641998-07-23 16:14:40 +00001295static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001296posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001297{
Victor Stinner8c62be82010-05-06 00:08:46 +00001298 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001299}
Mark Hammondef8b6542001-05-13 08:04:26 +00001300
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001301#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001302static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001303win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001304{
Victor Stinner8c62be82010-05-06 00:08:46 +00001305 /* XXX We should pass the function name along in the future.
1306 (winreg.c also wants to pass the function name.)
1307 This would however require an additional param to the
1308 Windows error object, which is non-trivial.
1309 */
1310 errno = GetLastError();
1311 if (filename)
1312 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1313 else
1314 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001315}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001316
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001317static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001318win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001319{
1320 /* XXX - see win32_error for comments on 'function' */
1321 errno = GetLastError();
1322 if (filename)
1323 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001324 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001325 errno,
1326 filename);
1327 else
1328 return PyErr_SetFromWindowsErr(errno);
1329}
1330
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001331#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001332
Larry Hastings9cf065c2012-06-22 16:30:09 -07001333static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001334path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001335{
1336#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001337 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1338 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001339#else
Victor Stinner292c8352012-10-30 02:17:38 +01001340 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001341#endif
1342}
1343
Larry Hastings31826802013-10-19 00:09:25 -07001344
Larry Hastingsb0827312014-02-09 22:05:19 -08001345static PyObject *
1346path_error2(path_t *path, path_t *path2)
1347{
1348#ifdef MS_WINDOWS
1349 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1350 0, path->object, path2->object);
1351#else
1352 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1353 path->object, path2->object);
1354#endif
1355}
1356
1357
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001358/* POSIX generic methods */
1359
Larry Hastings2f936352014-08-05 14:04:04 +10001360static int
1361fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001362{
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001364 int *pointer = (int *)p;
1365 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001367 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001368 *pointer = fd;
1369 return 1;
1370}
1371
1372static PyObject *
1373posix_fildes_fd(int fd, int (*func)(int))
1374{
1375 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001376 int async_err = 0;
1377
Steve Dower8fc89802015-04-12 00:26:27 -04001378 if (!_PyVerify_fd(fd))
1379 return posix_error();
1380
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001381 do {
1382 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001383 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001384 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001385 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001386 Py_END_ALLOW_THREADS
1387 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1388 if (res != 0)
1389 return (!async_err) ? posix_error() : NULL;
1390 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001391}
Guido van Rossum21142a01999-01-08 21:05:37 +00001392
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001393
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001394#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001395/* This is a reimplementation of the C library's chdir function,
1396 but one that produces Win32 errors instead of DOS error codes.
1397 chdir is essentially a wrapper around SetCurrentDirectory; however,
1398 it also needs to set "magic" environment variables indicating
1399 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001400static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001401win32_chdir(LPCSTR path)
1402{
Victor Stinner75875072013-11-24 19:23:25 +01001403 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001404 int result;
1405 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001406
Victor Stinner8c62be82010-05-06 00:08:46 +00001407 if(!SetCurrentDirectoryA(path))
1408 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001409 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001410 if (!result)
1411 return FALSE;
1412 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001413 than MAX_PATH-1 (not including the final null character). */
1414 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001415 if (strncmp(new_path, "\\\\", 2) == 0 ||
1416 strncmp(new_path, "//", 2) == 0)
1417 /* UNC path, nothing to do. */
1418 return TRUE;
1419 env[1] = new_path[0];
1420 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001421}
1422
1423/* The Unicode version differs from the ANSI version
1424 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001425static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001426win32_wchdir(LPCWSTR path)
1427{
Victor Stinnered537822015-12-13 21:40:26 +01001428 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001429 int result;
1430 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001431
Victor Stinner8c62be82010-05-06 00:08:46 +00001432 if(!SetCurrentDirectoryW(path))
1433 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001434 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001435 if (!result)
1436 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001437 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001438 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001439 if (!new_path) {
1440 SetLastError(ERROR_OUTOFMEMORY);
1441 return FALSE;
1442 }
1443 result = GetCurrentDirectoryW(result, new_path);
1444 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001445 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001446 return FALSE;
1447 }
1448 }
1449 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1450 wcsncmp(new_path, L"//", 2) == 0)
1451 /* UNC path, nothing to do. */
1452 return TRUE;
1453 env[1] = new_path[0];
1454 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001455 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001456 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001457 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001458}
1459#endif
1460
Martin v. Löwis14694662006-02-03 12:54:16 +00001461#ifdef MS_WINDOWS
1462/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1463 - time stamps are restricted to second resolution
1464 - file modification times suffer from forth-and-back conversions between
1465 UTC and local time
1466 Therefore, we implement our own stat, based on the Win32 API directly.
1467*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001468#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001469#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001470
Guido van Rossumd8faa362007-04-27 19:54:29 +00001471static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001472attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001473{
Victor Stinner8c62be82010-05-06 00:08:46 +00001474 HANDLE hFindFile;
1475 WIN32_FIND_DATAA FileData;
1476 hFindFile = FindFirstFileA(pszFile, &FileData);
1477 if (hFindFile == INVALID_HANDLE_VALUE)
1478 return FALSE;
1479 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001480 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001481 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001482 info->dwFileAttributes = FileData.dwFileAttributes;
1483 info->ftCreationTime = FileData.ftCreationTime;
1484 info->ftLastAccessTime = FileData.ftLastAccessTime;
1485 info->ftLastWriteTime = FileData.ftLastWriteTime;
1486 info->nFileSizeHigh = FileData.nFileSizeHigh;
1487 info->nFileSizeLow = FileData.nFileSizeLow;
1488/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1490 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001491 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001492}
1493
Victor Stinner6036e442015-03-08 01:58:04 +01001494static void
1495find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1496 BY_HANDLE_FILE_INFORMATION *info,
1497 ULONG *reparse_tag)
1498{
1499 memset(info, 0, sizeof(*info));
1500 info->dwFileAttributes = pFileData->dwFileAttributes;
1501 info->ftCreationTime = pFileData->ftCreationTime;
1502 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1503 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1504 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1505 info->nFileSizeLow = pFileData->nFileSizeLow;
1506/* info->nNumberOfLinks = 1; */
1507 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1508 *reparse_tag = pFileData->dwReserved0;
1509 else
1510 *reparse_tag = 0;
1511}
1512
Guido van Rossumd8faa362007-04-27 19:54:29 +00001513static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001514attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001515{
Victor Stinner8c62be82010-05-06 00:08:46 +00001516 HANDLE hFindFile;
1517 WIN32_FIND_DATAW FileData;
1518 hFindFile = FindFirstFileW(pszFile, &FileData);
1519 if (hFindFile == INVALID_HANDLE_VALUE)
1520 return FALSE;
1521 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001522 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001523 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001524}
1525
Brian Curtind25aef52011-06-13 15:16:04 -05001526static BOOL
1527get_target_path(HANDLE hdl, wchar_t **target_path)
1528{
1529 int buf_size, result_length;
1530 wchar_t *buf;
1531
1532 /* We have a good handle to the target, use it to determine
1533 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001534 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1535 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001536 if(!buf_size)
1537 return FALSE;
1538
Victor Stinnerc36674a2016-03-16 14:30:16 +01001539 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001540 if (!buf) {
1541 SetLastError(ERROR_OUTOFMEMORY);
1542 return FALSE;
1543 }
1544
Steve Dower2ea51c92015-03-20 21:49:12 -07001545 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001546 buf, buf_size, VOLUME_NAME_DOS);
1547
1548 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001549 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001550 return FALSE;
1551 }
1552
1553 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001554 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001555 return FALSE;
1556 }
1557
1558 buf[result_length] = 0;
1559
1560 *target_path = buf;
1561 return TRUE;
1562}
1563
1564static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001565win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001566 BOOL traverse);
1567static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001568win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001569 BOOL traverse)
1570{
Victor Stinner26de69d2011-06-17 15:15:38 +02001571 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001572 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001574 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001575 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001576 const char *dot;
1577
1578 hFile = CreateFileA(
1579 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001580 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001581 0, /* share mode */
1582 NULL, /* security attributes */
1583 OPEN_EXISTING,
1584 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001585 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1586 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001587 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001588 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1589 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001590 NULL);
1591
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001592 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001593 /* Either the target doesn't exist, or we don't have access to
1594 get a handle to it. If the former, we need to return an error.
1595 If the latter, we can use attributes_from_dir. */
1596 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001597 return -1;
1598 /* Could not get attributes on open file. Fall back to
1599 reading the directory. */
1600 if (!attributes_from_dir(path, &info, &reparse_tag))
1601 /* Very strange. This should not fail now */
1602 return -1;
1603 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1604 if (traverse) {
1605 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001606 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001608 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001610 } else {
1611 if (!GetFileInformationByHandle(hFile, &info)) {
1612 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001613 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001614 }
1615 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001616 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1617 return -1;
1618
1619 /* Close the outer open file handle now that we're about to
1620 reopen it with different flags. */
1621 if (!CloseHandle(hFile))
1622 return -1;
1623
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001625 /* In order to call GetFinalPathNameByHandle we need to open
1626 the file without the reparse handling flag set. */
1627 hFile2 = CreateFileA(
1628 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1629 NULL, OPEN_EXISTING,
1630 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1631 NULL);
1632 if (hFile2 == INVALID_HANDLE_VALUE)
1633 return -1;
1634
1635 if (!get_target_path(hFile2, &target_path))
1636 return -1;
1637
1638 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001639 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 return code;
1641 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001642 } else
1643 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001644 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001645 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001646
1647 /* Set S_IEXEC if it is an .exe, .bat, ... */
1648 dot = strrchr(path, '.');
1649 if (dot) {
1650 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1651 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1652 result->st_mode |= 0111;
1653 }
1654 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001655}
1656
1657static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001658win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001659 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660{
1661 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001662 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001664 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001665 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001666 const wchar_t *dot;
1667
1668 hFile = CreateFileW(
1669 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001670 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671 0, /* share mode */
1672 NULL, /* security attributes */
1673 OPEN_EXISTING,
1674 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001675 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1676 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001677 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001678 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001679 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001680 NULL);
1681
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001682 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683 /* Either the target doesn't exist, or we don't have access to
1684 get a handle to it. If the former, we need to return an error.
1685 If the latter, we can use attributes_from_dir. */
1686 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001687 return -1;
1688 /* Could not get attributes on open file. Fall back to
1689 reading the directory. */
1690 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1691 /* Very strange. This should not fail now */
1692 return -1;
1693 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1694 if (traverse) {
1695 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001696 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001697 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001698 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001699 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001700 } else {
1701 if (!GetFileInformationByHandle(hFile, &info)) {
1702 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001703 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001704 }
1705 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001706 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1707 return -1;
1708
1709 /* Close the outer open file handle now that we're about to
1710 reopen it with different flags. */
1711 if (!CloseHandle(hFile))
1712 return -1;
1713
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001715 /* In order to call GetFinalPathNameByHandle we need to open
1716 the file without the reparse handling flag set. */
1717 hFile2 = CreateFileW(
1718 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1719 NULL, OPEN_EXISTING,
1720 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1721 NULL);
1722 if (hFile2 == INVALID_HANDLE_VALUE)
1723 return -1;
1724
1725 if (!get_target_path(hFile2, &target_path))
1726 return -1;
1727
1728 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001729 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001730 return code;
1731 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001732 } else
1733 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001734 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001735 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001736
1737 /* Set S_IEXEC if it is an .exe, .bat, ... */
1738 dot = wcsrchr(path, '.');
1739 if (dot) {
1740 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1741 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1742 result->st_mode |= 0111;
1743 }
1744 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001745}
1746
1747static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001748win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001749{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 /* Protocol violation: we explicitly clear errno, instead of
1751 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001752 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001753 errno = 0;
1754 return code;
1755}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001756
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001757static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001758win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001759{
1760 /* Protocol violation: we explicitly clear errno, instead of
1761 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001762 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001763 errno = 0;
1764 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001765}
Brian Curtind25aef52011-06-13 15:16:04 -05001766/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001767
1768 In Posix, stat automatically traverses symlinks and returns the stat
1769 structure for the target. In Windows, the equivalent GetFileAttributes by
1770 default does not traverse symlinks and instead returns attributes for
1771 the symlink.
1772
1773 Therefore, win32_lstat will get the attributes traditionally, and
1774 win32_stat will first explicitly resolve the symlink target and then will
1775 call win32_lstat on that result.
1776
Ezio Melotti4969f702011-03-15 05:59:46 +02001777 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001778
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001779static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001780win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001781{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001782 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001783}
1784
Victor Stinner8c62be82010-05-06 00:08:46 +00001785static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001786win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001787{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001788 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001789}
1790
1791static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001792win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001793{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001794 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001795}
1796
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001797static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001798win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001799{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001800 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001801}
1802
Martin v. Löwis14694662006-02-03 12:54:16 +00001803#endif /* MS_WINDOWS */
1804
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001805PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001806"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001807This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001808 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001809or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1810\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001811Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1812or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001813\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001814See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815
1816static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001817 {"st_mode", "protection bits"},
1818 {"st_ino", "inode"},
1819 {"st_dev", "device"},
1820 {"st_nlink", "number of hard links"},
1821 {"st_uid", "user ID of owner"},
1822 {"st_gid", "group ID of owner"},
1823 {"st_size", "total size, in bytes"},
1824 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1825 {NULL, "integer time of last access"},
1826 {NULL, "integer time of last modification"},
1827 {NULL, "integer time of last change"},
1828 {"st_atime", "time of last access"},
1829 {"st_mtime", "time of last modification"},
1830 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001831 {"st_atime_ns", "time of last access in nanoseconds"},
1832 {"st_mtime_ns", "time of last modification in nanoseconds"},
1833 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001834#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001835 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001836#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001837#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001838 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001839#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001840#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001841 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001842#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001843#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001844 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001845#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001846#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001847 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001848#endif
1849#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001851#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001852#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1853 {"st_file_attributes", "Windows file attribute bits"},
1854#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001855 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856};
1857
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001858#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001859#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001860#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001861#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001862#endif
1863
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001864#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001865#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1866#else
1867#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1868#endif
1869
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001870#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001871#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1872#else
1873#define ST_RDEV_IDX ST_BLOCKS_IDX
1874#endif
1875
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001876#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1877#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1878#else
1879#define ST_FLAGS_IDX ST_RDEV_IDX
1880#endif
1881
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001882#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001883#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001884#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001885#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001886#endif
1887
1888#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1889#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1890#else
1891#define ST_BIRTHTIME_IDX ST_GEN_IDX
1892#endif
1893
Zachary Ware63f277b2014-06-19 09:46:37 -05001894#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1895#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1896#else
1897#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1898#endif
1899
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001900static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 "stat_result", /* name */
1902 stat_result__doc__, /* doc */
1903 stat_result_fields,
1904 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001905};
1906
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001907PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001908"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1909This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001910 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001911or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001912\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001913See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001914
1915static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001916 {"f_bsize", },
1917 {"f_frsize", },
1918 {"f_blocks", },
1919 {"f_bfree", },
1920 {"f_bavail", },
1921 {"f_files", },
1922 {"f_ffree", },
1923 {"f_favail", },
1924 {"f_flag", },
1925 {"f_namemax",},
1926 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001927};
1928
1929static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001930 "statvfs_result", /* name */
1931 statvfs_result__doc__, /* doc */
1932 statvfs_result_fields,
1933 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001934};
1935
Ross Lagerwall7807c352011-03-17 20:20:30 +02001936#if defined(HAVE_WAITID) && !defined(__APPLE__)
1937PyDoc_STRVAR(waitid_result__doc__,
1938"waitid_result: Result from waitid.\n\n\
1939This object may be accessed either as a tuple of\n\
1940 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1941or via the attributes si_pid, si_uid, and so on.\n\
1942\n\
1943See os.waitid for more information.");
1944
1945static PyStructSequence_Field waitid_result_fields[] = {
1946 {"si_pid", },
1947 {"si_uid", },
1948 {"si_signo", },
1949 {"si_status", },
1950 {"si_code", },
1951 {0}
1952};
1953
1954static PyStructSequence_Desc waitid_result_desc = {
1955 "waitid_result", /* name */
1956 waitid_result__doc__, /* doc */
1957 waitid_result_fields,
1958 5
1959};
1960static PyTypeObject WaitidResultType;
1961#endif
1962
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001963static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001964static PyTypeObject StatResultType;
1965static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001966#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001967static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001968#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001969static newfunc structseq_new;
1970
1971static PyObject *
1972statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1973{
Victor Stinner8c62be82010-05-06 00:08:46 +00001974 PyStructSequence *result;
1975 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001976
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 result = (PyStructSequence*)structseq_new(type, args, kwds);
1978 if (!result)
1979 return NULL;
1980 /* If we have been initialized from a tuple,
1981 st_?time might be set to None. Initialize it
1982 from the int slots. */
1983 for (i = 7; i <= 9; i++) {
1984 if (result->ob_item[i+3] == Py_None) {
1985 Py_DECREF(Py_None);
1986 Py_INCREF(result->ob_item[i]);
1987 result->ob_item[i+3] = result->ob_item[i];
1988 }
1989 }
1990 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001991}
1992
1993
1994
1995/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001996static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001997
1998PyDoc_STRVAR(stat_float_times__doc__,
1999"stat_float_times([newval]) -> oldval\n\n\
2000Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10002001\n\
2002If value is True, future calls to stat() return floats; if it is False,\n\
2003future calls return ints.\n\
2004If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002005
Larry Hastings2f936352014-08-05 14:04:04 +10002006/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002007static PyObject*
2008stat_float_times(PyObject* self, PyObject *args)
2009{
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 int newval = -1;
2011 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
2012 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02002013 if (PyErr_WarnEx(PyExc_DeprecationWarning,
2014 "stat_float_times() is deprecated",
2015 1))
2016 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 if (newval == -1)
2018 /* Return old value */
2019 return PyBool_FromLong(_stat_float_times);
2020 _stat_float_times = newval;
2021 Py_INCREF(Py_None);
2022 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00002023}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002024
Larry Hastings6fe20b32012-04-19 15:07:49 -07002025static PyObject *billion = NULL;
2026
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002027static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01002028fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002029{
Larry Hastings6fe20b32012-04-19 15:07:49 -07002030 PyObject *s = _PyLong_FromTime_t(sec);
2031 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
2032 PyObject *s_in_ns = NULL;
2033 PyObject *ns_total = NULL;
2034 PyObject *float_s = NULL;
2035
2036 if (!(s && ns_fractional))
2037 goto exit;
2038
2039 s_in_ns = PyNumber_Multiply(s, billion);
2040 if (!s_in_ns)
2041 goto exit;
2042
2043 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2044 if (!ns_total)
2045 goto exit;
2046
Victor Stinner4195b5c2012-02-08 23:03:19 +01002047 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002048 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2049 if (!float_s)
2050 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002052 else {
2053 float_s = s;
2054 Py_INCREF(float_s);
2055 }
2056
2057 PyStructSequence_SET_ITEM(v, index, s);
2058 PyStructSequence_SET_ITEM(v, index+3, float_s);
2059 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2060 s = NULL;
2061 float_s = NULL;
2062 ns_total = NULL;
2063exit:
2064 Py_XDECREF(s);
2065 Py_XDECREF(ns_fractional);
2066 Py_XDECREF(s_in_ns);
2067 Py_XDECREF(ns_total);
2068 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002069}
2070
Tim Peters5aa91602002-01-30 05:46:57 +00002071/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002072 (used by posix_stat() and posix_fstat()) */
2073static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002074_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002075{
Victor Stinner8c62be82010-05-06 00:08:46 +00002076 unsigned long ansec, mnsec, cnsec;
2077 PyObject *v = PyStructSequence_New(&StatResultType);
2078 if (v == NULL)
2079 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002080
Victor Stinner8c62be82010-05-06 00:08:46 +00002081 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002082#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyStructSequence_SET_ITEM(v, 1,
2084 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002085#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002087#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002088#ifdef MS_WINDOWS
2089 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002090#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002091 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002092#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002093 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002094#if defined(MS_WINDOWS)
2095 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2096 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2097#else
2098 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2099 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2100#endif
Fred Drake699f3522000-06-29 21:12:41 +00002101#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 PyStructSequence_SET_ITEM(v, 6,
2103 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002104#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002105 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002106#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002107
Martin v. Löwis14694662006-02-03 12:54:16 +00002108#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002109 ansec = st->st_atim.tv_nsec;
2110 mnsec = st->st_mtim.tv_nsec;
2111 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002112#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002113 ansec = st->st_atimespec.tv_nsec;
2114 mnsec = st->st_mtimespec.tv_nsec;
2115 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002116#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002117 ansec = st->st_atime_nsec;
2118 mnsec = st->st_mtime_nsec;
2119 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002120#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002121 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002122#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002123 fill_time(v, 7, st->st_atime, ansec);
2124 fill_time(v, 8, st->st_mtime, mnsec);
2125 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002126
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002127#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002128 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2129 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002130#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002131#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2133 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002134#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002135#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002136 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2137 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002138#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002139#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002140 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2141 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002142#endif
2143#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002144 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002145 PyObject *val;
2146 unsigned long bsec,bnsec;
2147 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002148#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002149 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002150#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002151 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002152#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002153 if (_stat_float_times) {
2154 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2155 } else {
2156 val = PyLong_FromLong((long)bsec);
2157 }
2158 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2159 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002160 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002161#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002162#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002163 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2164 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002165#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002166#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2167 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2168 PyLong_FromUnsignedLong(st->st_file_attributes));
2169#endif
Fred Drake699f3522000-06-29 21:12:41 +00002170
Victor Stinner8c62be82010-05-06 00:08:46 +00002171 if (PyErr_Occurred()) {
2172 Py_DECREF(v);
2173 return NULL;
2174 }
Fred Drake699f3522000-06-29 21:12:41 +00002175
Victor Stinner8c62be82010-05-06 00:08:46 +00002176 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002177}
2178
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002179/* POSIX methods */
2180
Guido van Rossum94f6f721999-01-06 18:42:14 +00002181
2182static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002183posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002184 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002185{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002186 STRUCT_STAT st;
2187 int result;
2188
2189#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2190 if (follow_symlinks_specified(function_name, follow_symlinks))
2191 return NULL;
2192#endif
2193
2194 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2195 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2196 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2197 return NULL;
2198
2199 Py_BEGIN_ALLOW_THREADS
2200 if (path->fd != -1)
2201 result = FSTAT(path->fd, &st);
2202 else
2203#ifdef MS_WINDOWS
2204 if (path->wide) {
2205 if (follow_symlinks)
2206 result = win32_stat_w(path->wide, &st);
2207 else
2208 result = win32_lstat_w(path->wide, &st);
2209 }
2210 else
2211#endif
2212#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2213 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2214 result = LSTAT(path->narrow, &st);
2215 else
2216#endif
2217#ifdef HAVE_FSTATAT
2218 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2219 result = fstatat(dir_fd, path->narrow, &st,
2220 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2221 else
2222#endif
2223 result = STAT(path->narrow, &st);
2224 Py_END_ALLOW_THREADS
2225
Victor Stinner292c8352012-10-30 02:17:38 +01002226 if (result != 0) {
2227 return path_error(path);
2228 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002229
2230 return _pystat_fromstructstat(&st);
2231}
2232
Larry Hastings2f936352014-08-05 14:04:04 +10002233/*[python input]
2234
2235for s in """
2236
2237FACCESSAT
2238FCHMODAT
2239FCHOWNAT
2240FSTATAT
2241LINKAT
2242MKDIRAT
2243MKFIFOAT
2244MKNODAT
2245OPENAT
2246READLINKAT
2247SYMLINKAT
2248UNLINKAT
2249
2250""".strip().split():
2251 s = s.strip()
2252 print("""
2253#ifdef HAVE_{s}
2254 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002255#else
Larry Hastings2f936352014-08-05 14:04:04 +10002256 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002257#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002258""".rstrip().format(s=s))
2259
2260for s in """
2261
2262FCHDIR
2263FCHMOD
2264FCHOWN
2265FDOPENDIR
2266FEXECVE
2267FPATHCONF
2268FSTATVFS
2269FTRUNCATE
2270
2271""".strip().split():
2272 s = s.strip()
2273 print("""
2274#ifdef HAVE_{s}
2275 #define PATH_HAVE_{s} 1
2276#else
2277 #define PATH_HAVE_{s} 0
2278#endif
2279
2280""".rstrip().format(s=s))
2281[python start generated code]*/
2282
2283#ifdef HAVE_FACCESSAT
2284 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2285#else
2286 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2287#endif
2288
2289#ifdef HAVE_FCHMODAT
2290 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2291#else
2292 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2293#endif
2294
2295#ifdef HAVE_FCHOWNAT
2296 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2297#else
2298 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2299#endif
2300
2301#ifdef HAVE_FSTATAT
2302 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2303#else
2304 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2305#endif
2306
2307#ifdef HAVE_LINKAT
2308 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2309#else
2310 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2311#endif
2312
2313#ifdef HAVE_MKDIRAT
2314 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2315#else
2316 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2317#endif
2318
2319#ifdef HAVE_MKFIFOAT
2320 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2321#else
2322 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2323#endif
2324
2325#ifdef HAVE_MKNODAT
2326 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2327#else
2328 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2329#endif
2330
2331#ifdef HAVE_OPENAT
2332 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2333#else
2334 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2335#endif
2336
2337#ifdef HAVE_READLINKAT
2338 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2339#else
2340 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2341#endif
2342
2343#ifdef HAVE_SYMLINKAT
2344 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2345#else
2346 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2347#endif
2348
2349#ifdef HAVE_UNLINKAT
2350 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2351#else
2352 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2353#endif
2354
2355#ifdef HAVE_FCHDIR
2356 #define PATH_HAVE_FCHDIR 1
2357#else
2358 #define PATH_HAVE_FCHDIR 0
2359#endif
2360
2361#ifdef HAVE_FCHMOD
2362 #define PATH_HAVE_FCHMOD 1
2363#else
2364 #define PATH_HAVE_FCHMOD 0
2365#endif
2366
2367#ifdef HAVE_FCHOWN
2368 #define PATH_HAVE_FCHOWN 1
2369#else
2370 #define PATH_HAVE_FCHOWN 0
2371#endif
2372
2373#ifdef HAVE_FDOPENDIR
2374 #define PATH_HAVE_FDOPENDIR 1
2375#else
2376 #define PATH_HAVE_FDOPENDIR 0
2377#endif
2378
2379#ifdef HAVE_FEXECVE
2380 #define PATH_HAVE_FEXECVE 1
2381#else
2382 #define PATH_HAVE_FEXECVE 0
2383#endif
2384
2385#ifdef HAVE_FPATHCONF
2386 #define PATH_HAVE_FPATHCONF 1
2387#else
2388 #define PATH_HAVE_FPATHCONF 0
2389#endif
2390
2391#ifdef HAVE_FSTATVFS
2392 #define PATH_HAVE_FSTATVFS 1
2393#else
2394 #define PATH_HAVE_FSTATVFS 0
2395#endif
2396
2397#ifdef HAVE_FTRUNCATE
2398 #define PATH_HAVE_FTRUNCATE 1
2399#else
2400 #define PATH_HAVE_FTRUNCATE 0
2401#endif
2402/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002403
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002404#ifdef MS_WINDOWS
2405 #undef PATH_HAVE_FTRUNCATE
2406 #define PATH_HAVE_FTRUNCATE 1
2407#endif
Larry Hastings31826802013-10-19 00:09:25 -07002408
Larry Hastings61272b72014-01-07 12:41:53 -08002409/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002410
2411class path_t_converter(CConverter):
2412
2413 type = "path_t"
2414 impl_by_reference = True
2415 parse_by_reference = True
2416
2417 converter = 'path_converter'
2418
2419 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002420 # right now path_t doesn't support default values.
2421 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002422 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002423 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002424
Larry Hastings2f936352014-08-05 14:04:04 +10002425 if self.c_default not in (None, 'Py_None'):
2426 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002427
2428 self.nullable = nullable
2429 self.allow_fd = allow_fd
2430
Larry Hastings7726ac92014-01-31 22:03:12 -08002431 def pre_render(self):
2432 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002433 if isinstance(value, str):
2434 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002435 return str(int(bool(value)))
2436
2437 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002438 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002439 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002440 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002441 strify(self.nullable),
2442 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002443 )
2444
2445 def cleanup(self):
2446 return "path_cleanup(&" + self.name + ");\n"
2447
2448
2449class dir_fd_converter(CConverter):
2450 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002451
Larry Hastings2f936352014-08-05 14:04:04 +10002452 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002453 if self.default in (unspecified, None):
2454 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002455 if isinstance(requires, str):
2456 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2457 else:
2458 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002459
Larry Hastings2f936352014-08-05 14:04:04 +10002460class fildes_converter(CConverter):
2461 type = 'int'
2462 converter = 'fildes_converter'
2463
2464class uid_t_converter(CConverter):
2465 type = "uid_t"
2466 converter = '_Py_Uid_Converter'
2467
2468class gid_t_converter(CConverter):
2469 type = "gid_t"
2470 converter = '_Py_Gid_Converter'
2471
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002472class dev_t_converter(CConverter):
2473 type = 'dev_t'
2474 converter = '_Py_Dev_Converter'
2475
2476class dev_t_return_converter(unsigned_long_return_converter):
2477 type = 'dev_t'
2478 conversion_fn = '_PyLong_FromDev'
2479 unsigned_cast = '(dev_t)'
2480
Larry Hastings2f936352014-08-05 14:04:04 +10002481class FSConverter_converter(CConverter):
2482 type = 'PyObject *'
2483 converter = 'PyUnicode_FSConverter'
2484 def converter_init(self):
2485 if self.default is not unspecified:
2486 fail("FSConverter_converter does not support default values")
2487 self.c_default = 'NULL'
2488
2489 def cleanup(self):
2490 return "Py_XDECREF(" + self.name + ");\n"
2491
2492class pid_t_converter(CConverter):
2493 type = 'pid_t'
2494 format_unit = '" _Py_PARSE_PID "'
2495
2496class idtype_t_converter(int_converter):
2497 type = 'idtype_t'
2498
2499class id_t_converter(CConverter):
2500 type = 'id_t'
2501 format_unit = '" _Py_PARSE_PID "'
2502
2503class Py_intptr_t_converter(CConverter):
2504 type = 'Py_intptr_t'
2505 format_unit = '" _Py_PARSE_INTPTR "'
2506
2507class Py_off_t_converter(CConverter):
2508 type = 'Py_off_t'
2509 converter = 'Py_off_t_converter'
2510
2511class Py_off_t_return_converter(long_return_converter):
2512 type = 'Py_off_t'
2513 conversion_fn = 'PyLong_FromPy_off_t'
2514
2515class path_confname_converter(CConverter):
2516 type="int"
2517 converter="conv_path_confname"
2518
2519class confstr_confname_converter(path_confname_converter):
2520 converter='conv_confstr_confname'
2521
2522class sysconf_confname_converter(path_confname_converter):
2523 converter="conv_sysconf_confname"
2524
2525class sched_param_converter(CConverter):
2526 type = 'struct sched_param'
2527 converter = 'convert_sched_param'
2528 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002529
Larry Hastings61272b72014-01-07 12:41:53 -08002530[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002531/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002532
Larry Hastings61272b72014-01-07 12:41:53 -08002533/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002534
Larry Hastings2a727912014-01-16 11:32:01 -08002535os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002536
2537 path : path_t(allow_fd=True)
2538 Path to be examined; can be string, bytes, or open-file-descriptor int.
2539
2540 *
2541
Larry Hastings2f936352014-08-05 14:04:04 +10002542 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002543 If not None, it should be a file descriptor open to a directory,
2544 and path should be a relative string; path will then be relative to
2545 that directory.
2546
2547 follow_symlinks: bool = True
2548 If False, and the last element of the path is a symbolic link,
2549 stat will examine the symbolic link itself instead of the file
2550 the link points to.
2551
2552Perform a stat system call on the given path.
2553
2554dir_fd and follow_symlinks may not be implemented
2555 on your platform. If they are unavailable, using them will raise a
2556 NotImplementedError.
2557
2558It's an error to use dir_fd or follow_symlinks when specifying path as
2559 an open file descriptor.
2560
Larry Hastings61272b72014-01-07 12:41:53 -08002561[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002562
Larry Hastings31826802013-10-19 00:09:25 -07002563static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002564os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2565/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002566{
2567 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2568}
2569
Larry Hastings2f936352014-08-05 14:04:04 +10002570
2571/*[clinic input]
2572os.lstat
2573
2574 path : path_t
2575
2576 *
2577
2578 dir_fd : dir_fd(requires='fstatat') = None
2579
2580Perform a stat system call on the given path, without following symbolic links.
2581
2582Like stat(), but do not follow symbolic links.
2583Equivalent to stat(path, follow_symlinks=False).
2584[clinic start generated code]*/
2585
Larry Hastings2f936352014-08-05 14:04:04 +10002586static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002587os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2588/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002589{
2590 int follow_symlinks = 0;
2591 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2592}
Larry Hastings31826802013-10-19 00:09:25 -07002593
Larry Hastings2f936352014-08-05 14:04:04 +10002594
Larry Hastings61272b72014-01-07 12:41:53 -08002595/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002596os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002597
2598 path: path_t(allow_fd=True)
2599 Path to be tested; can be string, bytes, or open-file-descriptor int.
2600
2601 mode: int
2602 Operating-system mode bitfield. Can be F_OK to test existence,
2603 or the inclusive-OR of R_OK, W_OK, and X_OK.
2604
2605 *
2606
Larry Hastings2f936352014-08-05 14:04:04 +10002607 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002608 If not None, it should be a file descriptor open to a directory,
2609 and path should be relative; path will then be relative to that
2610 directory.
2611
2612 effective_ids: bool = False
2613 If True, access will use the effective uid/gid instead of
2614 the real uid/gid.
2615
2616 follow_symlinks: bool = True
2617 If False, and the last element of the path is a symbolic link,
2618 access will examine the symbolic link itself instead of the file
2619 the link points to.
2620
2621Use the real uid/gid to test for access to a path.
2622
2623{parameters}
2624dir_fd, effective_ids, and follow_symlinks may not be implemented
2625 on your platform. If they are unavailable, using them will raise a
2626 NotImplementedError.
2627
2628Note that most operations will use the effective uid/gid, therefore this
2629 routine can be used in a suid/sgid environment to test if the invoking user
2630 has the specified access to the path.
2631
Larry Hastings61272b72014-01-07 12:41:53 -08002632[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002633
Larry Hastings2f936352014-08-05 14:04:04 +10002634static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002635os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002636 int effective_ids, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002637/*[clinic end generated code: output=cf84158bc90b1a77 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002638{
Larry Hastings2f936352014-08-05 14:04:04 +10002639 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002640
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002641#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002642 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002643#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002644 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002645#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646
Larry Hastings9cf065c2012-06-22 16:30:09 -07002647#ifndef HAVE_FACCESSAT
2648 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002649 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650
2651 if (effective_ids) {
2652 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002653 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654 }
2655#endif
2656
2657#ifdef MS_WINDOWS
2658 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002659 if (path->wide != NULL)
2660 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002661 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002662 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002663 Py_END_ALLOW_THREADS
2664
2665 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002666 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002667 * * we didn't get a -1, and
2668 * * write access wasn't requested,
2669 * * or the file isn't read-only,
2670 * * or it's a directory.
2671 * (Directories cannot be read-only on Windows.)
2672 */
Larry Hastings2f936352014-08-05 14:04:04 +10002673 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002674 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002675 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002676 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002677#else
2678
2679 Py_BEGIN_ALLOW_THREADS
2680#ifdef HAVE_FACCESSAT
2681 if ((dir_fd != DEFAULT_DIR_FD) ||
2682 effective_ids ||
2683 !follow_symlinks) {
2684 int flags = 0;
2685 if (!follow_symlinks)
2686 flags |= AT_SYMLINK_NOFOLLOW;
2687 if (effective_ids)
2688 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002689 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002690 }
2691 else
2692#endif
Larry Hastings31826802013-10-19 00:09:25 -07002693 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002694 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002695 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002696#endif
2697
Larry Hastings9cf065c2012-06-22 16:30:09 -07002698 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002699}
2700
Guido van Rossumd371ff11999-01-25 16:12:23 +00002701#ifndef F_OK
2702#define F_OK 0
2703#endif
2704#ifndef R_OK
2705#define R_OK 4
2706#endif
2707#ifndef W_OK
2708#define W_OK 2
2709#endif
2710#ifndef X_OK
2711#define X_OK 1
2712#endif
2713
Larry Hastings31826802013-10-19 00:09:25 -07002714
Guido van Rossumd371ff11999-01-25 16:12:23 +00002715#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002716/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002717os.ttyname -> DecodeFSDefault
2718
2719 fd: int
2720 Integer file descriptor handle.
2721
2722 /
2723
2724Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002725[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002726
Larry Hastings31826802013-10-19 00:09:25 -07002727static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002728os_ttyname_impl(PyObject *module, int fd)
2729/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002730{
2731 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002732
Larry Hastings31826802013-10-19 00:09:25 -07002733 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002734 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002735 posix_error();
2736 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002737}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002738#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002739
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002740#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002741/*[clinic input]
2742os.ctermid
2743
2744Return the name of the controlling terminal for this process.
2745[clinic start generated code]*/
2746
Larry Hastings2f936352014-08-05 14:04:04 +10002747static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002748os_ctermid_impl(PyObject *module)
2749/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002750{
Victor Stinner8c62be82010-05-06 00:08:46 +00002751 char *ret;
2752 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002753
Greg Wardb48bc172000-03-01 21:51:56 +00002754#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002755 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002756#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002757 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002758#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002759 if (ret == NULL)
2760 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002761 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002762}
Larry Hastings2f936352014-08-05 14:04:04 +10002763#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002764
Larry Hastings2f936352014-08-05 14:04:04 +10002765
2766/*[clinic input]
2767os.chdir
2768
2769 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2770
2771Change the current working directory to the specified path.
2772
2773path may always be specified as a string.
2774On some platforms, path may also be specified as an open file descriptor.
2775 If this functionality is unavailable, using it raises an exception.
2776[clinic start generated code]*/
2777
Larry Hastings2f936352014-08-05 14:04:04 +10002778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002779os_chdir_impl(PyObject *module, path_t *path)
2780/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002781{
2782 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002783
2784 Py_BEGIN_ALLOW_THREADS
2785#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002786 if (path->wide)
2787 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002788 else
Larry Hastings2f936352014-08-05 14:04:04 +10002789 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002790 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002791#else
2792#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002793 if (path->fd != -1)
2794 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795 else
2796#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002797 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798#endif
2799 Py_END_ALLOW_THREADS
2800
2801 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002802 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803 }
2804
Larry Hastings2f936352014-08-05 14:04:04 +10002805 Py_RETURN_NONE;
2806}
2807
2808
2809#ifdef HAVE_FCHDIR
2810/*[clinic input]
2811os.fchdir
2812
2813 fd: fildes
2814
2815Change to the directory of the given file descriptor.
2816
2817fd must be opened on a directory, not a file.
2818Equivalent to os.chdir(fd).
2819
2820[clinic start generated code]*/
2821
Fred Drake4d1e64b2002-04-15 19:40:07 +00002822static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002823os_fchdir_impl(PyObject *module, int fd)
2824/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002825{
Larry Hastings2f936352014-08-05 14:04:04 +10002826 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002827}
2828#endif /* HAVE_FCHDIR */
2829
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002830
Larry Hastings2f936352014-08-05 14:04:04 +10002831/*[clinic input]
2832os.chmod
2833
2834 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2835 Path to be modified. May always be specified as a str or bytes.
2836 On some platforms, path may also be specified as an open file descriptor.
2837 If this functionality is unavailable, using it raises an exception.
2838
2839 mode: int
2840 Operating-system mode bitfield.
2841
2842 *
2843
2844 dir_fd : dir_fd(requires='fchmodat') = None
2845 If not None, it should be a file descriptor open to a directory,
2846 and path should be relative; path will then be relative to that
2847 directory.
2848
2849 follow_symlinks: bool = True
2850 If False, and the last element of the path is a symbolic link,
2851 chmod will modify the symbolic link itself instead of the file
2852 the link points to.
2853
2854Change the access permissions of a file.
2855
2856It is an error to use dir_fd or follow_symlinks when specifying path as
2857 an open file descriptor.
2858dir_fd and follow_symlinks may not be implemented on your platform.
2859 If they are unavailable, using them will raise a NotImplementedError.
2860
2861[clinic start generated code]*/
2862
Larry Hastings2f936352014-08-05 14:04:04 +10002863static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002864os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002865 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002866/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002867{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002868 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002869
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002870#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002871 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002873
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874#ifdef HAVE_FCHMODAT
2875 int fchmodat_nofollow_unsupported = 0;
2876#endif
2877
Larry Hastings9cf065c2012-06-22 16:30:09 -07002878#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2879 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002880 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002881#endif
2882
2883#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002884 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002885 if (path->wide)
2886 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887 else
Larry Hastings2f936352014-08-05 14:04:04 +10002888 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002889 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890 result = 0;
2891 else {
2892 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002893 attr &= ~FILE_ATTRIBUTE_READONLY;
2894 else
2895 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002896 if (path->wide)
2897 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002898 else
Larry Hastings2f936352014-08-05 14:04:04 +10002899 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900 }
2901 Py_END_ALLOW_THREADS
2902
2903 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002904 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002905 }
2906#else /* MS_WINDOWS */
2907 Py_BEGIN_ALLOW_THREADS
2908#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002909 if (path->fd != -1)
2910 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002911 else
2912#endif
2913#ifdef HAVE_LCHMOD
2914 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002915 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002916 else
2917#endif
2918#ifdef HAVE_FCHMODAT
2919 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2920 /*
2921 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2922 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002923 * and then says it isn't implemented yet.
2924 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002925 *
2926 * Once it is supported, os.chmod will automatically
2927 * support dir_fd and follow_symlinks=False. (Hopefully.)
2928 * Until then, we need to be careful what exception we raise.
2929 */
Larry Hastings2f936352014-08-05 14:04:04 +10002930 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002931 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2932 /*
2933 * But wait! We can't throw the exception without allowing threads,
2934 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2935 */
2936 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002937 result &&
2938 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2939 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 }
2941 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002942#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002943 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002944 Py_END_ALLOW_THREADS
2945
2946 if (result) {
2947#ifdef HAVE_FCHMODAT
2948 if (fchmodat_nofollow_unsupported) {
2949 if (dir_fd != DEFAULT_DIR_FD)
2950 dir_fd_and_follow_symlinks_invalid("chmod",
2951 dir_fd, follow_symlinks);
2952 else
2953 follow_symlinks_specified("chmod", follow_symlinks);
2954 }
2955 else
2956#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002957 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002958 }
2959#endif
2960
Larry Hastings2f936352014-08-05 14:04:04 +10002961 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002962}
2963
Larry Hastings9cf065c2012-06-22 16:30:09 -07002964
Christian Heimes4e30a842007-11-30 22:12:06 +00002965#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002966/*[clinic input]
2967os.fchmod
2968
2969 fd: int
2970 mode: int
2971
2972Change the access permissions of the file given by file descriptor fd.
2973
2974Equivalent to os.chmod(fd, mode).
2975[clinic start generated code]*/
2976
Larry Hastings2f936352014-08-05 14:04:04 +10002977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002978os_fchmod_impl(PyObject *module, int fd, int mode)
2979/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002980{
2981 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002982 int async_err = 0;
2983
2984 do {
2985 Py_BEGIN_ALLOW_THREADS
2986 res = fchmod(fd, mode);
2987 Py_END_ALLOW_THREADS
2988 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2989 if (res != 0)
2990 return (!async_err) ? posix_error() : NULL;
2991
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002993}
2994#endif /* HAVE_FCHMOD */
2995
Larry Hastings2f936352014-08-05 14:04:04 +10002996
Christian Heimes4e30a842007-11-30 22:12:06 +00002997#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002998/*[clinic input]
2999os.lchmod
3000
3001 path: path_t
3002 mode: int
3003
3004Change the access permissions of a file, without following symbolic links.
3005
3006If path is a symlink, this affects the link itself rather than the target.
3007Equivalent to chmod(path, mode, follow_symlinks=False)."
3008[clinic start generated code]*/
3009
Larry Hastings2f936352014-08-05 14:04:04 +10003010static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003011os_lchmod_impl(PyObject *module, path_t *path, int mode)
3012/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003013{
Victor Stinner8c62be82010-05-06 00:08:46 +00003014 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003016 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003018 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003019 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003020 return NULL;
3021 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003022 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003023}
3024#endif /* HAVE_LCHMOD */
3025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003026
Thomas Wouterscf297e42007-02-23 15:07:44 +00003027#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003028/*[clinic input]
3029os.chflags
3030
3031 path: path_t
3032 flags: unsigned_long(bitwise=True)
3033 follow_symlinks: bool=True
3034
3035Set file flags.
3036
3037If follow_symlinks is False, and the last element of the path is a symbolic
3038 link, chflags will change flags on the symbolic link itself instead of the
3039 file the link points to.
3040follow_symlinks may not be implemented on your platform. If it is
3041unavailable, using it will raise a NotImplementedError.
3042
3043[clinic start generated code]*/
3044
Larry Hastings2f936352014-08-05 14:04:04 +10003045static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003046os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003047 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003048/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003049{
3050 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003051
3052#ifndef HAVE_LCHFLAGS
3053 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003054 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003055#endif
3056
Victor Stinner8c62be82010-05-06 00:08:46 +00003057 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003058#ifdef HAVE_LCHFLAGS
3059 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003060 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003061 else
3062#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003063 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003064 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003065
Larry Hastings2f936352014-08-05 14:04:04 +10003066 if (result)
3067 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003068
Larry Hastings2f936352014-08-05 14:04:04 +10003069 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003070}
3071#endif /* HAVE_CHFLAGS */
3072
Larry Hastings2f936352014-08-05 14:04:04 +10003073
Thomas Wouterscf297e42007-02-23 15:07:44 +00003074#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003075/*[clinic input]
3076os.lchflags
3077
3078 path: path_t
3079 flags: unsigned_long(bitwise=True)
3080
3081Set file flags.
3082
3083This function will not follow symbolic links.
3084Equivalent to chflags(path, flags, follow_symlinks=False).
3085[clinic start generated code]*/
3086
Larry Hastings2f936352014-08-05 14:04:04 +10003087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003088os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3089/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003090{
Victor Stinner8c62be82010-05-06 00:08:46 +00003091 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003092 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003093 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003094 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003095 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003096 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003097 }
Victor Stinner292c8352012-10-30 02:17:38 +01003098 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003099}
3100#endif /* HAVE_LCHFLAGS */
3101
Larry Hastings2f936352014-08-05 14:04:04 +10003102
Martin v. Löwis244edc82001-10-04 22:44:26 +00003103#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003104/*[clinic input]
3105os.chroot
3106 path: path_t
3107
3108Change root directory to path.
3109
3110[clinic start generated code]*/
3111
Larry Hastings2f936352014-08-05 14:04:04 +10003112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003113os_chroot_impl(PyObject *module, path_t *path)
3114/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003115{
3116 int res;
3117 Py_BEGIN_ALLOW_THREADS
3118 res = chroot(path->narrow);
3119 Py_END_ALLOW_THREADS
3120 if (res < 0)
3121 return path_error(path);
3122 Py_RETURN_NONE;
3123}
3124#endif /* HAVE_CHROOT */
3125
Martin v. Löwis244edc82001-10-04 22:44:26 +00003126
Guido van Rossum21142a01999-01-08 21:05:37 +00003127#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003128/*[clinic input]
3129os.fsync
3130
3131 fd: fildes
3132
3133Force write of fd to disk.
3134[clinic start generated code]*/
3135
Larry Hastings2f936352014-08-05 14:04:04 +10003136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003137os_fsync_impl(PyObject *module, int fd)
3138/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003139{
3140 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003141}
3142#endif /* HAVE_FSYNC */
3143
Larry Hastings2f936352014-08-05 14:04:04 +10003144
Ross Lagerwall7807c352011-03-17 20:20:30 +02003145#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003146/*[clinic input]
3147os.sync
3148
3149Force write of everything to disk.
3150[clinic start generated code]*/
3151
Larry Hastings2f936352014-08-05 14:04:04 +10003152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153os_sync_impl(PyObject *module)
3154/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003155{
3156 Py_BEGIN_ALLOW_THREADS
3157 sync();
3158 Py_END_ALLOW_THREADS
3159 Py_RETURN_NONE;
3160}
Larry Hastings2f936352014-08-05 14:04:04 +10003161#endif /* HAVE_SYNC */
3162
Ross Lagerwall7807c352011-03-17 20:20:30 +02003163
Guido van Rossum21142a01999-01-08 21:05:37 +00003164#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003165#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003166extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3167#endif
3168
Larry Hastings2f936352014-08-05 14:04:04 +10003169/*[clinic input]
3170os.fdatasync
3171
3172 fd: fildes
3173
3174Force write of fd to disk without forcing update of metadata.
3175[clinic start generated code]*/
3176
Larry Hastings2f936352014-08-05 14:04:04 +10003177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003178os_fdatasync_impl(PyObject *module, int fd)
3179/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003180{
3181 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003182}
3183#endif /* HAVE_FDATASYNC */
3184
3185
Fredrik Lundh10723342000-07-10 16:38:09 +00003186#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003187/*[clinic input]
3188os.chown
3189
3190 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3191 Path to be examined; can be string, bytes, or open-file-descriptor int.
3192
3193 uid: uid_t
3194
3195 gid: gid_t
3196
3197 *
3198
3199 dir_fd : dir_fd(requires='fchownat') = None
3200 If not None, it should be a file descriptor open to a directory,
3201 and path should be relative; path will then be relative to that
3202 directory.
3203
3204 follow_symlinks: bool = True
3205 If False, and the last element of the path is a symbolic link,
3206 stat will examine the symbolic link itself instead of the file
3207 the link points to.
3208
3209Change the owner and group id of path to the numeric uid and gid.\
3210
3211path may always be specified as a string.
3212On some platforms, path may also be specified as an open file descriptor.
3213 If this functionality is unavailable, using it raises an exception.
3214If dir_fd is not None, it should be a file descriptor open to a directory,
3215 and path should be relative; path will then be relative to that directory.
3216If follow_symlinks is False, and the last element of the path is a symbolic
3217 link, chown will modify the symbolic link itself instead of the file the
3218 link points to.
3219It is an error to use dir_fd or follow_symlinks when specifying path as
3220 an open file descriptor.
3221dir_fd and follow_symlinks may not be implemented on your platform.
3222 If they are unavailable, using them will raise a NotImplementedError.
3223
3224[clinic start generated code]*/
3225
Larry Hastings2f936352014-08-05 14:04:04 +10003226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003227os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003228 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003229/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003230{
3231 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003232
3233#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3234 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003235 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003236#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003237 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3238 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3239 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003240
3241#ifdef __APPLE__
3242 /*
3243 * This is for Mac OS X 10.3, which doesn't have lchown.
3244 * (But we still have an lchown symbol because of weak-linking.)
3245 * It doesn't have fchownat either. So there's no possibility
3246 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003247 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003248 if ((!follow_symlinks) && (lchown == NULL)) {
3249 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003250 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003251 }
3252#endif
3253
Victor Stinner8c62be82010-05-06 00:08:46 +00003254 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003255#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003256 if (path->fd != -1)
3257 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003258 else
3259#endif
3260#ifdef HAVE_LCHOWN
3261 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003262 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003263 else
3264#endif
3265#ifdef HAVE_FCHOWNAT
3266 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003267 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003268 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3269 else
3270#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003271 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003272 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003273
Larry Hastings2f936352014-08-05 14:04:04 +10003274 if (result)
3275 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003276
Larry Hastings2f936352014-08-05 14:04:04 +10003277 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003278}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003279#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003280
Larry Hastings2f936352014-08-05 14:04:04 +10003281
Christian Heimes4e30a842007-11-30 22:12:06 +00003282#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003283/*[clinic input]
3284os.fchown
3285
3286 fd: int
3287 uid: uid_t
3288 gid: gid_t
3289
3290Change the owner and group id of the file specified by file descriptor.
3291
3292Equivalent to os.chown(fd, uid, gid).
3293
3294[clinic start generated code]*/
3295
Larry Hastings2f936352014-08-05 14:04:04 +10003296static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003297os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3298/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003299{
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003301 int async_err = 0;
3302
3303 do {
3304 Py_BEGIN_ALLOW_THREADS
3305 res = fchown(fd, uid, gid);
3306 Py_END_ALLOW_THREADS
3307 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3308 if (res != 0)
3309 return (!async_err) ? posix_error() : NULL;
3310
Victor Stinner8c62be82010-05-06 00:08:46 +00003311 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003312}
3313#endif /* HAVE_FCHOWN */
3314
Larry Hastings2f936352014-08-05 14:04:04 +10003315
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003316#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003317/*[clinic input]
3318os.lchown
3319
3320 path : path_t
3321 uid: uid_t
3322 gid: gid_t
3323
3324Change the owner and group id of path to the numeric uid and gid.
3325
3326This function will not follow symbolic links.
3327Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3328[clinic start generated code]*/
3329
Larry Hastings2f936352014-08-05 14:04:04 +10003330static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003331os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3332/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003333{
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003336 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003338 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003339 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003340 }
Larry Hastings2f936352014-08-05 14:04:04 +10003341 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003342}
3343#endif /* HAVE_LCHOWN */
3344
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003345
Barry Warsaw53699e91996-12-10 23:23:01 +00003346static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003347posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003348{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003349 char *buf, *tmpbuf;
3350 char *cwd;
3351 const size_t chunk = 1024;
3352 size_t buflen = 0;
3353 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003354
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003355#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003356 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003357 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003358 wchar_t *wbuf2 = wbuf;
3359 PyObject *resobj;
3360 DWORD len;
3361 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003362 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003363 /* If the buffer is large enough, len does not include the
3364 terminating \0. If the buffer is too small, len includes
3365 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003366 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003367 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 if (wbuf2)
3369 len = GetCurrentDirectoryW(len, wbuf2);
3370 }
3371 Py_END_ALLOW_THREADS
3372 if (!wbuf2) {
3373 PyErr_NoMemory();
3374 return NULL;
3375 }
3376 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003377 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003378 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003379 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003380 }
3381 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003382 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003383 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003384 return resobj;
3385 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003386
3387 if (win32_warn_bytes_api())
3388 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003389#endif
3390
Victor Stinner4403d7d2015-04-25 00:16:10 +02003391 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003392 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003393 do {
3394 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003395#ifdef MS_WINDOWS
3396 if (buflen > INT_MAX) {
3397 PyErr_NoMemory();
3398 break;
3399 }
3400#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003401 tmpbuf = PyMem_RawRealloc(buf, buflen);
3402 if (tmpbuf == NULL)
3403 break;
3404
3405 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003406#ifdef MS_WINDOWS
3407 cwd = getcwd(buf, (int)buflen);
3408#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003409 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003410#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003411 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003412 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003413
3414 if (cwd == NULL) {
3415 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003416 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003417 }
3418
Victor Stinner8c62be82010-05-06 00:08:46 +00003419 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003420 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3421 else
3422 obj = PyUnicode_DecodeFSDefault(buf);
3423 PyMem_RawFree(buf);
3424
3425 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003426}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003427
Larry Hastings2f936352014-08-05 14:04:04 +10003428
3429/*[clinic input]
3430os.getcwd
3431
3432Return a unicode string representing the current working directory.
3433[clinic start generated code]*/
3434
Larry Hastings2f936352014-08-05 14:04:04 +10003435static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003436os_getcwd_impl(PyObject *module)
3437/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003438{
3439 return posix_getcwd(0);
3440}
3441
Larry Hastings2f936352014-08-05 14:04:04 +10003442
3443/*[clinic input]
3444os.getcwdb
3445
3446Return a bytes string representing the current working directory.
3447[clinic start generated code]*/
3448
Larry Hastings2f936352014-08-05 14:04:04 +10003449static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003450os_getcwdb_impl(PyObject *module)
3451/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003452{
3453 return posix_getcwd(1);
3454}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003455
Larry Hastings2f936352014-08-05 14:04:04 +10003456
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3458#define HAVE_LINK 1
3459#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003460
Guido van Rossumb6775db1994-08-01 11:34:53 +00003461#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003462/*[clinic input]
3463
3464os.link
3465
3466 src : path_t
3467 dst : path_t
3468 *
3469 src_dir_fd : dir_fd = None
3470 dst_dir_fd : dir_fd = None
3471 follow_symlinks: bool = True
3472
3473Create a hard link to a file.
3474
3475If either src_dir_fd or dst_dir_fd is not None, it should be a file
3476 descriptor open to a directory, and the respective path string (src or dst)
3477 should be relative; the path will then be relative to that directory.
3478If follow_symlinks is False, and the last element of src is a symbolic
3479 link, link will create a link to the symbolic link itself instead of the
3480 file the link points to.
3481src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3482 platform. If they are unavailable, using them will raise a
3483 NotImplementedError.
3484[clinic start generated code]*/
3485
Larry Hastings2f936352014-08-05 14:04:04 +10003486static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003487os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003488 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003489/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003490{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491#ifdef MS_WINDOWS
3492 BOOL result;
3493#else
3494 int result;
3495#endif
3496
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497#ifndef HAVE_LINKAT
3498 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3499 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003500 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 }
3502#endif
3503
Larry Hastings2f936352014-08-05 14:04:04 +10003504 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 PyErr_SetString(PyExc_NotImplementedError,
3506 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003507 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003509
Brian Curtin1b9df392010-11-24 20:24:31 +00003510#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003512 if (src->wide)
3513 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 else
Larry Hastings2f936352014-08-05 14:04:04 +10003515 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003517
Larry Hastings2f936352014-08-05 14:04:04 +10003518 if (!result)
3519 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520#else
3521 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003522#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3524 (dst_dir_fd != DEFAULT_DIR_FD) ||
3525 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003526 result = linkat(src_dir_fd, src->narrow,
3527 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3529 else
3530#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003531 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003533
Larry Hastings2f936352014-08-05 14:04:04 +10003534 if (result)
3535 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536#endif
3537
Larry Hastings2f936352014-08-05 14:04:04 +10003538 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003539}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003540#endif
3541
Brian Curtin1b9df392010-11-24 20:24:31 +00003542
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003543#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003544static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003546{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 PyObject *v;
3548 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3549 BOOL result;
3550 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003551 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003553 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555
Gregory P. Smith40a21602013-03-20 20:52:50 -07003556 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 WIN32_FIND_DATAW wFileData;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003558 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003559
Gregory P. Smith40a21602013-03-20 20:52:50 -07003560 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003561 po_wchars = L".";
3562 len = 1;
3563 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003564 po_wchars = path->wide;
3565 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003566 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003568 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 if (!wnamebuf) {
3570 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003573 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003575 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003576 if (wch != SEP && wch != ALTSEP && wch != L':')
3577 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 wcscpy(wnamebuf + len, L"*.*");
3579 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 if ((list = PyList_New(0)) == NULL) {
3581 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003583 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003584 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003585 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003586 if (hFindFile == INVALID_HANDLE_VALUE) {
3587 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588 if (error == ERROR_FILE_NOT_FOUND)
3589 goto exit;
3590 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003591 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 }
3594 do {
3595 /* Skip over . and .. */
3596 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3597 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598 v = PyUnicode_FromWideChar(wFileData.cFileName,
3599 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003600 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 Py_DECREF(list);
3602 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003603 break;
3604 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 Py_DECREF(list);
3608 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003609 break;
3610 }
3611 Py_DECREF(v);
3612 }
3613 Py_BEGIN_ALLOW_THREADS
3614 result = FindNextFileW(hFindFile, &wFileData);
3615 Py_END_ALLOW_THREADS
3616 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3617 it got to the end of the directory. */
3618 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003620 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003622 }
3623 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003624
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003626 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003627 strcpy(namebuf, path->narrow);
3628 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003629 if (len > 0) {
3630 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003631 if (ch != '\\' && ch != '/' && ch != ':')
3632 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 strcpy(namebuf + len, "*.*");
3634 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003635
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003638
Antoine Pitroub73caab2010-08-09 23:39:31 +00003639 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003640 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003641 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003642 if (hFindFile == INVALID_HANDLE_VALUE) {
3643 int error = GetLastError();
3644 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 goto exit;
3646 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003647 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003648 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003649 }
3650 do {
3651 /* Skip over . and .. */
3652 if (strcmp(FileData.cFileName, ".") != 0 &&
3653 strcmp(FileData.cFileName, "..") != 0) {
3654 v = PyBytes_FromString(FileData.cFileName);
3655 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003656 Py_DECREF(list);
3657 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 break;
3659 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003661 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 Py_DECREF(list);
3663 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 break;
3665 }
3666 Py_DECREF(v);
3667 }
3668 Py_BEGIN_ALLOW_THREADS
3669 result = FindNextFile(hFindFile, &FileData);
3670 Py_END_ALLOW_THREADS
3671 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3672 it got to the end of the directory. */
3673 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003675 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 }
3678 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003679
Larry Hastings9cf065c2012-06-22 16:30:09 -07003680exit:
3681 if (hFindFile != INVALID_HANDLE_VALUE) {
3682 if (FindClose(hFindFile) == FALSE) {
3683 if (list != NULL) {
3684 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003685 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003686 }
3687 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003688 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003689 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003690
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003692} /* end of _listdir_windows_no_opendir */
3693
3694#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3695
3696static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003697_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003698{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003699 PyObject *v;
3700 DIR *dirp = NULL;
3701 struct dirent *ep;
3702 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003703#ifdef HAVE_FDOPENDIR
3704 int fd = -1;
3705#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003706
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003709 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003711 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003712 if (fd == -1)
3713 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003714
Larry Hastingsfdaea062012-06-25 04:42:23 -07003715 return_str = 1;
3716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717 Py_BEGIN_ALLOW_THREADS
3718 dirp = fdopendir(fd);
3719 Py_END_ALLOW_THREADS
3720 }
3721 else
3722#endif
3723 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003724 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003725 if (path->narrow) {
3726 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003727 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003728 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003729 }
3730 else {
3731 name = ".";
3732 return_str = 1;
3733 }
3734
Larry Hastings9cf065c2012-06-22 16:30:09 -07003735 Py_BEGIN_ALLOW_THREADS
3736 dirp = opendir(name);
3737 Py_END_ALLOW_THREADS
3738 }
3739
3740 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003741 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003742#ifdef HAVE_FDOPENDIR
3743 if (fd != -1) {
3744 Py_BEGIN_ALLOW_THREADS
3745 close(fd);
3746 Py_END_ALLOW_THREADS
3747 }
3748#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003749 goto exit;
3750 }
3751 if ((list = PyList_New(0)) == NULL) {
3752 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 }
3754 for (;;) {
3755 errno = 0;
3756 Py_BEGIN_ALLOW_THREADS
3757 ep = readdir(dirp);
3758 Py_END_ALLOW_THREADS
3759 if (ep == NULL) {
3760 if (errno == 0) {
3761 break;
3762 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003763 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003764 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003765 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003766 }
3767 }
3768 if (ep->d_name[0] == '.' &&
3769 (NAMLEN(ep) == 1 ||
3770 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3771 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003772 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003773 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3774 else
3775 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003777 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 break;
3779 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003780 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003782 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 break;
3784 }
3785 Py_DECREF(v);
3786 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003787
Larry Hastings9cf065c2012-06-22 16:30:09 -07003788exit:
3789 if (dirp != NULL) {
3790 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003791#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003792 if (fd > -1)
3793 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003794#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003795 closedir(dirp);
3796 Py_END_ALLOW_THREADS
3797 }
3798
Larry Hastings9cf065c2012-06-22 16:30:09 -07003799 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003800} /* end of _posix_listdir */
3801#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003802
Larry Hastings2f936352014-08-05 14:04:04 +10003803
3804/*[clinic input]
3805os.listdir
3806
3807 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3808
3809Return a list containing the names of the files in the directory.
3810
3811path can be specified as either str or bytes. If path is bytes,
3812 the filenames returned will also be bytes; in all other circumstances
3813 the filenames returned will be str.
3814If path is None, uses the path='.'.
3815On some platforms, path may also be specified as an open file descriptor;\
3816 the file descriptor must refer to a directory.
3817 If this functionality is unavailable, using it raises NotImplementedError.
3818
3819The list is in arbitrary order. It does not include the special
3820entries '.' and '..' even if they are present in the directory.
3821
3822
3823[clinic start generated code]*/
3824
Larry Hastings2f936352014-08-05 14:04:04 +10003825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003826os_listdir_impl(PyObject *module, path_t *path)
3827/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003828{
3829#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3830 return _listdir_windows_no_opendir(path, NULL);
3831#else
3832 return _posix_listdir(path, NULL);
3833#endif
3834}
3835
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003836#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003837/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003838/*[clinic input]
3839os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003840
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003841 path: path_t
3842 /
3843
3844[clinic start generated code]*/
3845
3846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003847os__getfullpathname_impl(PyObject *module, path_t *path)
3848/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003849{
3850 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003851 {
Victor Stinner75875072013-11-24 19:23:25 +01003852 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003853 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003854 DWORD result;
3855 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003856
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003857 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003858 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003859 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003860 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003861 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003862 if (!woutbufp)
3863 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003864 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003865 }
3866 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003867 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003868 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003869 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003870 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003871 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003872 return v;
3873 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003874 else {
3875 char outbuf[MAX_PATH];
3876 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003877
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003878 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3879 outbuf, &temp)) {
3880 win32_error_object("GetFullPathName", path->object);
3881 return NULL;
3882 }
3883 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003884 }
Larry Hastings2f936352014-08-05 14:04:04 +10003885}
Brian Curtind40e6f72010-07-08 21:39:08 +00003886
Brian Curtind25aef52011-06-13 15:16:04 -05003887
Larry Hastings2f936352014-08-05 14:04:04 +10003888/*[clinic input]
3889os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003890
Larry Hastings2f936352014-08-05 14:04:04 +10003891 path: unicode
3892 /
3893
3894A helper function for samepath on windows.
3895[clinic start generated code]*/
3896
Larry Hastings2f936352014-08-05 14:04:04 +10003897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003898os__getfinalpathname_impl(PyObject *module, PyObject *path)
3899/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003900{
3901 HANDLE hFile;
3902 int buf_size;
3903 wchar_t *target_path;
3904 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003905 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003906 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003907
Larry Hastings2f936352014-08-05 14:04:04 +10003908 path_wchar = PyUnicode_AsUnicode(path);
3909 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003910 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003911
Brian Curtind40e6f72010-07-08 21:39:08 +00003912 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003913 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003914 0, /* desired access */
3915 0, /* share mode */
3916 NULL, /* security attributes */
3917 OPEN_EXISTING,
3918 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3919 FILE_FLAG_BACKUP_SEMANTICS,
3920 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003921
Victor Stinnereb5657a2011-09-30 01:44:27 +02003922 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003923 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003924
3925 /* We have a good handle to the target, use it to determine the
3926 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003927 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003928
3929 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003930 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003931
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003932 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003933 if(!target_path)
3934 return PyErr_NoMemory();
3935
Steve Dower2ea51c92015-03-20 21:49:12 -07003936 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3937 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003938 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003939 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003940
3941 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003942 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003943
3944 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003945 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003946 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003947 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003948}
Brian Curtin62857742010-09-06 17:07:27 +00003949
Brian Curtin95d028f2011-06-09 09:10:38 -05003950PyDoc_STRVAR(posix__isdir__doc__,
3951"Return true if the pathname refers to an existing directory.");
3952
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003953/*[clinic input]
3954os._isdir
3955
3956 path: path_t
3957 /
3958
3959[clinic start generated code]*/
3960
Brian Curtin9c669cc2011-06-08 18:17:18 -05003961static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003962os__isdir_impl(PyObject *module, path_t *path)
3963/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003964{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003965 DWORD attributes;
3966
Steve Dowerb22a6772016-07-17 20:49:38 -07003967 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003968 if (!path->narrow)
3969 attributes = GetFileAttributesW(path->wide);
3970 else
3971 attributes = GetFileAttributesA(path->narrow);
Steve Dowerb22a6772016-07-17 20:49:38 -07003972 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003973
Brian Curtin9c669cc2011-06-08 18:17:18 -05003974 if (attributes == INVALID_FILE_ATTRIBUTES)
3975 Py_RETURN_FALSE;
3976
Brian Curtin9c669cc2011-06-08 18:17:18 -05003977 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3978 Py_RETURN_TRUE;
3979 else
3980 Py_RETURN_FALSE;
3981}
Tim Golden6b528062013-08-01 12:44:00 +01003982
Tim Golden6b528062013-08-01 12:44:00 +01003983
Larry Hastings2f936352014-08-05 14:04:04 +10003984/*[clinic input]
3985os._getvolumepathname
3986
3987 path: unicode
3988
3989A helper function for ismount on Win32.
3990[clinic start generated code]*/
3991
Larry Hastings2f936352014-08-05 14:04:04 +10003992static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003993os__getvolumepathname_impl(PyObject *module, PyObject *path)
3994/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003995{
3996 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003997 const wchar_t *path_wchar;
3998 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003999 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01004000 BOOL ret;
4001
Larry Hastings2f936352014-08-05 14:04:04 +10004002 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
4003 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01004004 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01004005 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01004006
4007 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01004008 buflen = Py_MAX(buflen, MAX_PATH);
4009
4010 if (buflen > DWORD_MAX) {
4011 PyErr_SetString(PyExc_OverflowError, "path too long");
4012 return NULL;
4013 }
4014
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02004015 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01004016 if (mountpath == NULL)
4017 return PyErr_NoMemory();
4018
4019 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004020 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01004021 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01004022 Py_END_ALLOW_THREADS
4023
4024 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10004025 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01004026 goto exit;
4027 }
4028 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
4029
4030exit:
4031 PyMem_Free(mountpath);
4032 return result;
4033}
Tim Golden6b528062013-08-01 12:44:00 +01004034
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00004035#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00004036
Larry Hastings2f936352014-08-05 14:04:04 +10004037
4038/*[clinic input]
4039os.mkdir
4040
4041 path : path_t
4042
4043 mode: int = 0o777
4044
4045 *
4046
4047 dir_fd : dir_fd(requires='mkdirat') = None
4048
4049# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4050
4051Create a directory.
4052
4053If dir_fd is not None, it should be a file descriptor open to a directory,
4054 and path should be relative; path will then be relative to that directory.
4055dir_fd may not be implemented on your platform.
4056 If it is unavailable, using it will raise a NotImplementedError.
4057
4058The mode argument is ignored on Windows.
4059[clinic start generated code]*/
4060
Larry Hastings2f936352014-08-05 14:04:04 +10004061static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004062os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4063/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004064{
4065 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004066
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004067#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004068 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004069 if (path->wide)
4070 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004071 else
Larry Hastings2f936352014-08-05 14:04:04 +10004072 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004073 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004074
Larry Hastings2f936352014-08-05 14:04:04 +10004075 if (!result)
4076 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004077#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004078 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004079#if HAVE_MKDIRAT
4080 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004081 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004082 else
4083#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004084#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004085 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004086#else
Larry Hastings2f936352014-08-05 14:04:04 +10004087 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004088#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004089 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004090 if (result < 0)
4091 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004092#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004093 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004094}
4095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004096
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004097/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4098#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004099#include <sys/resource.h>
4100#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004101
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004102
4103#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004104/*[clinic input]
4105os.nice
4106
4107 increment: int
4108 /
4109
4110Add increment to the priority of process and return the new priority.
4111[clinic start generated code]*/
4112
Larry Hastings2f936352014-08-05 14:04:04 +10004113static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004114os_nice_impl(PyObject *module, int increment)
4115/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004116{
4117 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004118
Victor Stinner8c62be82010-05-06 00:08:46 +00004119 /* There are two flavours of 'nice': one that returns the new
4120 priority (as required by almost all standards out there) and the
4121 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4122 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004123
Victor Stinner8c62be82010-05-06 00:08:46 +00004124 If we are of the nice family that returns the new priority, we
4125 need to clear errno before the call, and check if errno is filled
4126 before calling posix_error() on a returnvalue of -1, because the
4127 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004128
Victor Stinner8c62be82010-05-06 00:08:46 +00004129 errno = 0;
4130 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004131#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004132 if (value == 0)
4133 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004134#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004135 if (value == -1 && errno != 0)
4136 /* either nice() or getpriority() returned an error */
4137 return posix_error();
4138 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004139}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004140#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004141
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004142
4143#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004144/*[clinic input]
4145os.getpriority
4146
4147 which: int
4148 who: int
4149
4150Return program scheduling priority.
4151[clinic start generated code]*/
4152
Larry Hastings2f936352014-08-05 14:04:04 +10004153static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004154os_getpriority_impl(PyObject *module, int which, int who)
4155/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004156{
4157 int retval;
4158
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004159 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004160 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004161 if (errno != 0)
4162 return posix_error();
4163 return PyLong_FromLong((long)retval);
4164}
4165#endif /* HAVE_GETPRIORITY */
4166
4167
4168#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004169/*[clinic input]
4170os.setpriority
4171
4172 which: int
4173 who: int
4174 priority: int
4175
4176Set program scheduling priority.
4177[clinic start generated code]*/
4178
Larry Hastings2f936352014-08-05 14:04:04 +10004179static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004180os_setpriority_impl(PyObject *module, int which, int who, int priority)
4181/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004182{
4183 int retval;
4184
4185 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004186 if (retval == -1)
4187 return posix_error();
4188 Py_RETURN_NONE;
4189}
4190#endif /* HAVE_SETPRIORITY */
4191
4192
Barry Warsaw53699e91996-12-10 23:23:01 +00004193static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004194internal_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 +00004195{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004196 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004197 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004198
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004199#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004200 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004201 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004202#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004203 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004204#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004205
Larry Hastings9cf065c2012-06-22 16:30:09 -07004206 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4207 (dst_dir_fd != DEFAULT_DIR_FD);
4208#ifndef HAVE_RENAMEAT
4209 if (dir_fd_specified) {
4210 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004211 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004212 }
4213#endif
4214
Larry Hastings2f936352014-08-05 14:04:04 +10004215 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004216 PyErr_Format(PyExc_ValueError,
4217 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004218 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004219 }
4220
4221#ifdef MS_WINDOWS
4222 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004223 if (src->wide)
4224 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004225 else
Larry Hastings2f936352014-08-05 14:04:04 +10004226 result = MoveFileExA(src->narrow, dst->narrow, flags);
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_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004231
4232#else
4233 Py_BEGIN_ALLOW_THREADS
4234#ifdef HAVE_RENAMEAT
4235 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004236 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004237 else
4238#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004239 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004240 Py_END_ALLOW_THREADS
4241
Larry Hastings2f936352014-08-05 14:04:04 +10004242 if (result)
4243 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004244#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004245 Py_RETURN_NONE;
4246}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004247
Larry Hastings2f936352014-08-05 14:04:04 +10004248
4249/*[clinic input]
4250os.rename
4251
4252 src : path_t
4253 dst : path_t
4254 *
4255 src_dir_fd : dir_fd = None
4256 dst_dir_fd : dir_fd = None
4257
4258Rename a file or directory.
4259
4260If either src_dir_fd or dst_dir_fd is not None, it should be a file
4261 descriptor open to a directory, and the respective path string (src or dst)
4262 should be relative; the path will then be relative to that directory.
4263src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4264 If they are unavailable, using them will raise a NotImplementedError.
4265[clinic start generated code]*/
4266
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004267static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004268os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004269 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004270/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004271{
Larry Hastings2f936352014-08-05 14:04:04 +10004272 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004273}
4274
Larry Hastings2f936352014-08-05 14:04:04 +10004275
4276/*[clinic input]
4277os.replace = os.rename
4278
4279Rename a file or directory, overwriting the destination.
4280
4281If either src_dir_fd or dst_dir_fd is not None, it should be a file
4282 descriptor open to a directory, and the respective path string (src or dst)
4283 should be relative; the path will then be relative to that directory.
4284src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4285 If they are unavailable, using them will raise a NotImplementedError."
4286[clinic start generated code]*/
4287
Larry Hastings2f936352014-08-05 14:04:04 +10004288static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004289os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4290 int dst_dir_fd)
4291/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004292{
4293 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4294}
4295
4296
4297/*[clinic input]
4298os.rmdir
4299
4300 path: path_t
4301 *
4302 dir_fd: dir_fd(requires='unlinkat') = None
4303
4304Remove a directory.
4305
4306If dir_fd is not None, it should be a file descriptor open to a directory,
4307 and path should be relative; path will then be relative to that directory.
4308dir_fd may not be implemented on your platform.
4309 If it is unavailable, using it will raise a NotImplementedError.
4310[clinic start generated code]*/
4311
Larry Hastings2f936352014-08-05 14:04:04 +10004312static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004313os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4314/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004315{
4316 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004317
4318 Py_BEGIN_ALLOW_THREADS
4319#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004320 if (path->wide)
4321 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004322 else
Larry Hastings2f936352014-08-05 14:04:04 +10004323 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004324 result = !result; /* Windows, success=1, UNIX, success=0 */
4325#else
4326#ifdef HAVE_UNLINKAT
4327 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004328 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004329 else
4330#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004331 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004332#endif
4333 Py_END_ALLOW_THREADS
4334
Larry Hastings2f936352014-08-05 14:04:04 +10004335 if (result)
4336 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004337
Larry Hastings2f936352014-08-05 14:04:04 +10004338 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004339}
4340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004342#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004343#ifdef MS_WINDOWS
4344/*[clinic input]
4345os.system -> long
4346
4347 command: Py_UNICODE
4348
4349Execute the command in a subshell.
4350[clinic start generated code]*/
4351
Larry Hastings2f936352014-08-05 14:04:04 +10004352static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004353os_system_impl(PyObject *module, Py_UNICODE *command)
4354/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004355{
4356 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004357 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004358 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004359 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004360 return result;
4361}
4362#else /* MS_WINDOWS */
4363/*[clinic input]
4364os.system -> long
4365
4366 command: FSConverter
4367
4368Execute the command in a subshell.
4369[clinic start generated code]*/
4370
Larry Hastings2f936352014-08-05 14:04:04 +10004371static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004372os_system_impl(PyObject *module, PyObject *command)
4373/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004374{
4375 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004376 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004377 Py_BEGIN_ALLOW_THREADS
4378 result = system(bytes);
4379 Py_END_ALLOW_THREADS
4380 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004381}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004382#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004383#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004384
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004385
Larry Hastings2f936352014-08-05 14:04:04 +10004386/*[clinic input]
4387os.umask
4388
4389 mask: int
4390 /
4391
4392Set the current numeric umask and return the previous umask.
4393[clinic start generated code]*/
4394
Larry Hastings2f936352014-08-05 14:04:04 +10004395static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004396os_umask_impl(PyObject *module, int mask)
4397/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004398{
4399 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004400 if (i < 0)
4401 return posix_error();
4402 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004403}
4404
Brian Curtind40e6f72010-07-08 21:39:08 +00004405#ifdef MS_WINDOWS
4406
4407/* override the default DeleteFileW behavior so that directory
4408symlinks can be removed with this function, the same as with
4409Unix symlinks */
4410BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4411{
4412 WIN32_FILE_ATTRIBUTE_DATA info;
4413 WIN32_FIND_DATAW find_data;
4414 HANDLE find_data_handle;
4415 int is_directory = 0;
4416 int is_link = 0;
4417
4418 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4419 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004420
Brian Curtind40e6f72010-07-08 21:39:08 +00004421 /* Get WIN32_FIND_DATA structure for the path to determine if
4422 it is a symlink */
4423 if(is_directory &&
4424 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4425 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4426
4427 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004428 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4429 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4430 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4431 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004432 FindClose(find_data_handle);
4433 }
4434 }
4435 }
4436
4437 if (is_directory && is_link)
4438 return RemoveDirectoryW(lpFileName);
4439
4440 return DeleteFileW(lpFileName);
4441}
4442#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004443
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004444
Larry Hastings2f936352014-08-05 14:04:04 +10004445/*[clinic input]
4446os.unlink
4447
4448 path: path_t
4449 *
4450 dir_fd: dir_fd(requires='unlinkat')=None
4451
4452Remove a file (same as remove()).
4453
4454If dir_fd is not None, it should be a file descriptor open to a directory,
4455 and path should be relative; path will then be relative to that directory.
4456dir_fd may not be implemented on your platform.
4457 If it is unavailable, using it will raise a NotImplementedError.
4458
4459[clinic start generated code]*/
4460
Larry Hastings2f936352014-08-05 14:04:04 +10004461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004462os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4463/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004464{
4465 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004466
4467 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004468 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004469#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004470 if (path->wide)
4471 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004472 else
Larry Hastings2f936352014-08-05 14:04:04 +10004473 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004474 result = !result; /* Windows, success=1, UNIX, success=0 */
4475#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004476#ifdef HAVE_UNLINKAT
4477 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004478 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004479 else
4480#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004481 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004482#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004483 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004484 Py_END_ALLOW_THREADS
4485
Larry Hastings2f936352014-08-05 14:04:04 +10004486 if (result)
4487 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004488
Larry Hastings2f936352014-08-05 14:04:04 +10004489 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004490}
4491
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004492
Larry Hastings2f936352014-08-05 14:04:04 +10004493/*[clinic input]
4494os.remove = os.unlink
4495
4496Remove a file (same as unlink()).
4497
4498If dir_fd is not None, it should be a file descriptor open to a directory,
4499 and path should be relative; path will then be relative to that directory.
4500dir_fd may not be implemented on your platform.
4501 If it is unavailable, using it will raise a NotImplementedError.
4502[clinic start generated code]*/
4503
Larry Hastings2f936352014-08-05 14:04:04 +10004504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004505os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4506/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004507{
4508 return os_unlink_impl(module, path, dir_fd);
4509}
4510
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004511
Larry Hastings605a62d2012-06-24 04:33:36 -07004512static PyStructSequence_Field uname_result_fields[] = {
4513 {"sysname", "operating system name"},
4514 {"nodename", "name of machine on network (implementation-defined)"},
4515 {"release", "operating system release"},
4516 {"version", "operating system version"},
4517 {"machine", "hardware identifier"},
4518 {NULL}
4519};
4520
4521PyDoc_STRVAR(uname_result__doc__,
4522"uname_result: Result from os.uname().\n\n\
4523This object may be accessed either as a tuple of\n\
4524 (sysname, nodename, release, version, machine),\n\
4525or via the attributes sysname, nodename, release, version, and machine.\n\
4526\n\
4527See os.uname for more information.");
4528
4529static PyStructSequence_Desc uname_result_desc = {
4530 "uname_result", /* name */
4531 uname_result__doc__, /* doc */
4532 uname_result_fields,
4533 5
4534};
4535
4536static PyTypeObject UnameResultType;
4537
4538
4539#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004540/*[clinic input]
4541os.uname
4542
4543Return an object identifying the current operating system.
4544
4545The object behaves like a named tuple with the following fields:
4546 (sysname, nodename, release, version, machine)
4547
4548[clinic start generated code]*/
4549
Larry Hastings2f936352014-08-05 14:04:04 +10004550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004551os_uname_impl(PyObject *module)
4552/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004553{
Victor Stinner8c62be82010-05-06 00:08:46 +00004554 struct utsname u;
4555 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004556 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004557
Victor Stinner8c62be82010-05-06 00:08:46 +00004558 Py_BEGIN_ALLOW_THREADS
4559 res = uname(&u);
4560 Py_END_ALLOW_THREADS
4561 if (res < 0)
4562 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004563
4564 value = PyStructSequence_New(&UnameResultType);
4565 if (value == NULL)
4566 return NULL;
4567
4568#define SET(i, field) \
4569 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004570 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004571 if (!o) { \
4572 Py_DECREF(value); \
4573 return NULL; \
4574 } \
4575 PyStructSequence_SET_ITEM(value, i, o); \
4576 } \
4577
4578 SET(0, u.sysname);
4579 SET(1, u.nodename);
4580 SET(2, u.release);
4581 SET(3, u.version);
4582 SET(4, u.machine);
4583
4584#undef SET
4585
4586 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004587}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004588#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004589
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004590
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591
4592typedef struct {
4593 int now;
4594 time_t atime_s;
4595 long atime_ns;
4596 time_t mtime_s;
4597 long mtime_ns;
4598} utime_t;
4599
4600/*
Victor Stinner484df002014-10-09 13:52:31 +02004601 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602 * they also intentionally leak the declaration of a pointer named "time"
4603 */
4604#define UTIME_TO_TIMESPEC \
4605 struct timespec ts[2]; \
4606 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004607 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608 time = NULL; \
4609 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004610 ts[0].tv_sec = ut->atime_s; \
4611 ts[0].tv_nsec = ut->atime_ns; \
4612 ts[1].tv_sec = ut->mtime_s; \
4613 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004614 time = ts; \
4615 } \
4616
4617#define UTIME_TO_TIMEVAL \
4618 struct timeval tv[2]; \
4619 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004620 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621 time = NULL; \
4622 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004623 tv[0].tv_sec = ut->atime_s; \
4624 tv[0].tv_usec = ut->atime_ns / 1000; \
4625 tv[1].tv_sec = ut->mtime_s; \
4626 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004627 time = tv; \
4628 } \
4629
4630#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004631 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004633 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634 time = NULL; \
4635 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004636 u.actime = ut->atime_s; \
4637 u.modtime = ut->mtime_s; \
4638 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639 }
4640
4641#define UTIME_TO_TIME_T \
4642 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004643 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004644 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004645 time = NULL; \
4646 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004647 timet[0] = ut->atime_s; \
4648 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004649 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650 } \
4651
4652
Victor Stinner528a9ab2015-09-03 21:30:26 +02004653#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004654
4655static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004656utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657{
4658#ifdef HAVE_UTIMENSAT
4659 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4660 UTIME_TO_TIMESPEC;
4661 return utimensat(dir_fd, path, time, flags);
4662#elif defined(HAVE_FUTIMESAT)
4663 UTIME_TO_TIMEVAL;
4664 /*
4665 * follow_symlinks will never be false here;
4666 * we only allow !follow_symlinks and dir_fd together
4667 * if we have utimensat()
4668 */
4669 assert(follow_symlinks);
4670 return futimesat(dir_fd, path, time);
4671#endif
4672}
4673
Larry Hastings2f936352014-08-05 14:04:04 +10004674 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4675#else
4676 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004677#endif
4678
Victor Stinner528a9ab2015-09-03 21:30:26 +02004679#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004680
4681static int
Victor Stinner484df002014-10-09 13:52:31 +02004682utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004683{
4684#ifdef HAVE_FUTIMENS
4685 UTIME_TO_TIMESPEC;
4686 return futimens(fd, time);
4687#else
4688 UTIME_TO_TIMEVAL;
4689 return futimes(fd, time);
4690#endif
4691}
4692
Larry Hastings2f936352014-08-05 14:04:04 +10004693 #define PATH_UTIME_HAVE_FD 1
4694#else
4695 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004696#endif
4697
Victor Stinner5ebae872015-09-22 01:29:33 +02004698#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4699# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4700#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004701
Victor Stinner4552ced2015-09-21 22:37:15 +02004702#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703
4704static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004705utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004706{
4707#ifdef HAVE_UTIMENSAT
4708 UTIME_TO_TIMESPEC;
4709 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4710#else
4711 UTIME_TO_TIMEVAL;
4712 return lutimes(path, time);
4713#endif
4714}
4715
4716#endif
4717
4718#ifndef MS_WINDOWS
4719
4720static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004721utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722{
4723#ifdef HAVE_UTIMENSAT
4724 UTIME_TO_TIMESPEC;
4725 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4726#elif defined(HAVE_UTIMES)
4727 UTIME_TO_TIMEVAL;
4728 return utimes(path, time);
4729#elif defined(HAVE_UTIME_H)
4730 UTIME_TO_UTIMBUF;
4731 return utime(path, time);
4732#else
4733 UTIME_TO_TIME_T;
4734 return utime(path, time);
4735#endif
4736}
4737
4738#endif
4739
Larry Hastings76ad59b2012-05-03 00:30:07 -07004740static int
4741split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4742{
4743 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004744 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004745 divmod = PyNumber_Divmod(py_long, billion);
4746 if (!divmod)
4747 goto exit;
4748 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4749 if ((*s == -1) && PyErr_Occurred())
4750 goto exit;
4751 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004752 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004753 goto exit;
4754
4755 result = 1;
4756exit:
4757 Py_XDECREF(divmod);
4758 return result;
4759}
4760
Larry Hastings2f936352014-08-05 14:04:04 +10004761
4762/*[clinic input]
4763os.utime
4764
4765 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4766 times: object = NULL
4767 *
4768 ns: object = NULL
4769 dir_fd: dir_fd(requires='futimensat') = None
4770 follow_symlinks: bool=True
4771
Martin Panter0ff89092015-09-09 01:56:53 +00004772# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004773
4774Set the access and modified time of path.
4775
4776path may always be specified as a string.
4777On some platforms, path may also be specified as an open file descriptor.
4778 If this functionality is unavailable, using it raises an exception.
4779
4780If times is not None, it must be a tuple (atime, mtime);
4781 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004782If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004783 atime_ns and mtime_ns should be expressed as integer nanoseconds
4784 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004785If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004786Specifying tuples for both times and ns is an error.
4787
4788If dir_fd is not None, it should be a file descriptor open to a directory,
4789 and path should be relative; path will then be relative to that directory.
4790If follow_symlinks is False, and the last element of the path is a symbolic
4791 link, utime will modify the symbolic link itself instead of the file the
4792 link points to.
4793It is an error to use dir_fd or follow_symlinks when specifying path
4794 as an open file descriptor.
4795dir_fd and follow_symlinks may not be available on your platform.
4796 If they are unavailable, using them will raise a NotImplementedError.
4797
4798[clinic start generated code]*/
4799
Larry Hastings2f936352014-08-05 14:04:04 +10004800static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004801os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4802 int dir_fd, int follow_symlinks)
4803/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004804{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805#ifdef MS_WINDOWS
4806 HANDLE hFile;
4807 FILETIME atime, mtime;
4808#else
4809 int result;
4810#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004813 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004814
Christian Heimesb3c87242013-08-01 00:08:16 +02004815 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004816
Larry Hastings9cf065c2012-06-22 16:30:09 -07004817 if (times && (times != Py_None) && ns) {
4818 PyErr_SetString(PyExc_ValueError,
4819 "utime: you may specify either 'times'"
4820 " or 'ns' but not both");
4821 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004822 }
4823
4824 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004825 time_t a_sec, m_sec;
4826 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004827 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828 PyErr_SetString(PyExc_TypeError,
4829 "utime: 'times' must be either"
4830 " a tuple of two ints or None");
4831 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004832 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004834 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004835 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004836 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004837 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004839 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004840 utime.atime_s = a_sec;
4841 utime.atime_ns = a_nsec;
4842 utime.mtime_s = m_sec;
4843 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004844 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004846 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004847 PyErr_SetString(PyExc_TypeError,
4848 "utime: 'ns' must be a tuple of two ints");
4849 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004850 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004852 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004854 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004855 &utime.mtime_s, &utime.mtime_ns)) {
4856 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004857 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 }
4859 else {
4860 /* times and ns are both None/unspecified. use "now". */
4861 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004862 }
4863
Victor Stinner4552ced2015-09-21 22:37:15 +02004864#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865 if (follow_symlinks_specified("utime", follow_symlinks))
4866 goto exit;
4867#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004868
Larry Hastings2f936352014-08-05 14:04:04 +10004869 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4870 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4871 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004872 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004873
Larry Hastings9cf065c2012-06-22 16:30:09 -07004874#if !defined(HAVE_UTIMENSAT)
4875 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004876 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004877 "utime: cannot use dir_fd and follow_symlinks "
4878 "together on this platform");
4879 goto exit;
4880 }
4881#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004882
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004883#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004884 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004885 if (path->wide)
4886 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004887 NULL, OPEN_EXISTING,
4888 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 else
Larry Hastings2f936352014-08-05 14:04:04 +10004890 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004891 NULL, OPEN_EXISTING,
4892 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004893 Py_END_ALLOW_THREADS
4894 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004895 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004896 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004897 }
4898
Larry Hastings9cf065c2012-06-22 16:30:09 -07004899 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004900 GetSystemTimeAsFileTime(&mtime);
4901 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004904 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4905 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 }
4907 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4908 /* Avoid putting the file name into the error here,
4909 as that may confuse the user into believing that
4910 something is wrong with the file, when it also
4911 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004912 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004913 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004915#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004916 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004917
Victor Stinner4552ced2015-09-21 22:37:15 +02004918#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004919 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004920 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004921 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004922#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004923
Victor Stinner528a9ab2015-09-03 21:30:26 +02004924#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004925 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004926 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004927 else
4928#endif
4929
Victor Stinner528a9ab2015-09-03 21:30:26 +02004930#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004931 if (path->fd != -1)
4932 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004933 else
4934#endif
4935
Larry Hastings2f936352014-08-05 14:04:04 +10004936 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004937
4938 Py_END_ALLOW_THREADS
4939
4940 if (result < 0) {
4941 /* see previous comment about not putting filename in error here */
4942 return_value = posix_error();
4943 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004945
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004946#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004947
4948 Py_INCREF(Py_None);
4949 return_value = Py_None;
4950
4951exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004952#ifdef MS_WINDOWS
4953 if (hFile != INVALID_HANDLE_VALUE)
4954 CloseHandle(hFile);
4955#endif
4956 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004957}
4958
Guido van Rossum3b066191991-06-04 19:40:25 +00004959/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004960
Larry Hastings2f936352014-08-05 14:04:04 +10004961
4962/*[clinic input]
4963os._exit
4964
4965 status: int
4966
4967Exit to the system with specified status, without normal exit processing.
4968[clinic start generated code]*/
4969
Larry Hastings2f936352014-08-05 14:04:04 +10004970static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004971os__exit_impl(PyObject *module, int status)
4972/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004973{
4974 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004976}
4977
Martin v. Löwis114619e2002-10-07 06:44:21 +00004978#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4979static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004980free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004981{
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 Py_ssize_t i;
4983 for (i = 0; i < count; i++)
4984 PyMem_Free(array[i]);
4985 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004986}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004987
Antoine Pitrou69f71142009-05-24 21:25:49 +00004988static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004989int fsconvert_strdup(PyObject *o, char**out)
4990{
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 PyObject *bytes;
4992 Py_ssize_t size;
4993 if (!PyUnicode_FSConverter(o, &bytes))
4994 return 0;
4995 size = PyBytes_GET_SIZE(bytes);
4996 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004997 if (!*out) {
4998 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01005000 }
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 memcpy(*out, PyBytes_AsString(bytes), size+1);
5002 Py_DECREF(bytes);
5003 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00005004}
Martin v. Löwis114619e2002-10-07 06:44:21 +00005005#endif
5006
Ross Lagerwall7807c352011-03-17 20:20:30 +02005007#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00005008static char**
5009parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
5010{
Victor Stinner8c62be82010-05-06 00:08:46 +00005011 char **envlist;
5012 Py_ssize_t i, pos, envc;
5013 PyObject *keys=NULL, *vals=NULL;
5014 PyObject *key, *val, *key2, *val2;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005015 char *p;
5016 const char *k, *v;
Victor Stinner8c62be82010-05-06 00:08:46 +00005017 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005018
Victor Stinner8c62be82010-05-06 00:08:46 +00005019 i = PyMapping_Size(env);
5020 if (i < 0)
5021 return NULL;
5022 envlist = PyMem_NEW(char *, i + 1);
5023 if (envlist == NULL) {
5024 PyErr_NoMemory();
5025 return NULL;
5026 }
5027 envc = 0;
5028 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005029 if (!keys)
5030 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005031 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01005032 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 goto error;
5034 if (!PyList_Check(keys) || !PyList_Check(vals)) {
5035 PyErr_Format(PyExc_TypeError,
5036 "env.keys() or env.values() is not a list");
5037 goto error;
5038 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005039
Victor Stinner8c62be82010-05-06 00:08:46 +00005040 for (pos = 0; pos < i; pos++) {
5041 key = PyList_GetItem(keys, pos);
5042 val = PyList_GetItem(vals, pos);
5043 if (!key || !val)
5044 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005045
Victor Stinner8c62be82010-05-06 00:08:46 +00005046 if (PyUnicode_FSConverter(key, &key2) == 0)
5047 goto error;
5048 if (PyUnicode_FSConverter(val, &val2) == 0) {
5049 Py_DECREF(key2);
5050 goto error;
5051 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005052
Victor Stinner8c62be82010-05-06 00:08:46 +00005053 k = PyBytes_AsString(key2);
5054 v = PyBytes_AsString(val2);
5055 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005056
Victor Stinner8c62be82010-05-06 00:08:46 +00005057 p = PyMem_NEW(char, len);
5058 if (p == NULL) {
5059 PyErr_NoMemory();
5060 Py_DECREF(key2);
5061 Py_DECREF(val2);
5062 goto error;
5063 }
5064 PyOS_snprintf(p, len, "%s=%s", k, v);
5065 envlist[envc++] = p;
5066 Py_DECREF(key2);
5067 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005068 }
5069 Py_DECREF(vals);
5070 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005071
Victor Stinner8c62be82010-05-06 00:08:46 +00005072 envlist[envc] = 0;
5073 *envc_ptr = envc;
5074 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005075
5076error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005077 Py_XDECREF(keys);
5078 Py_XDECREF(vals);
5079 while (--envc >= 0)
5080 PyMem_DEL(envlist[envc]);
5081 PyMem_DEL(envlist);
5082 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005083}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005084
Ross Lagerwall7807c352011-03-17 20:20:30 +02005085static char**
5086parse_arglist(PyObject* argv, Py_ssize_t *argc)
5087{
5088 int i;
5089 char **argvlist = PyMem_NEW(char *, *argc+1);
5090 if (argvlist == NULL) {
5091 PyErr_NoMemory();
5092 return NULL;
5093 }
5094 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005095 PyObject* item = PySequence_ITEM(argv, i);
5096 if (item == NULL)
5097 goto fail;
5098 if (!fsconvert_strdup(item, &argvlist[i])) {
5099 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005100 goto fail;
5101 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005102 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 }
5104 argvlist[*argc] = NULL;
5105 return argvlist;
5106fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005107 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 free_string_array(argvlist, *argc);
5109 return NULL;
5110}
5111#endif
5112
Larry Hastings2f936352014-08-05 14:04:04 +10005113
Ross Lagerwall7807c352011-03-17 20:20:30 +02005114#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005115/*[clinic input]
5116os.execv
5117
5118 path: FSConverter
5119 Path of executable file.
5120 argv: object
5121 Tuple or list of strings.
5122 /
5123
5124Execute an executable path with arguments, replacing current process.
5125[clinic start generated code]*/
5126
Larry Hastings2f936352014-08-05 14:04:04 +10005127static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005128os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5129/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005130{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005131 const char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005132 char **argvlist;
5133 Py_ssize_t argc;
5134
5135 /* execv has two arguments: (path, argv), where
5136 argv is a list or tuple of strings. */
5137
Larry Hastings2f936352014-08-05 14:04:04 +10005138 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005139 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5140 PyErr_SetString(PyExc_TypeError,
5141 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 return NULL;
5143 }
5144 argc = PySequence_Size(argv);
5145 if (argc < 1) {
5146 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005147 return NULL;
5148 }
5149
5150 argvlist = parse_arglist(argv, &argc);
5151 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005152 return NULL;
5153 }
5154
Larry Hastings2f936352014-08-05 14:04:04 +10005155 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005156
5157 /* If we get here it's definitely an error */
5158
5159 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005160 return posix_error();
5161}
5162
Larry Hastings2f936352014-08-05 14:04:04 +10005163
5164/*[clinic input]
5165os.execve
5166
5167 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5168 Path of executable file.
5169 argv: object
5170 Tuple or list of strings.
5171 env: object
5172 Dictionary of strings mapping to strings.
5173
5174Execute an executable path with arguments, replacing current process.
5175[clinic start generated code]*/
5176
Larry Hastings2f936352014-08-05 14:04:04 +10005177static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005178os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5179/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005180{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005181 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005182 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005183 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005184
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 /* execve has three arguments: (path, argv, env), where
5186 argv is a list or tuple of strings and env is a dictionary
5187 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005188
Ross Lagerwall7807c352011-03-17 20:20:30 +02005189 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005191 "execve: argv must be a tuple or list");
5192 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005194 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 if (!PyMapping_Check(env)) {
5196 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005197 "execve: environment must be a mapping object");
5198 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005199 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005200
Ross Lagerwall7807c352011-03-17 20:20:30 +02005201 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005203 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005204 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 envlist = parse_envlist(env, &envc);
5207 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005208 goto fail;
5209
Larry Hastings9cf065c2012-06-22 16:30:09 -07005210#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005211 if (path->fd > -1)
5212 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005213 else
5214#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005215 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005216
5217 /* If we get here it's definitely an error */
5218
Larry Hastings2f936352014-08-05 14:04:04 +10005219 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005220
5221 while (--envc >= 0)
5222 PyMem_DEL(envlist[envc]);
5223 PyMem_DEL(envlist);
5224 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005225 if (argvlist)
5226 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005227 return NULL;
5228}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005229#endif /* HAVE_EXECV */
5230
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005231
Guido van Rossuma1065681999-01-25 23:20:23 +00005232#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005233/*[clinic input]
5234os.spawnv
5235
5236 mode: int
5237 Mode of process creation.
5238 path: FSConverter
5239 Path of executable file.
5240 argv: object
5241 Tuple or list of strings.
5242 /
5243
5244Execute the program specified by path in a new process.
5245[clinic start generated code]*/
5246
Larry Hastings2f936352014-08-05 14:04:04 +10005247static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005248os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5249/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005250{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005251 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005253 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005254 Py_ssize_t argc;
5255 Py_intptr_t spawnval;
5256 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005257
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 /* spawnv has three arguments: (mode, path, argv), where
5259 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005260
Larry Hastings2f936352014-08-05 14:04:04 +10005261 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005262 if (PyList_Check(argv)) {
5263 argc = PyList_Size(argv);
5264 getitem = PyList_GetItem;
5265 }
5266 else if (PyTuple_Check(argv)) {
5267 argc = PyTuple_Size(argv);
5268 getitem = PyTuple_GetItem;
5269 }
5270 else {
5271 PyErr_SetString(PyExc_TypeError,
5272 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 return NULL;
5274 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 argvlist = PyMem_NEW(char *, argc+1);
5277 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 return PyErr_NoMemory();
5279 }
5280 for (i = 0; i < argc; i++) {
5281 if (!fsconvert_strdup((*getitem)(argv, i),
5282 &argvlist[i])) {
5283 free_string_array(argvlist, i);
5284 PyErr_SetString(
5285 PyExc_TypeError,
5286 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 return NULL;
5288 }
5289 }
5290 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 if (mode == _OLD_P_OVERLAY)
5293 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005294
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005296 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 if (spawnval == -1)
5302 return posix_error();
5303 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005304 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005305}
5306
5307
Larry Hastings2f936352014-08-05 14:04:04 +10005308/*[clinic input]
5309os.spawnve
5310
5311 mode: int
5312 Mode of process creation.
5313 path: FSConverter
5314 Path of executable file.
5315 argv: object
5316 Tuple or list of strings.
5317 env: object
5318 Dictionary of strings mapping to strings.
5319 /
5320
5321Execute the program specified by path in a new process.
5322[clinic start generated code]*/
5323
Larry Hastings2f936352014-08-05 14:04:04 +10005324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005325os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5326 PyObject *env)
5327/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005328{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005329 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005330 char **argvlist;
5331 char **envlist;
5332 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005333 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 Py_intptr_t spawnval;
5335 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5336 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005337
Victor Stinner8c62be82010-05-06 00:08:46 +00005338 /* spawnve has four arguments: (mode, path, argv, env), where
5339 argv is a list or tuple of strings and env is a dictionary
5340 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005341
Larry Hastings2f936352014-08-05 14:04:04 +10005342 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 if (PyList_Check(argv)) {
5344 argc = PyList_Size(argv);
5345 getitem = PyList_GetItem;
5346 }
5347 else if (PyTuple_Check(argv)) {
5348 argc = PyTuple_Size(argv);
5349 getitem = PyTuple_GetItem;
5350 }
5351 else {
5352 PyErr_SetString(PyExc_TypeError,
5353 "spawnve() arg 2 must be a tuple or list");
5354 goto fail_0;
5355 }
5356 if (!PyMapping_Check(env)) {
5357 PyErr_SetString(PyExc_TypeError,
5358 "spawnve() arg 3 must be a mapping object");
5359 goto fail_0;
5360 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005361
Victor Stinner8c62be82010-05-06 00:08:46 +00005362 argvlist = PyMem_NEW(char *, argc+1);
5363 if (argvlist == NULL) {
5364 PyErr_NoMemory();
5365 goto fail_0;
5366 }
5367 for (i = 0; i < argc; i++) {
5368 if (!fsconvert_strdup((*getitem)(argv, i),
5369 &argvlist[i]))
5370 {
5371 lastarg = i;
5372 goto fail_1;
5373 }
5374 }
5375 lastarg = argc;
5376 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005377
Victor Stinner8c62be82010-05-06 00:08:46 +00005378 envlist = parse_envlist(env, &envc);
5379 if (envlist == NULL)
5380 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005381
Victor Stinner8c62be82010-05-06 00:08:46 +00005382 if (mode == _OLD_P_OVERLAY)
5383 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005384
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005386 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005387 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005388
Victor Stinner8c62be82010-05-06 00:08:46 +00005389 if (spawnval == -1)
5390 (void) posix_error();
5391 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005392 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005393
Victor Stinner8c62be82010-05-06 00:08:46 +00005394 while (--envc >= 0)
5395 PyMem_DEL(envlist[envc]);
5396 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005397 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005398 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005399 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005400 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005401}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005402
Guido van Rossuma1065681999-01-25 23:20:23 +00005403#endif /* HAVE_SPAWNV */
5404
5405
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005406#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005407/*[clinic input]
5408os.fork1
5409
5410Fork a child process with a single multiplexed (i.e., not bound) thread.
5411
5412Return 0 to child process and PID of child to parent process.
5413[clinic start generated code]*/
5414
Larry Hastings2f936352014-08-05 14:04:04 +10005415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005416os_fork1_impl(PyObject *module)
5417/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005418{
Victor Stinner8c62be82010-05-06 00:08:46 +00005419 pid_t pid;
5420 int result = 0;
5421 _PyImport_AcquireLock();
5422 pid = fork1();
5423 if (pid == 0) {
5424 /* child: this clobbers and resets the import lock. */
5425 PyOS_AfterFork();
5426 } else {
5427 /* parent: release the import lock. */
5428 result = _PyImport_ReleaseLock();
5429 }
5430 if (pid == -1)
5431 return posix_error();
5432 if (result < 0) {
5433 /* Don't clobber the OSError if the fork failed. */
5434 PyErr_SetString(PyExc_RuntimeError,
5435 "not holding the import lock");
5436 return NULL;
5437 }
5438 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005439}
Larry Hastings2f936352014-08-05 14:04:04 +10005440#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005441
5442
Guido van Rossumad0ee831995-03-01 10:34:45 +00005443#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005444/*[clinic input]
5445os.fork
5446
5447Fork a child process.
5448
5449Return 0 to child process and PID of child to parent process.
5450[clinic start generated code]*/
5451
Larry Hastings2f936352014-08-05 14:04:04 +10005452static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005453os_fork_impl(PyObject *module)
5454/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005455{
Victor Stinner8c62be82010-05-06 00:08:46 +00005456 pid_t pid;
5457 int result = 0;
5458 _PyImport_AcquireLock();
5459 pid = fork();
5460 if (pid == 0) {
5461 /* child: this clobbers and resets the import lock. */
5462 PyOS_AfterFork();
5463 } else {
5464 /* parent: release the import lock. */
5465 result = _PyImport_ReleaseLock();
5466 }
5467 if (pid == -1)
5468 return posix_error();
5469 if (result < 0) {
5470 /* Don't clobber the OSError if the fork failed. */
5471 PyErr_SetString(PyExc_RuntimeError,
5472 "not holding the import lock");
5473 return NULL;
5474 }
5475 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005476}
Larry Hastings2f936352014-08-05 14:04:04 +10005477#endif /* HAVE_FORK */
5478
Guido van Rossum85e3b011991-06-03 12:42:10 +00005479
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005480#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005481#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005482/*[clinic input]
5483os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005484
Larry Hastings2f936352014-08-05 14:04:04 +10005485 policy: int
5486
5487Get the maximum scheduling priority for policy.
5488[clinic start generated code]*/
5489
Larry Hastings2f936352014-08-05 14:04:04 +10005490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005491os_sched_get_priority_max_impl(PyObject *module, int policy)
5492/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005493{
5494 int max;
5495
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 max = sched_get_priority_max(policy);
5497 if (max < 0)
5498 return posix_error();
5499 return PyLong_FromLong(max);
5500}
5501
Larry Hastings2f936352014-08-05 14:04:04 +10005502
5503/*[clinic input]
5504os.sched_get_priority_min
5505
5506 policy: int
5507
5508Get the minimum scheduling priority for policy.
5509[clinic start generated code]*/
5510
Larry Hastings2f936352014-08-05 14:04:04 +10005511static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005512os_sched_get_priority_min_impl(PyObject *module, int policy)
5513/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005514{
5515 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005516 if (min < 0)
5517 return posix_error();
5518 return PyLong_FromLong(min);
5519}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005520#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5521
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005522
Larry Hastings2f936352014-08-05 14:04:04 +10005523#ifdef HAVE_SCHED_SETSCHEDULER
5524/*[clinic input]
5525os.sched_getscheduler
5526 pid: pid_t
5527 /
5528
5529Get the scheduling policy for the process identifiedy by pid.
5530
5531Passing 0 for pid returns the scheduling policy for the calling process.
5532[clinic start generated code]*/
5533
Larry Hastings2f936352014-08-05 14:04:04 +10005534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005535os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5536/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005537{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005538 int policy;
5539
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005540 policy = sched_getscheduler(pid);
5541 if (policy < 0)
5542 return posix_error();
5543 return PyLong_FromLong(policy);
5544}
Larry Hastings2f936352014-08-05 14:04:04 +10005545#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005546
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005547
5548#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005549/*[clinic input]
5550class os.sched_param "PyObject *" "&SchedParamType"
5551
5552@classmethod
5553os.sched_param.__new__
5554
5555 sched_priority: object
5556 A scheduling parameter.
5557
5558Current has only one field: sched_priority");
5559[clinic start generated code]*/
5560
Larry Hastings2f936352014-08-05 14:04:04 +10005561static PyObject *
5562os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005563/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005564{
5565 PyObject *res;
5566
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005567 res = PyStructSequence_New(type);
5568 if (!res)
5569 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005570 Py_INCREF(sched_priority);
5571 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005572 return res;
5573}
5574
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005575
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005576PyDoc_VAR(os_sched_param__doc__);
5577
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005578static PyStructSequence_Field sched_param_fields[] = {
5579 {"sched_priority", "the scheduling priority"},
5580 {0}
5581};
5582
5583static PyStructSequence_Desc sched_param_desc = {
5584 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005585 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586 sched_param_fields,
5587 1
5588};
5589
5590static int
5591convert_sched_param(PyObject *param, struct sched_param *res)
5592{
5593 long priority;
5594
5595 if (Py_TYPE(param) != &SchedParamType) {
5596 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5597 return 0;
5598 }
5599 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5600 if (priority == -1 && PyErr_Occurred())
5601 return 0;
5602 if (priority > INT_MAX || priority < INT_MIN) {
5603 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5604 return 0;
5605 }
5606 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5607 return 1;
5608}
Larry Hastings2f936352014-08-05 14:04:04 +10005609#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005610
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005611
5612#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005613/*[clinic input]
5614os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005615
Larry Hastings2f936352014-08-05 14:04:04 +10005616 pid: pid_t
5617 policy: int
5618 param: sched_param
5619 /
5620
5621Set the scheduling policy for the process identified by pid.
5622
5623If pid is 0, the calling process is changed.
5624param is an instance of sched_param.
5625[clinic start generated code]*/
5626
Larry Hastings2f936352014-08-05 14:04:04 +10005627static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005628os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005629 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005630/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005631{
Jesus Cea9c822272011-09-10 01:40:52 +02005632 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005633 ** sched_setscheduler() returns 0 in Linux, but the previous
5634 ** scheduling policy under Solaris/Illumos, and others.
5635 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005636 */
Larry Hastings2f936352014-08-05 14:04:04 +10005637 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005638 return posix_error();
5639 Py_RETURN_NONE;
5640}
Larry Hastings2f936352014-08-05 14:04:04 +10005641#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005642
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005643
5644#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005645/*[clinic input]
5646os.sched_getparam
5647 pid: pid_t
5648 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005649
Larry Hastings2f936352014-08-05 14:04:04 +10005650Returns scheduling parameters for the process identified by pid.
5651
5652If pid is 0, returns parameters for the calling process.
5653Return value is an instance of sched_param.
5654[clinic start generated code]*/
5655
Larry Hastings2f936352014-08-05 14:04:04 +10005656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005657os_sched_getparam_impl(PyObject *module, pid_t pid)
5658/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005659{
5660 struct sched_param param;
5661 PyObject *result;
5662 PyObject *priority;
5663
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005664 if (sched_getparam(pid, &param))
5665 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005666 result = PyStructSequence_New(&SchedParamType);
5667 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005668 return NULL;
5669 priority = PyLong_FromLong(param.sched_priority);
5670 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005671 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005672 return NULL;
5673 }
Larry Hastings2f936352014-08-05 14:04:04 +10005674 PyStructSequence_SET_ITEM(result, 0, priority);
5675 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005676}
5677
Larry Hastings2f936352014-08-05 14:04:04 +10005678
5679/*[clinic input]
5680os.sched_setparam
5681 pid: pid_t
5682 param: sched_param
5683 /
5684
5685Set scheduling parameters for the process identified by pid.
5686
5687If pid is 0, sets parameters for the calling process.
5688param should be an instance of sched_param.
5689[clinic start generated code]*/
5690
Larry Hastings2f936352014-08-05 14:04:04 +10005691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005692os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005693 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005694/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005695{
5696 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005697 return posix_error();
5698 Py_RETURN_NONE;
5699}
Larry Hastings2f936352014-08-05 14:04:04 +10005700#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005701
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005702
5703#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005704/*[clinic input]
5705os.sched_rr_get_interval -> double
5706 pid: pid_t
5707 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005708
Larry Hastings2f936352014-08-05 14:04:04 +10005709Return the round-robin quantum for the process identified by pid, in seconds.
5710
5711Value returned is a float.
5712[clinic start generated code]*/
5713
Larry Hastings2f936352014-08-05 14:04:04 +10005714static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005715os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5716/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005717{
5718 struct timespec interval;
5719 if (sched_rr_get_interval(pid, &interval)) {
5720 posix_error();
5721 return -1.0;
5722 }
5723 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5724}
5725#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005726
Larry Hastings2f936352014-08-05 14:04:04 +10005727
5728/*[clinic input]
5729os.sched_yield
5730
5731Voluntarily relinquish the CPU.
5732[clinic start generated code]*/
5733
Larry Hastings2f936352014-08-05 14:04:04 +10005734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005735os_sched_yield_impl(PyObject *module)
5736/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005737{
5738 if (sched_yield())
5739 return posix_error();
5740 Py_RETURN_NONE;
5741}
5742
Benjamin Peterson2740af82011-08-02 17:41:34 -05005743#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005744/* The minimum number of CPUs allocated in a cpu_set_t */
5745static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005746
Larry Hastings2f936352014-08-05 14:04:04 +10005747/*[clinic input]
5748os.sched_setaffinity
5749 pid: pid_t
5750 mask : object
5751 /
5752
5753Set the CPU affinity of the process identified by pid to mask.
5754
5755mask should be an iterable of integers identifying CPUs.
5756[clinic start generated code]*/
5757
Larry Hastings2f936352014-08-05 14:04:04 +10005758static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005759os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5760/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005761{
Antoine Pitrou84869872012-08-04 16:16:35 +02005762 int ncpus;
5763 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005764 cpu_set_t *cpu_set = NULL;
5765 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005766
Larry Hastings2f936352014-08-05 14:04:04 +10005767 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005768 if (iterator == NULL)
5769 return NULL;
5770
5771 ncpus = NCPUS_START;
5772 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005773 cpu_set = CPU_ALLOC(ncpus);
5774 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005775 PyErr_NoMemory();
5776 goto error;
5777 }
Larry Hastings2f936352014-08-05 14:04:04 +10005778 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005779
5780 while ((item = PyIter_Next(iterator))) {
5781 long cpu;
5782 if (!PyLong_Check(item)) {
5783 PyErr_Format(PyExc_TypeError,
5784 "expected an iterator of ints, "
5785 "but iterator yielded %R",
5786 Py_TYPE(item));
5787 Py_DECREF(item);
5788 goto error;
5789 }
5790 cpu = PyLong_AsLong(item);
5791 Py_DECREF(item);
5792 if (cpu < 0) {
5793 if (!PyErr_Occurred())
5794 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5795 goto error;
5796 }
5797 if (cpu > INT_MAX - 1) {
5798 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5799 goto error;
5800 }
5801 if (cpu >= ncpus) {
5802 /* Grow CPU mask to fit the CPU number */
5803 int newncpus = ncpus;
5804 cpu_set_t *newmask;
5805 size_t newsetsize;
5806 while (newncpus <= cpu) {
5807 if (newncpus > INT_MAX / 2)
5808 newncpus = cpu + 1;
5809 else
5810 newncpus = newncpus * 2;
5811 }
5812 newmask = CPU_ALLOC(newncpus);
5813 if (newmask == NULL) {
5814 PyErr_NoMemory();
5815 goto error;
5816 }
5817 newsetsize = CPU_ALLOC_SIZE(newncpus);
5818 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005819 memcpy(newmask, cpu_set, setsize);
5820 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005821 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005822 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005823 ncpus = newncpus;
5824 }
Larry Hastings2f936352014-08-05 14:04:04 +10005825 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005826 }
5827 Py_CLEAR(iterator);
5828
Larry Hastings2f936352014-08-05 14:04:04 +10005829 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005830 posix_error();
5831 goto error;
5832 }
Larry Hastings2f936352014-08-05 14:04:04 +10005833 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005834 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005835
5836error:
Larry Hastings2f936352014-08-05 14:04:04 +10005837 if (cpu_set)
5838 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005839 Py_XDECREF(iterator);
5840 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005841}
5842
Larry Hastings2f936352014-08-05 14:04:04 +10005843
5844/*[clinic input]
5845os.sched_getaffinity
5846 pid: pid_t
5847 /
5848
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005849Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005850
5851The affinity is returned as a set of CPU identifiers.
5852[clinic start generated code]*/
5853
Larry Hastings2f936352014-08-05 14:04:04 +10005854static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005855os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005856/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005857{
Antoine Pitrou84869872012-08-04 16:16:35 +02005858 int cpu, ncpus, count;
5859 size_t setsize;
5860 cpu_set_t *mask = NULL;
5861 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005862
Antoine Pitrou84869872012-08-04 16:16:35 +02005863 ncpus = NCPUS_START;
5864 while (1) {
5865 setsize = CPU_ALLOC_SIZE(ncpus);
5866 mask = CPU_ALLOC(ncpus);
5867 if (mask == NULL)
5868 return PyErr_NoMemory();
5869 if (sched_getaffinity(pid, setsize, mask) == 0)
5870 break;
5871 CPU_FREE(mask);
5872 if (errno != EINVAL)
5873 return posix_error();
5874 if (ncpus > INT_MAX / 2) {
5875 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5876 "a large enough CPU set");
5877 return NULL;
5878 }
5879 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005880 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005881
5882 res = PySet_New(NULL);
5883 if (res == NULL)
5884 goto error;
5885 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5886 if (CPU_ISSET_S(cpu, setsize, mask)) {
5887 PyObject *cpu_num = PyLong_FromLong(cpu);
5888 --count;
5889 if (cpu_num == NULL)
5890 goto error;
5891 if (PySet_Add(res, cpu_num)) {
5892 Py_DECREF(cpu_num);
5893 goto error;
5894 }
5895 Py_DECREF(cpu_num);
5896 }
5897 }
5898 CPU_FREE(mask);
5899 return res;
5900
5901error:
5902 if (mask)
5903 CPU_FREE(mask);
5904 Py_XDECREF(res);
5905 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005906}
5907
Benjamin Peterson2740af82011-08-02 17:41:34 -05005908#endif /* HAVE_SCHED_SETAFFINITY */
5909
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005910#endif /* HAVE_SCHED_H */
5911
Larry Hastings2f936352014-08-05 14:04:04 +10005912
Neal Norwitzb59798b2003-03-21 01:43:31 +00005913/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005914/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5915#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005916#define DEV_PTY_FILE "/dev/ptc"
5917#define HAVE_DEV_PTMX
5918#else
5919#define DEV_PTY_FILE "/dev/ptmx"
5920#endif
5921
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005922#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005923#ifdef HAVE_PTY_H
5924#include <pty.h>
5925#else
5926#ifdef HAVE_LIBUTIL_H
5927#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005928#else
5929#ifdef HAVE_UTIL_H
5930#include <util.h>
5931#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005932#endif /* HAVE_LIBUTIL_H */
5933#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005934#ifdef HAVE_STROPTS_H
5935#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005936#endif
5937#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005938
Larry Hastings2f936352014-08-05 14:04:04 +10005939
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005940#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005941/*[clinic input]
5942os.openpty
5943
5944Open a pseudo-terminal.
5945
5946Return a tuple of (master_fd, slave_fd) containing open file descriptors
5947for both the master and slave ends.
5948[clinic start generated code]*/
5949
Larry Hastings2f936352014-08-05 14:04:04 +10005950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005951os_openpty_impl(PyObject *module)
5952/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005953{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005954 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005955#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005956 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005957#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005958#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005959 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005960#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005961 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005962#endif
5963#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005964
Thomas Wouters70c21a12000-07-14 14:28:33 +00005965#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005967 goto posix_error;
5968
5969 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5970 goto error;
5971 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5972 goto error;
5973
Neal Norwitzb59798b2003-03-21 01:43:31 +00005974#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5976 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005977 goto posix_error;
5978 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5979 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005980
Victor Stinnerdaf45552013-08-28 00:53:59 +02005981 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005983 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005985#else
Victor Stinner000de532013-11-25 23:19:58 +01005986 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005987 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005988 goto posix_error;
5989
Victor Stinner8c62be82010-05-06 00:08:46 +00005990 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005991
Victor Stinner8c62be82010-05-06 00:08:46 +00005992 /* change permission of slave */
5993 if (grantpt(master_fd) < 0) {
5994 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005995 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005997
Victor Stinner8c62be82010-05-06 00:08:46 +00005998 /* unlock slave */
5999 if (unlockpt(master_fd) < 0) {
6000 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006001 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00006002 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02006003
Victor Stinner8c62be82010-05-06 00:08:46 +00006004 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02006005
Victor Stinner8c62be82010-05-06 00:08:46 +00006006 slave_name = ptsname(master_fd); /* get name of slave */
6007 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02006008 goto posix_error;
6009
6010 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01006011 if (slave_fd == -1)
6012 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01006013
6014 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
6015 goto posix_error;
6016
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02006017#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00006018 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
6019 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00006020#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00006021 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00006022#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006023#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00006024#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00006025
Victor Stinner8c62be82010-05-06 00:08:46 +00006026 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00006027
Victor Stinnerdaf45552013-08-28 00:53:59 +02006028posix_error:
6029 posix_error();
6030error:
6031 if (master_fd != -1)
6032 close(master_fd);
6033 if (slave_fd != -1)
6034 close(slave_fd);
6035 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00006036}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00006037#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00006038
Larry Hastings2f936352014-08-05 14:04:04 +10006039
Fred Drake8cef4cf2000-06-28 16:40:38 +00006040#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10006041/*[clinic input]
6042os.forkpty
6043
6044Fork a new process with a new pseudo-terminal as controlling tty.
6045
6046Returns a tuple of (pid, master_fd).
6047Like fork(), return pid of 0 to the child process,
6048and pid of child to the parent process.
6049To both, return fd of newly opened pseudo-terminal.
6050[clinic start generated code]*/
6051
Larry Hastings2f936352014-08-05 14:04:04 +10006052static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006053os_forkpty_impl(PyObject *module)
6054/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006055{
Victor Stinner8c62be82010-05-06 00:08:46 +00006056 int master_fd = -1, result = 0;
6057 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006058
Victor Stinner8c62be82010-05-06 00:08:46 +00006059 _PyImport_AcquireLock();
6060 pid = forkpty(&master_fd, NULL, NULL, NULL);
6061 if (pid == 0) {
6062 /* child: this clobbers and resets the import lock. */
6063 PyOS_AfterFork();
6064 } else {
6065 /* parent: release the import lock. */
6066 result = _PyImport_ReleaseLock();
6067 }
6068 if (pid == -1)
6069 return posix_error();
6070 if (result < 0) {
6071 /* Don't clobber the OSError if the fork failed. */
6072 PyErr_SetString(PyExc_RuntimeError,
6073 "not holding the import lock");
6074 return NULL;
6075 }
6076 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006077}
Larry Hastings2f936352014-08-05 14:04:04 +10006078#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006079
Ross Lagerwall7807c352011-03-17 20:20:30 +02006080
Guido van Rossumad0ee831995-03-01 10:34:45 +00006081#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006082/*[clinic input]
6083os.getegid
6084
6085Return the current process's effective group id.
6086[clinic start generated code]*/
6087
Larry Hastings2f936352014-08-05 14:04:04 +10006088static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006089os_getegid_impl(PyObject *module)
6090/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006091{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006092 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006093}
Larry Hastings2f936352014-08-05 14:04:04 +10006094#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006095
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006096
Guido van Rossumad0ee831995-03-01 10:34:45 +00006097#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006098/*[clinic input]
6099os.geteuid
6100
6101Return the current process's effective user id.
6102[clinic start generated code]*/
6103
Larry Hastings2f936352014-08-05 14:04:04 +10006104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006105os_geteuid_impl(PyObject *module)
6106/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006107{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006108 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006109}
Larry Hastings2f936352014-08-05 14:04:04 +10006110#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006111
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006112
Guido van Rossumad0ee831995-03-01 10:34:45 +00006113#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006114/*[clinic input]
6115os.getgid
6116
6117Return the current process's group id.
6118[clinic start generated code]*/
6119
Larry Hastings2f936352014-08-05 14:04:04 +10006120static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006121os_getgid_impl(PyObject *module)
6122/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006123{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006124 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006125}
Larry Hastings2f936352014-08-05 14:04:04 +10006126#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006128
Larry Hastings2f936352014-08-05 14:04:04 +10006129/*[clinic input]
6130os.getpid
6131
6132Return the current process id.
6133[clinic start generated code]*/
6134
Larry Hastings2f936352014-08-05 14:04:04 +10006135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006136os_getpid_impl(PyObject *module)
6137/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006138{
Victor Stinner8c62be82010-05-06 00:08:46 +00006139 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006140}
6141
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006142#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006143
6144/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006145PyDoc_STRVAR(posix_getgrouplist__doc__,
6146"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6147Returns a list of groups to which a user belongs.\n\n\
6148 user: username to lookup\n\
6149 group: base group id of the user");
6150
6151static PyObject *
6152posix_getgrouplist(PyObject *self, PyObject *args)
6153{
6154#ifdef NGROUPS_MAX
6155#define MAX_GROUPS NGROUPS_MAX
6156#else
6157 /* defined to be 16 on Solaris7, so this should be a small number */
6158#define MAX_GROUPS 64
6159#endif
6160
6161 const char *user;
6162 int i, ngroups;
6163 PyObject *list;
6164#ifdef __APPLE__
6165 int *groups, basegid;
6166#else
6167 gid_t *groups, basegid;
6168#endif
6169 ngroups = MAX_GROUPS;
6170
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006171#ifdef __APPLE__
6172 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006173 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006174#else
6175 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6176 _Py_Gid_Converter, &basegid))
6177 return NULL;
6178#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006179
6180#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006181 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006182#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006183 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006184#endif
6185 if (groups == NULL)
6186 return PyErr_NoMemory();
6187
6188 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6189 PyMem_Del(groups);
6190 return posix_error();
6191 }
6192
6193 list = PyList_New(ngroups);
6194 if (list == NULL) {
6195 PyMem_Del(groups);
6196 return NULL;
6197 }
6198
6199 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006200#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006201 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006202#else
6203 PyObject *o = _PyLong_FromGid(groups[i]);
6204#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006205 if (o == NULL) {
6206 Py_DECREF(list);
6207 PyMem_Del(groups);
6208 return NULL;
6209 }
6210 PyList_SET_ITEM(list, i, o);
6211 }
6212
6213 PyMem_Del(groups);
6214
6215 return list;
6216}
Larry Hastings2f936352014-08-05 14:04:04 +10006217#endif /* HAVE_GETGROUPLIST */
6218
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006219
Fred Drakec9680921999-12-13 16:37:25 +00006220#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006221/*[clinic input]
6222os.getgroups
6223
6224Return list of supplemental group IDs for the process.
6225[clinic start generated code]*/
6226
Larry Hastings2f936352014-08-05 14:04:04 +10006227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006228os_getgroups_impl(PyObject *module)
6229/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006230{
6231 PyObject *result = NULL;
6232
Fred Drakec9680921999-12-13 16:37:25 +00006233#ifdef NGROUPS_MAX
6234#define MAX_GROUPS NGROUPS_MAX
6235#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006237#define MAX_GROUPS 64
6238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006240
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006241 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006242 * This is a helper variable to store the intermediate result when
6243 * that happens.
6244 *
6245 * To keep the code readable the OSX behaviour is unconditional,
6246 * according to the POSIX spec this should be safe on all unix-y
6247 * systems.
6248 */
6249 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006251
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006252#ifdef __APPLE__
6253 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6254 * there are more groups than can fit in grouplist. Therefore, on OS X
6255 * always first call getgroups with length 0 to get the actual number
6256 * of groups.
6257 */
6258 n = getgroups(0, NULL);
6259 if (n < 0) {
6260 return posix_error();
6261 } else if (n <= MAX_GROUPS) {
6262 /* groups will fit in existing array */
6263 alt_grouplist = grouplist;
6264 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006265 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006266 if (alt_grouplist == NULL) {
6267 errno = EINVAL;
6268 return posix_error();
6269 }
6270 }
6271
6272 n = getgroups(n, alt_grouplist);
6273 if (n == -1) {
6274 if (alt_grouplist != grouplist) {
6275 PyMem_Free(alt_grouplist);
6276 }
6277 return posix_error();
6278 }
6279#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006281 if (n < 0) {
6282 if (errno == EINVAL) {
6283 n = getgroups(0, NULL);
6284 if (n == -1) {
6285 return posix_error();
6286 }
6287 if (n == 0) {
6288 /* Avoid malloc(0) */
6289 alt_grouplist = grouplist;
6290 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006291 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006292 if (alt_grouplist == NULL) {
6293 errno = EINVAL;
6294 return posix_error();
6295 }
6296 n = getgroups(n, alt_grouplist);
6297 if (n == -1) {
6298 PyMem_Free(alt_grouplist);
6299 return posix_error();
6300 }
6301 }
6302 } else {
6303 return posix_error();
6304 }
6305 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006306#endif
6307
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006308 result = PyList_New(n);
6309 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006310 int i;
6311 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006312 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006313 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006314 Py_DECREF(result);
6315 result = NULL;
6316 break;
Fred Drakec9680921999-12-13 16:37:25 +00006317 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006319 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006320 }
6321
6322 if (alt_grouplist != grouplist) {
6323 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006325
Fred Drakec9680921999-12-13 16:37:25 +00006326 return result;
6327}
Larry Hastings2f936352014-08-05 14:04:04 +10006328#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006329
Antoine Pitroub7572f02009-12-02 20:46:48 +00006330#ifdef HAVE_INITGROUPS
6331PyDoc_STRVAR(posix_initgroups__doc__,
6332"initgroups(username, gid) -> None\n\n\
6333Call the system initgroups() to initialize the group access list with all of\n\
6334the groups of which the specified username is a member, plus the specified\n\
6335group id.");
6336
Larry Hastings2f936352014-08-05 14:04:04 +10006337/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006338static PyObject *
6339posix_initgroups(PyObject *self, PyObject *args)
6340{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006341 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006342 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006343 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006344#ifdef __APPLE__
6345 int gid;
6346#else
6347 gid_t gid;
6348#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006349
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006350#ifdef __APPLE__
6351 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6352 PyUnicode_FSConverter, &oname,
6353 &gid))
6354#else
6355 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6356 PyUnicode_FSConverter, &oname,
6357 _Py_Gid_Converter, &gid))
6358#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006360 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006361
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006362 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006363 Py_DECREF(oname);
6364 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006366
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 Py_INCREF(Py_None);
6368 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006369}
Larry Hastings2f936352014-08-05 14:04:04 +10006370#endif /* HAVE_INITGROUPS */
6371
Antoine Pitroub7572f02009-12-02 20:46:48 +00006372
Martin v. Löwis606edc12002-06-13 21:09:11 +00006373#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006374/*[clinic input]
6375os.getpgid
6376
6377 pid: pid_t
6378
6379Call the system call getpgid(), and return the result.
6380[clinic start generated code]*/
6381
Larry Hastings2f936352014-08-05 14:04:04 +10006382static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006383os_getpgid_impl(PyObject *module, pid_t pid)
6384/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006385{
6386 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006387 if (pgid < 0)
6388 return posix_error();
6389 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006390}
6391#endif /* HAVE_GETPGID */
6392
6393
Guido van Rossumb6775db1994-08-01 11:34:53 +00006394#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006395/*[clinic input]
6396os.getpgrp
6397
6398Return the current process group id.
6399[clinic start generated code]*/
6400
Larry Hastings2f936352014-08-05 14:04:04 +10006401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006402os_getpgrp_impl(PyObject *module)
6403/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006404{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006405#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006406 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006407#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006409#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006410}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006411#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006412
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006413
Guido van Rossumb6775db1994-08-01 11:34:53 +00006414#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006415/*[clinic input]
6416os.setpgrp
6417
6418Make the current process the leader of its process group.
6419[clinic start generated code]*/
6420
Larry Hastings2f936352014-08-05 14:04:04 +10006421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006422os_setpgrp_impl(PyObject *module)
6423/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006424{
Guido van Rossum64933891994-10-20 21:56:42 +00006425#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006427#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006429#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 return posix_error();
6431 Py_INCREF(Py_None);
6432 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006433}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006434#endif /* HAVE_SETPGRP */
6435
Guido van Rossumad0ee831995-03-01 10:34:45 +00006436#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006437
6438#ifdef MS_WINDOWS
6439#include <tlhelp32.h>
6440
6441static PyObject*
6442win32_getppid()
6443{
6444 HANDLE snapshot;
6445 pid_t mypid;
6446 PyObject* result = NULL;
6447 BOOL have_record;
6448 PROCESSENTRY32 pe;
6449
6450 mypid = getpid(); /* This function never fails */
6451
6452 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6453 if (snapshot == INVALID_HANDLE_VALUE)
6454 return PyErr_SetFromWindowsErr(GetLastError());
6455
6456 pe.dwSize = sizeof(pe);
6457 have_record = Process32First(snapshot, &pe);
6458 while (have_record) {
6459 if (mypid == (pid_t)pe.th32ProcessID) {
6460 /* We could cache the ulong value in a static variable. */
6461 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6462 break;
6463 }
6464
6465 have_record = Process32Next(snapshot, &pe);
6466 }
6467
6468 /* If our loop exits and our pid was not found (result will be NULL)
6469 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6470 * error anyway, so let's raise it. */
6471 if (!result)
6472 result = PyErr_SetFromWindowsErr(GetLastError());
6473
6474 CloseHandle(snapshot);
6475
6476 return result;
6477}
6478#endif /*MS_WINDOWS*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480
6481/*[clinic input]
6482os.getppid
6483
6484Return the parent's process id.
6485
6486If the parent process has already exited, Windows machines will still
6487return its id; others systems will return the id of the 'init' process (1).
6488[clinic start generated code]*/
6489
Larry Hastings2f936352014-08-05 14:04:04 +10006490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006491os_getppid_impl(PyObject *module)
6492/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006493{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006494#ifdef MS_WINDOWS
6495 return win32_getppid();
6496#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006497 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006498#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006499}
6500#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006501
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006502
Fred Drake12c6e2d1999-12-14 21:25:03 +00006503#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006504/*[clinic input]
6505os.getlogin
6506
6507Return the actual login name.
6508[clinic start generated code]*/
6509
Larry Hastings2f936352014-08-05 14:04:04 +10006510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006511os_getlogin_impl(PyObject *module)
6512/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006513{
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006515#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006516 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006517 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006518
6519 if (GetUserNameW(user_name, &num_chars)) {
6520 /* num_chars is the number of unicode chars plus null terminator */
6521 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006522 }
6523 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006524 result = PyErr_SetFromWindowsErr(GetLastError());
6525#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 char *name;
6527 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006528
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 errno = 0;
6530 name = getlogin();
6531 if (name == NULL) {
6532 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006533 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006534 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006535 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 }
6537 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006538 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006540#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006541 return result;
6542}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006543#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006544
Larry Hastings2f936352014-08-05 14:04:04 +10006545
Guido van Rossumad0ee831995-03-01 10:34:45 +00006546#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006547/*[clinic input]
6548os.getuid
6549
6550Return the current process's user id.
6551[clinic start generated code]*/
6552
Larry Hastings2f936352014-08-05 14:04:04 +10006553static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006554os_getuid_impl(PyObject *module)
6555/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006556{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006557 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006558}
Larry Hastings2f936352014-08-05 14:04:04 +10006559#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006560
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006561
Brian Curtineb24d742010-04-12 17:16:38 +00006562#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006563#define HAVE_KILL
6564#endif /* MS_WINDOWS */
6565
6566#ifdef HAVE_KILL
6567/*[clinic input]
6568os.kill
6569
6570 pid: pid_t
6571 signal: Py_ssize_t
6572 /
6573
6574Kill a process with a signal.
6575[clinic start generated code]*/
6576
Larry Hastings2f936352014-08-05 14:04:04 +10006577static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006578os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6579/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006580#ifndef MS_WINDOWS
6581{
6582 if (kill(pid, (int)signal) == -1)
6583 return posix_error();
6584 Py_RETURN_NONE;
6585}
6586#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006587{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006588 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006589 DWORD sig = (DWORD)signal;
6590 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006591 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006592
Victor Stinner8c62be82010-05-06 00:08:46 +00006593 /* Console processes which share a common console can be sent CTRL+C or
6594 CTRL+BREAK events, provided they handle said events. */
6595 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006596 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 err = GetLastError();
6598 PyErr_SetFromWindowsErr(err);
6599 }
6600 else
6601 Py_RETURN_NONE;
6602 }
Brian Curtineb24d742010-04-12 17:16:38 +00006603
Victor Stinner8c62be82010-05-06 00:08:46 +00006604 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6605 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006606 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 if (handle == NULL) {
6608 err = GetLastError();
6609 return PyErr_SetFromWindowsErr(err);
6610 }
Brian Curtineb24d742010-04-12 17:16:38 +00006611
Victor Stinner8c62be82010-05-06 00:08:46 +00006612 if (TerminateProcess(handle, sig) == 0) {
6613 err = GetLastError();
6614 result = PyErr_SetFromWindowsErr(err);
6615 } else {
6616 Py_INCREF(Py_None);
6617 result = Py_None;
6618 }
Brian Curtineb24d742010-04-12 17:16:38 +00006619
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 CloseHandle(handle);
6621 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006622}
Larry Hastings2f936352014-08-05 14:04:04 +10006623#endif /* !MS_WINDOWS */
6624#endif /* HAVE_KILL */
6625
6626
6627#ifdef HAVE_KILLPG
6628/*[clinic input]
6629os.killpg
6630
6631 pgid: pid_t
6632 signal: int
6633 /
6634
6635Kill a process group with a signal.
6636[clinic start generated code]*/
6637
Larry Hastings2f936352014-08-05 14:04:04 +10006638static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006639os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6640/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006641{
6642 /* XXX some man pages make the `pgid` parameter an int, others
6643 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6644 take the same type. Moreover, pid_t is always at least as wide as
6645 int (else compilation of this module fails), which is safe. */
6646 if (killpg(pgid, signal) == -1)
6647 return posix_error();
6648 Py_RETURN_NONE;
6649}
6650#endif /* HAVE_KILLPG */
6651
Brian Curtineb24d742010-04-12 17:16:38 +00006652
Guido van Rossumc0125471996-06-28 18:55:32 +00006653#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006654#ifdef HAVE_SYS_LOCK_H
6655#include <sys/lock.h>
6656#endif
6657
Larry Hastings2f936352014-08-05 14:04:04 +10006658/*[clinic input]
6659os.plock
6660 op: int
6661 /
6662
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006663Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006664[clinic start generated code]*/
6665
Larry Hastings2f936352014-08-05 14:04:04 +10006666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006667os_plock_impl(PyObject *module, int op)
6668/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006669{
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 if (plock(op) == -1)
6671 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006672 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006673}
Larry Hastings2f936352014-08-05 14:04:04 +10006674#endif /* HAVE_PLOCK */
6675
Guido van Rossumc0125471996-06-28 18:55:32 +00006676
Guido van Rossumb6775db1994-08-01 11:34:53 +00006677#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006678/*[clinic input]
6679os.setuid
6680
6681 uid: uid_t
6682 /
6683
6684Set the current process's user id.
6685[clinic start generated code]*/
6686
Larry Hastings2f936352014-08-05 14:04:04 +10006687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006688os_setuid_impl(PyObject *module, uid_t uid)
6689/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006690{
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 if (setuid(uid) < 0)
6692 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006693 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006694}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006695#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006696
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006697
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006698#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006699/*[clinic input]
6700os.seteuid
6701
6702 euid: uid_t
6703 /
6704
6705Set the current process's effective user id.
6706[clinic start generated code]*/
6707
Larry Hastings2f936352014-08-05 14:04:04 +10006708static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006709os_seteuid_impl(PyObject *module, uid_t euid)
6710/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006711{
6712 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006713 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006714 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006715}
6716#endif /* HAVE_SETEUID */
6717
Larry Hastings2f936352014-08-05 14:04:04 +10006718
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006719#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006720/*[clinic input]
6721os.setegid
6722
6723 egid: gid_t
6724 /
6725
6726Set the current process's effective group id.
6727[clinic start generated code]*/
6728
Larry Hastings2f936352014-08-05 14:04:04 +10006729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006730os_setegid_impl(PyObject *module, gid_t egid)
6731/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006732{
6733 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006735 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006736}
6737#endif /* HAVE_SETEGID */
6738
Larry Hastings2f936352014-08-05 14:04:04 +10006739
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006740#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006741/*[clinic input]
6742os.setreuid
6743
6744 ruid: uid_t
6745 euid: uid_t
6746 /
6747
6748Set the current process's real and effective user ids.
6749[clinic start generated code]*/
6750
Larry Hastings2f936352014-08-05 14:04:04 +10006751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006752os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6753/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006754{
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 if (setreuid(ruid, euid) < 0) {
6756 return posix_error();
6757 } else {
6758 Py_INCREF(Py_None);
6759 return Py_None;
6760 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006761}
6762#endif /* HAVE_SETREUID */
6763
Larry Hastings2f936352014-08-05 14:04:04 +10006764
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006765#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006766/*[clinic input]
6767os.setregid
6768
6769 rgid: gid_t
6770 egid: gid_t
6771 /
6772
6773Set the current process's real and effective group ids.
6774[clinic start generated code]*/
6775
Larry Hastings2f936352014-08-05 14:04:04 +10006776static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006777os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6778/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006779{
6780 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006782 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006783}
6784#endif /* HAVE_SETREGID */
6785
Larry Hastings2f936352014-08-05 14:04:04 +10006786
Guido van Rossumb6775db1994-08-01 11:34:53 +00006787#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006788/*[clinic input]
6789os.setgid
6790 gid: gid_t
6791 /
6792
6793Set the current process's group id.
6794[clinic start generated code]*/
6795
Larry Hastings2f936352014-08-05 14:04:04 +10006796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006797os_setgid_impl(PyObject *module, gid_t gid)
6798/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006799{
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 if (setgid(gid) < 0)
6801 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006802 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006803}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006804#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006805
Larry Hastings2f936352014-08-05 14:04:04 +10006806
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006807#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006808/*[clinic input]
6809os.setgroups
6810
6811 groups: object
6812 /
6813
6814Set the groups of the current process to list.
6815[clinic start generated code]*/
6816
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006817static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006818os_setgroups(PyObject *module, PyObject *groups)
6819/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006820{
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 int i, len;
6822 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006823
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 if (!PySequence_Check(groups)) {
6825 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6826 return NULL;
6827 }
6828 len = PySequence_Size(groups);
6829 if (len > MAX_GROUPS) {
6830 PyErr_SetString(PyExc_ValueError, "too many groups");
6831 return NULL;
6832 }
6833 for(i = 0; i < len; i++) {
6834 PyObject *elem;
6835 elem = PySequence_GetItem(groups, i);
6836 if (!elem)
6837 return NULL;
6838 if (!PyLong_Check(elem)) {
6839 PyErr_SetString(PyExc_TypeError,
6840 "groups must be integers");
6841 Py_DECREF(elem);
6842 return NULL;
6843 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006844 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 Py_DECREF(elem);
6846 return NULL;
6847 }
6848 }
6849 Py_DECREF(elem);
6850 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006851
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 if (setgroups(len, grouplist) < 0)
6853 return posix_error();
6854 Py_INCREF(Py_None);
6855 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006856}
6857#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006858
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006859#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6860static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006861wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006862{
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 PyObject *result;
6864 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006865 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 if (pid == -1)
6868 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 if (struct_rusage == NULL) {
6871 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6872 if (m == NULL)
6873 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006874 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006875 Py_DECREF(m);
6876 if (struct_rusage == NULL)
6877 return NULL;
6878 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006879
Victor Stinner8c62be82010-05-06 00:08:46 +00006880 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6881 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6882 if (!result)
6883 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006884
6885#ifndef doubletime
6886#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6887#endif
6888
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006890 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006892 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006894 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6895 SET_INT(result, 2, ru->ru_maxrss);
6896 SET_INT(result, 3, ru->ru_ixrss);
6897 SET_INT(result, 4, ru->ru_idrss);
6898 SET_INT(result, 5, ru->ru_isrss);
6899 SET_INT(result, 6, ru->ru_minflt);
6900 SET_INT(result, 7, ru->ru_majflt);
6901 SET_INT(result, 8, ru->ru_nswap);
6902 SET_INT(result, 9, ru->ru_inblock);
6903 SET_INT(result, 10, ru->ru_oublock);
6904 SET_INT(result, 11, ru->ru_msgsnd);
6905 SET_INT(result, 12, ru->ru_msgrcv);
6906 SET_INT(result, 13, ru->ru_nsignals);
6907 SET_INT(result, 14, ru->ru_nvcsw);
6908 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006909#undef SET_INT
6910
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 if (PyErr_Occurred()) {
6912 Py_DECREF(result);
6913 return NULL;
6914 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915
Victor Stinner8c62be82010-05-06 00:08:46 +00006916 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917}
6918#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6919
Larry Hastings2f936352014-08-05 14:04:04 +10006920
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006921#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006922/*[clinic input]
6923os.wait3
6924
6925 options: int
6926Wait for completion of a child process.
6927
6928Returns a tuple of information about the child process:
6929 (pid, status, rusage)
6930[clinic start generated code]*/
6931
Larry Hastings2f936352014-08-05 14:04:04 +10006932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006933os_wait3_impl(PyObject *module, int options)
6934/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006935{
Victor Stinner8c62be82010-05-06 00:08:46 +00006936 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006937 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006938 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006939 WAIT_TYPE status;
6940 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006941
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006942 do {
6943 Py_BEGIN_ALLOW_THREADS
6944 pid = wait3(&status, options, &ru);
6945 Py_END_ALLOW_THREADS
6946 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6947 if (pid < 0)
6948 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006949
Victor Stinner4195b5c2012-02-08 23:03:19 +01006950 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006951}
6952#endif /* HAVE_WAIT3 */
6953
Larry Hastings2f936352014-08-05 14:04:04 +10006954
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006955#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006956/*[clinic input]
6957
6958os.wait4
6959
6960 pid: pid_t
6961 options: int
6962
6963Wait for completion of a specific child process.
6964
6965Returns a tuple of information about the child process:
6966 (pid, status, rusage)
6967[clinic start generated code]*/
6968
Larry Hastings2f936352014-08-05 14:04:04 +10006969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006970os_wait4_impl(PyObject *module, pid_t pid, int options)
6971/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006972{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006973 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006974 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006975 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006976 WAIT_TYPE status;
6977 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006978
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006979 do {
6980 Py_BEGIN_ALLOW_THREADS
6981 res = wait4(pid, &status, options, &ru);
6982 Py_END_ALLOW_THREADS
6983 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6984 if (res < 0)
6985 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006986
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006987 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006988}
6989#endif /* HAVE_WAIT4 */
6990
Larry Hastings2f936352014-08-05 14:04:04 +10006991
Ross Lagerwall7807c352011-03-17 20:20:30 +02006992#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006993/*[clinic input]
6994os.waitid
6995
6996 idtype: idtype_t
6997 Must be one of be P_PID, P_PGID or P_ALL.
6998 id: id_t
6999 The id to wait on.
7000 options: int
7001 Constructed from the ORing of one or more of WEXITED, WSTOPPED
7002 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
7003 /
7004
7005Returns the result of waiting for a process or processes.
7006
7007Returns either waitid_result or None if WNOHANG is specified and there are
7008no children in a waitable state.
7009[clinic start generated code]*/
7010
Larry Hastings2f936352014-08-05 14:04:04 +10007011static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007012os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
7013/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007014{
7015 PyObject *result;
7016 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007017 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007018 siginfo_t si;
7019 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007020
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007021 do {
7022 Py_BEGIN_ALLOW_THREADS
7023 res = waitid(idtype, id, &si, options);
7024 Py_END_ALLOW_THREADS
7025 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7026 if (res < 0)
7027 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007028
7029 if (si.si_pid == 0)
7030 Py_RETURN_NONE;
7031
7032 result = PyStructSequence_New(&WaitidResultType);
7033 if (!result)
7034 return NULL;
7035
7036 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02007037 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02007038 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
7039 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
7040 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
7041 if (PyErr_Occurred()) {
7042 Py_DECREF(result);
7043 return NULL;
7044 }
7045
7046 return result;
7047}
Larry Hastings2f936352014-08-05 14:04:04 +10007048#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007049
Larry Hastings2f936352014-08-05 14:04:04 +10007050
7051#if defined(HAVE_WAITPID)
7052/*[clinic input]
7053os.waitpid
7054 pid: pid_t
7055 options: int
7056 /
7057
7058Wait for completion of a given child process.
7059
7060Returns a tuple of information regarding the child process:
7061 (pid, status)
7062
7063The options argument is ignored on Windows.
7064[clinic start generated code]*/
7065
Larry Hastings2f936352014-08-05 14:04:04 +10007066static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007067os_waitpid_impl(PyObject *module, pid_t pid, int options)
7068/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007069{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007070 pid_t res;
7071 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007072 WAIT_TYPE status;
7073 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007074
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007075 do {
7076 Py_BEGIN_ALLOW_THREADS
7077 res = waitpid(pid, &status, options);
7078 Py_END_ALLOW_THREADS
7079 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7080 if (res < 0)
7081 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007082
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007083 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007084}
Tim Petersab034fa2002-02-01 11:27:43 +00007085#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007086/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007087/*[clinic input]
7088os.waitpid
7089 pid: Py_intptr_t
7090 options: int
7091 /
7092
7093Wait for completion of a given process.
7094
7095Returns a tuple of information regarding the process:
7096 (pid, status << 8)
7097
7098The options argument is ignored on Windows.
7099[clinic start generated code]*/
7100
Larry Hastings2f936352014-08-05 14:04:04 +10007101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007102os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7103/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007104{
7105 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007106 Py_intptr_t res;
7107 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007108
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007109 do {
7110 Py_BEGIN_ALLOW_THREADS
7111 res = _cwait(&status, pid, options);
7112 Py_END_ALLOW_THREADS
7113 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007114 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007115 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007116
Victor Stinner8c62be82010-05-06 00:08:46 +00007117 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007118 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007119}
Larry Hastings2f936352014-08-05 14:04:04 +10007120#endif
7121
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007122
Guido van Rossumad0ee831995-03-01 10:34:45 +00007123#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007124/*[clinic input]
7125os.wait
7126
7127Wait for completion of a child process.
7128
7129Returns a tuple of information about the child process:
7130 (pid, status)
7131[clinic start generated code]*/
7132
Larry Hastings2f936352014-08-05 14:04:04 +10007133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007134os_wait_impl(PyObject *module)
7135/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007136{
Victor Stinner8c62be82010-05-06 00:08:46 +00007137 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007138 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007139 WAIT_TYPE status;
7140 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007141
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007142 do {
7143 Py_BEGIN_ALLOW_THREADS
7144 pid = wait(&status);
7145 Py_END_ALLOW_THREADS
7146 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7147 if (pid < 0)
7148 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007149
Victor Stinner8c62be82010-05-06 00:08:46 +00007150 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007151}
Larry Hastings2f936352014-08-05 14:04:04 +10007152#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007153
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007154
Larry Hastings9cf065c2012-06-22 16:30:09 -07007155#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7156PyDoc_STRVAR(readlink__doc__,
7157"readlink(path, *, dir_fd=None) -> path\n\n\
7158Return a string representing the path to which the symbolic link points.\n\
7159\n\
7160If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7161 and path should be relative; path will then be relative to that directory.\n\
7162dir_fd may not be implemented on your platform.\n\
7163 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007164#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007165
Guido van Rossumb6775db1994-08-01 11:34:53 +00007166#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007167
Larry Hastings2f936352014-08-05 14:04:04 +10007168/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007169static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007170posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007171{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007172 path_t path;
7173 int dir_fd = DEFAULT_DIR_FD;
7174 char buffer[MAXPATHLEN];
7175 ssize_t length;
7176 PyObject *return_value = NULL;
7177 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007178
Larry Hastings9cf065c2012-06-22 16:30:09 -07007179 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007180 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007181 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7182 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007183 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007184 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007185
Victor Stinner8c62be82010-05-06 00:08:46 +00007186 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007187#ifdef HAVE_READLINKAT
7188 if (dir_fd != DEFAULT_DIR_FD)
7189 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007190 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007191#endif
7192 length = readlink(path.narrow, buffer, sizeof(buffer));
7193 Py_END_ALLOW_THREADS
7194
7195 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007196 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197 goto exit;
7198 }
7199
7200 if (PyUnicode_Check(path.object))
7201 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7202 else
7203 return_value = PyBytes_FromStringAndSize(buffer, length);
7204exit:
7205 path_cleanup(&path);
7206 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007207}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007208
Guido van Rossumb6775db1994-08-01 11:34:53 +00007209#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007210
Larry Hastings2f936352014-08-05 14:04:04 +10007211#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7212
7213static PyObject *
7214win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7215{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007216 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007217 DWORD n_bytes_returned;
7218 DWORD io_result;
7219 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007220 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007221 HANDLE reparse_point_handle;
7222
Martin Panter70214ad2016-08-04 02:38:59 +00007223 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7224 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007225 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007226
7227 static char *keywords[] = {"path", "dir_fd", NULL};
7228
7229 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7230 &po,
7231 dir_fd_unavailable, &dir_fd
7232 ))
7233 return NULL;
7234
7235 path = PyUnicode_AsUnicode(po);
7236 if (path == NULL)
7237 return NULL;
7238
7239 /* First get a handle to the reparse point */
7240 Py_BEGIN_ALLOW_THREADS
7241 reparse_point_handle = CreateFileW(
7242 path,
7243 0,
7244 0,
7245 0,
7246 OPEN_EXISTING,
7247 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7248 0);
7249 Py_END_ALLOW_THREADS
7250
7251 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7252 return win32_error_object("readlink", po);
7253
7254 Py_BEGIN_ALLOW_THREADS
7255 /* New call DeviceIoControl to read the reparse point */
7256 io_result = DeviceIoControl(
7257 reparse_point_handle,
7258 FSCTL_GET_REPARSE_POINT,
7259 0, 0, /* in buffer */
7260 target_buffer, sizeof(target_buffer),
7261 &n_bytes_returned,
7262 0 /* we're not using OVERLAPPED_IO */
7263 );
7264 CloseHandle(reparse_point_handle);
7265 Py_END_ALLOW_THREADS
7266
7267 if (io_result==0)
7268 return win32_error_object("readlink", po);
7269
7270 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7271 {
7272 PyErr_SetString(PyExc_ValueError,
7273 "not a symbolic link");
7274 return NULL;
7275 }
7276 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7277 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7278
7279 result = PyUnicode_FromWideChar(print_name,
7280 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7281 return result;
7282}
7283
7284#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7285
7286
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007287
Larry Hastings9cf065c2012-06-22 16:30:09 -07007288#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007289
7290#if defined(MS_WINDOWS)
7291
7292/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007293static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
7294static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPCSTR, LPCSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007295
Larry Hastings9cf065c2012-06-22 16:30:09 -07007296static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007297check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007298{
7299 HINSTANCE hKernel32;
7300 /* only recheck */
7301 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7302 return 1;
7303 hKernel32 = GetModuleHandleW(L"KERNEL32");
7304 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7305 "CreateSymbolicLinkW");
7306 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7307 "CreateSymbolicLinkA");
7308 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7309}
7310
Victor Stinner31b3b922013-06-05 01:49:17 +02007311/* Remove the last portion of the path */
7312static void
7313_dirnameW(WCHAR *path)
7314{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315 WCHAR *ptr;
7316
7317 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007318 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007319 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007321 }
7322 *ptr = 0;
7323}
7324
Victor Stinner31b3b922013-06-05 01:49:17 +02007325/* Remove the last portion of the path */
7326static void
7327_dirnameA(char *path)
7328{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007329 char *ptr;
7330
7331 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007332 for(ptr = path + strlen(path); ptr != path; ptr--) {
7333 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007334 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007335 }
7336 *ptr = 0;
7337}
7338
Victor Stinner31b3b922013-06-05 01:49:17 +02007339/* Is this path absolute? */
7340static int
7341_is_absW(const WCHAR *path)
7342{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007343 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7344
7345}
7346
Victor Stinner31b3b922013-06-05 01:49:17 +02007347/* Is this path absolute? */
7348static int
7349_is_absA(const char *path)
7350{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007351 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7352
7353}
7354
Victor Stinner31b3b922013-06-05 01:49:17 +02007355/* join root and rest with a backslash */
7356static void
7357_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7358{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007359 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007360
Victor Stinner31b3b922013-06-05 01:49:17 +02007361 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007362 wcscpy(dest_path, rest);
7363 return;
7364 }
7365
7366 root_len = wcslen(root);
7367
7368 wcscpy(dest_path, root);
7369 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007370 dest_path[root_len] = L'\\';
7371 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007372 }
7373 wcscpy(dest_path+root_len, rest);
7374}
7375
Victor Stinner31b3b922013-06-05 01:49:17 +02007376/* join root and rest with a backslash */
7377static void
7378_joinA(char *dest_path, const char *root, const char *rest)
7379{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007380 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007381
Victor Stinner31b3b922013-06-05 01:49:17 +02007382 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007383 strcpy(dest_path, rest);
7384 return;
7385 }
7386
7387 root_len = strlen(root);
7388
7389 strcpy(dest_path, root);
7390 if(root_len) {
7391 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007392 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007393 }
7394 strcpy(dest_path+root_len, rest);
7395}
7396
Victor Stinner31b3b922013-06-05 01:49:17 +02007397/* Return True if the path at src relative to dest is a directory */
7398static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007399_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007400{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007401 WIN32_FILE_ATTRIBUTE_DATA src_info;
7402 WCHAR dest_parent[MAX_PATH];
7403 WCHAR src_resolved[MAX_PATH] = L"";
7404
7405 /* dest_parent = os.path.dirname(dest) */
7406 wcscpy(dest_parent, dest);
7407 _dirnameW(dest_parent);
7408 /* src_resolved = os.path.join(dest_parent, src) */
7409 _joinW(src_resolved, dest_parent, src);
7410 return (
7411 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7412 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7413 );
7414}
7415
Victor Stinner31b3b922013-06-05 01:49:17 +02007416/* Return True if the path at src relative to dest is a directory */
7417static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007418_check_dirA(LPCSTR src, LPCSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007419{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007420 WIN32_FILE_ATTRIBUTE_DATA src_info;
7421 char dest_parent[MAX_PATH];
7422 char src_resolved[MAX_PATH] = "";
7423
7424 /* dest_parent = os.path.dirname(dest) */
7425 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007426 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007427 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007428 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007429 return (
7430 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7431 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7432 );
7433}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007435
Larry Hastings2f936352014-08-05 14:04:04 +10007436
7437/*[clinic input]
7438os.symlink
7439 src: path_t
7440 dst: path_t
7441 target_is_directory: bool = False
7442 *
7443 dir_fd: dir_fd(requires='symlinkat')=None
7444
7445# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7446
7447Create a symbolic link pointing to src named dst.
7448
7449target_is_directory is required on Windows if the target is to be
7450 interpreted as a directory. (On Windows, symlink requires
7451 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7452 target_is_directory is ignored on non-Windows platforms.
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
7459[clinic start generated code]*/
7460
Larry Hastings2f936352014-08-05 14:04:04 +10007461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007462os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007463 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007464/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007465{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007466#ifdef MS_WINDOWS
7467 DWORD result;
7468#else
7469 int result;
7470#endif
7471
Larry Hastings9cf065c2012-06-22 16:30:09 -07007472#ifdef MS_WINDOWS
7473 if (!check_CreateSymbolicLink()) {
7474 PyErr_SetString(PyExc_NotImplementedError,
7475 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007476 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007477 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007478 if (!win32_can_symlink) {
7479 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007480 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007481 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007482#endif
7483
Larry Hastings2f936352014-08-05 14:04:04 +10007484 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007485 PyErr_SetString(PyExc_ValueError,
7486 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007487 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007488 }
7489
7490#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007491
Larry Hastings9cf065c2012-06-22 16:30:09 -07007492 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007493 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007494 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007495 target_is_directory |= _check_dirW(src->wide, dst->wide);
7496 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007497 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007498 }
7499 else {
7500 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007501 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7502 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007503 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007504 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007505 Py_END_ALLOW_THREADS
7506
Larry Hastings2f936352014-08-05 14:04:04 +10007507 if (!result)
7508 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007509
7510#else
7511
7512 Py_BEGIN_ALLOW_THREADS
7513#if HAVE_SYMLINKAT
7514 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007515 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007516 else
7517#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007518 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007519 Py_END_ALLOW_THREADS
7520
Larry Hastings2f936352014-08-05 14:04:04 +10007521 if (result)
7522 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007523#endif
7524
Larry Hastings2f936352014-08-05 14:04:04 +10007525 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007526}
7527#endif /* HAVE_SYMLINK */
7528
Larry Hastings9cf065c2012-06-22 16:30:09 -07007529
Brian Curtind40e6f72010-07-08 21:39:08 +00007530
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007531
Larry Hastings605a62d2012-06-24 04:33:36 -07007532static PyStructSequence_Field times_result_fields[] = {
7533 {"user", "user time"},
7534 {"system", "system time"},
7535 {"children_user", "user time of children"},
7536 {"children_system", "system time of children"},
7537 {"elapsed", "elapsed time since an arbitrary point in the past"},
7538 {NULL}
7539};
7540
7541PyDoc_STRVAR(times_result__doc__,
7542"times_result: Result from os.times().\n\n\
7543This object may be accessed either as a tuple of\n\
7544 (user, system, children_user, children_system, elapsed),\n\
7545or via the attributes user, system, children_user, children_system,\n\
7546and elapsed.\n\
7547\n\
7548See os.times for more information.");
7549
7550static PyStructSequence_Desc times_result_desc = {
7551 "times_result", /* name */
7552 times_result__doc__, /* doc */
7553 times_result_fields,
7554 5
7555};
7556
7557static PyTypeObject TimesResultType;
7558
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007559#ifdef MS_WINDOWS
7560#define HAVE_TIMES /* mandatory, for the method table */
7561#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007562
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007563#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007564
7565static PyObject *
7566build_times_result(double user, double system,
7567 double children_user, double children_system,
7568 double elapsed)
7569{
7570 PyObject *value = PyStructSequence_New(&TimesResultType);
7571 if (value == NULL)
7572 return NULL;
7573
7574#define SET(i, field) \
7575 { \
7576 PyObject *o = PyFloat_FromDouble(field); \
7577 if (!o) { \
7578 Py_DECREF(value); \
7579 return NULL; \
7580 } \
7581 PyStructSequence_SET_ITEM(value, i, o); \
7582 } \
7583
7584 SET(0, user);
7585 SET(1, system);
7586 SET(2, children_user);
7587 SET(3, children_system);
7588 SET(4, elapsed);
7589
7590#undef SET
7591
7592 return value;
7593}
7594
Larry Hastings605a62d2012-06-24 04:33:36 -07007595
Larry Hastings2f936352014-08-05 14:04:04 +10007596#ifndef MS_WINDOWS
7597#define NEED_TICKS_PER_SECOND
7598static long ticks_per_second = -1;
7599#endif /* MS_WINDOWS */
7600
7601/*[clinic input]
7602os.times
7603
7604Return a collection containing process timing information.
7605
7606The object returned behaves like a named tuple with these fields:
7607 (utime, stime, cutime, cstime, elapsed_time)
7608All fields are floating point numbers.
7609[clinic start generated code]*/
7610
Larry Hastings2f936352014-08-05 14:04:04 +10007611static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007612os_times_impl(PyObject *module)
7613/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007614#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007615{
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 FILETIME create, exit, kernel, user;
7617 HANDLE hProc;
7618 hProc = GetCurrentProcess();
7619 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7620 /* The fields of a FILETIME structure are the hi and lo part
7621 of a 64-bit value expressed in 100 nanosecond units.
7622 1e7 is one second in such units; 1e-7 the inverse.
7623 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7624 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007625 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 (double)(user.dwHighDateTime*429.4967296 +
7627 user.dwLowDateTime*1e-7),
7628 (double)(kernel.dwHighDateTime*429.4967296 +
7629 kernel.dwLowDateTime*1e-7),
7630 (double)0,
7631 (double)0,
7632 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007633}
Larry Hastings2f936352014-08-05 14:04:04 +10007634#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007635{
Larry Hastings2f936352014-08-05 14:04:04 +10007636
7637
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007638 struct tms t;
7639 clock_t c;
7640 errno = 0;
7641 c = times(&t);
7642 if (c == (clock_t) -1)
7643 return posix_error();
7644 return build_times_result(
7645 (double)t.tms_utime / ticks_per_second,
7646 (double)t.tms_stime / ticks_per_second,
7647 (double)t.tms_cutime / ticks_per_second,
7648 (double)t.tms_cstime / ticks_per_second,
7649 (double)c / ticks_per_second);
7650}
Larry Hastings2f936352014-08-05 14:04:04 +10007651#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007652#endif /* HAVE_TIMES */
7653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007654
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007655#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007656/*[clinic input]
7657os.getsid
7658
7659 pid: pid_t
7660 /
7661
7662Call the system call getsid(pid) and return the result.
7663[clinic start generated code]*/
7664
Larry Hastings2f936352014-08-05 14:04:04 +10007665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007666os_getsid_impl(PyObject *module, pid_t pid)
7667/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007668{
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 sid = getsid(pid);
7671 if (sid < 0)
7672 return posix_error();
7673 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007674}
7675#endif /* HAVE_GETSID */
7676
7677
Guido van Rossumb6775db1994-08-01 11:34:53 +00007678#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007679/*[clinic input]
7680os.setsid
7681
7682Call the system call setsid().
7683[clinic start generated code]*/
7684
Larry Hastings2f936352014-08-05 14:04:04 +10007685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007686os_setsid_impl(PyObject *module)
7687/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007688{
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 if (setsid() < 0)
7690 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007691 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007692}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007693#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007694
Larry Hastings2f936352014-08-05 14:04:04 +10007695
Guido van Rossumb6775db1994-08-01 11:34:53 +00007696#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007697/*[clinic input]
7698os.setpgid
7699
7700 pid: pid_t
7701 pgrp: pid_t
7702 /
7703
7704Call the system call setpgid(pid, pgrp).
7705[clinic start generated code]*/
7706
Larry Hastings2f936352014-08-05 14:04:04 +10007707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007708os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7709/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007710{
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 if (setpgid(pid, pgrp) < 0)
7712 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007713 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007714}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007715#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007716
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007717
Guido van Rossumb6775db1994-08-01 11:34:53 +00007718#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007719/*[clinic input]
7720os.tcgetpgrp
7721
7722 fd: int
7723 /
7724
7725Return the process group associated with the terminal specified by fd.
7726[clinic start generated code]*/
7727
Larry Hastings2f936352014-08-05 14:04:04 +10007728static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007729os_tcgetpgrp_impl(PyObject *module, int fd)
7730/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007731{
7732 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007733 if (pgid < 0)
7734 return posix_error();
7735 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007736}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007737#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007738
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007739
Guido van Rossumb6775db1994-08-01 11:34:53 +00007740#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007741/*[clinic input]
7742os.tcsetpgrp
7743
7744 fd: int
7745 pgid: pid_t
7746 /
7747
7748Set the process group associated with the terminal specified by fd.
7749[clinic start generated code]*/
7750
Larry Hastings2f936352014-08-05 14:04:04 +10007751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007752os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7753/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007754{
Victor Stinner8c62be82010-05-06 00:08:46 +00007755 if (tcsetpgrp(fd, pgid) < 0)
7756 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007757 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007758}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007759#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007760
Guido van Rossum687dd131993-05-17 08:34:16 +00007761/* Functions acting on file descriptors */
7762
Victor Stinnerdaf45552013-08-28 00:53:59 +02007763#ifdef O_CLOEXEC
7764extern int _Py_open_cloexec_works;
7765#endif
7766
Larry Hastings2f936352014-08-05 14:04:04 +10007767
7768/*[clinic input]
7769os.open -> int
7770 path: path_t
7771 flags: int
7772 mode: int = 0o777
7773 *
7774 dir_fd: dir_fd(requires='openat') = None
7775
7776# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7777
7778Open a file for low level IO. Returns a file descriptor (integer).
7779
7780If dir_fd is not None, it should be a file descriptor open to a directory,
7781 and path should be relative; path will then be relative to that directory.
7782dir_fd may not be implemented on your platform.
7783 If it is unavailable, using it will raise a NotImplementedError.
7784[clinic start generated code]*/
7785
Larry Hastings2f936352014-08-05 14:04:04 +10007786static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007787os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7788/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007789{
7790 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007791 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007792
Victor Stinnerdaf45552013-08-28 00:53:59 +02007793#ifdef O_CLOEXEC
7794 int *atomic_flag_works = &_Py_open_cloexec_works;
7795#elif !defined(MS_WINDOWS)
7796 int *atomic_flag_works = NULL;
7797#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007798
Victor Stinnerdaf45552013-08-28 00:53:59 +02007799#ifdef MS_WINDOWS
7800 flags |= O_NOINHERIT;
7801#elif defined(O_CLOEXEC)
7802 flags |= O_CLOEXEC;
7803#endif
7804
Steve Dower8fc89802015-04-12 00:26:27 -04007805 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007806 do {
7807 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007808#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007809 if (path->wide)
7810 fd = _wopen(path->wide, flags, mode);
7811 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007812#endif
7813#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007814 if (dir_fd != DEFAULT_DIR_FD)
7815 fd = openat(dir_fd, path->narrow, flags, mode);
7816 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007817#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007818 fd = open(path->narrow, flags, mode);
7819 Py_END_ALLOW_THREADS
7820 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007821 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007822
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007823 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007824 if (!async_err)
7825 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007826 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007827 }
7828
Victor Stinnerdaf45552013-08-28 00:53:59 +02007829#ifndef MS_WINDOWS
7830 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7831 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007832 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007833 }
7834#endif
7835
Larry Hastings2f936352014-08-05 14:04:04 +10007836 return fd;
7837}
7838
7839
7840/*[clinic input]
7841os.close
7842
7843 fd: int
7844
7845Close a file descriptor.
7846[clinic start generated code]*/
7847
Barry Warsaw53699e91996-12-10 23:23:01 +00007848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007849os_close_impl(PyObject *module, int fd)
7850/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007851{
Larry Hastings2f936352014-08-05 14:04:04 +10007852 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007853 if (!_PyVerify_fd(fd))
7854 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007855 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7856 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7857 * for more details.
7858 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007860 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007861 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007862 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 Py_END_ALLOW_THREADS
7864 if (res < 0)
7865 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007866 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007867}
7868
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007869
Larry Hastings2f936352014-08-05 14:04:04 +10007870/*[clinic input]
7871os.closerange
7872
7873 fd_low: int
7874 fd_high: int
7875 /
7876
7877Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7878[clinic start generated code]*/
7879
Larry Hastings2f936352014-08-05 14:04:04 +10007880static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007881os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7882/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007883{
7884 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007885 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007886 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007887 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007888 if (_PyVerify_fd(i))
7889 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007890 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007891 Py_END_ALLOW_THREADS
7892 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007893}
7894
7895
Larry Hastings2f936352014-08-05 14:04:04 +10007896/*[clinic input]
7897os.dup -> int
7898
7899 fd: int
7900 /
7901
7902Return a duplicate of a file descriptor.
7903[clinic start generated code]*/
7904
Larry Hastings2f936352014-08-05 14:04:04 +10007905static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007906os_dup_impl(PyObject *module, int fd)
7907/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007908{
7909 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007910}
7911
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007912
Larry Hastings2f936352014-08-05 14:04:04 +10007913/*[clinic input]
7914os.dup2
7915 fd: int
7916 fd2: int
7917 inheritable: bool=True
7918
7919Duplicate file descriptor.
7920[clinic start generated code]*/
7921
Larry Hastings2f936352014-08-05 14:04:04 +10007922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007923os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7924/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007925{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007926 int res;
7927#if defined(HAVE_DUP3) && \
7928 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7929 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7930 int dup3_works = -1;
7931#endif
7932
Victor Stinner8c62be82010-05-06 00:08:46 +00007933 if (!_PyVerify_fd_dup2(fd, fd2))
7934 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007935
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007936 /* dup2() can fail with EINTR if the target FD is already open, because it
7937 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7938 * upon close(), and therefore below.
7939 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007940#ifdef MS_WINDOWS
7941 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007942 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007943 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007944 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007945 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007946 if (res < 0)
7947 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007948
7949 /* Character files like console cannot be make non-inheritable */
7950 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7951 close(fd2);
7952 return NULL;
7953 }
7954
7955#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7956 Py_BEGIN_ALLOW_THREADS
7957 if (!inheritable)
7958 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7959 else
7960 res = dup2(fd, fd2);
7961 Py_END_ALLOW_THREADS
7962 if (res < 0)
7963 return posix_error();
7964
7965#else
7966
7967#ifdef HAVE_DUP3
7968 if (!inheritable && dup3_works != 0) {
7969 Py_BEGIN_ALLOW_THREADS
7970 res = dup3(fd, fd2, O_CLOEXEC);
7971 Py_END_ALLOW_THREADS
7972 if (res < 0) {
7973 if (dup3_works == -1)
7974 dup3_works = (errno != ENOSYS);
7975 if (dup3_works)
7976 return posix_error();
7977 }
7978 }
7979
7980 if (inheritable || dup3_works == 0)
7981 {
7982#endif
7983 Py_BEGIN_ALLOW_THREADS
7984 res = dup2(fd, fd2);
7985 Py_END_ALLOW_THREADS
7986 if (res < 0)
7987 return posix_error();
7988
7989 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7990 close(fd2);
7991 return NULL;
7992 }
7993#ifdef HAVE_DUP3
7994 }
7995#endif
7996
7997#endif
7998
Larry Hastings2f936352014-08-05 14:04:04 +10007999 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00008000}
8001
Larry Hastings2f936352014-08-05 14:04:04 +10008002
Ross Lagerwall7807c352011-03-17 20:20:30 +02008003#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10008004/*[clinic input]
8005os.lockf
8006
8007 fd: int
8008 An open file descriptor.
8009 command: int
8010 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
8011 length: Py_off_t
8012 The number of bytes to lock, starting at the current position.
8013 /
8014
8015Apply, test or remove a POSIX lock on an open file descriptor.
8016
8017[clinic start generated code]*/
8018
Larry Hastings2f936352014-08-05 14:04:04 +10008019static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008020os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
8021/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008022{
8023 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008024
8025 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008026 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008027 Py_END_ALLOW_THREADS
8028
8029 if (res < 0)
8030 return posix_error();
8031
8032 Py_RETURN_NONE;
8033}
Larry Hastings2f936352014-08-05 14:04:04 +10008034#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008036
Larry Hastings2f936352014-08-05 14:04:04 +10008037/*[clinic input]
8038os.lseek -> Py_off_t
8039
8040 fd: int
8041 position: Py_off_t
8042 how: int
8043 /
8044
8045Set the position of a file descriptor. Return the new position.
8046
8047Return the new cursor position in number of bytes
8048relative to the beginning of the file.
8049[clinic start generated code]*/
8050
Larry Hastings2f936352014-08-05 14:04:04 +10008051static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008052os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8053/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008054{
8055 Py_off_t result;
8056
8057 if (!_PyVerify_fd(fd)) {
8058 posix_error();
8059 return -1;
8060 }
Guido van Rossum687dd131993-05-17 08:34:16 +00008061#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8063 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008064 case 0: how = SEEK_SET; break;
8065 case 1: how = SEEK_CUR; break;
8066 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008067 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008068#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008069
Victor Stinner8c62be82010-05-06 00:08:46 +00008070 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008071 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008072
Larry Hastings2f936352014-08-05 14:04:04 +10008073 if (!_PyVerify_fd(fd)) {
8074 posix_error();
8075 return -1;
8076 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008078 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008079#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008080 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008081#else
Larry Hastings2f936352014-08-05 14:04:04 +10008082 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008083#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008084 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008085 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008086 if (result < 0)
8087 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008088
Larry Hastings2f936352014-08-05 14:04:04 +10008089 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008090}
8091
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008092
Larry Hastings2f936352014-08-05 14:04:04 +10008093/*[clinic input]
8094os.read
8095 fd: int
8096 length: Py_ssize_t
8097 /
8098
8099Read from a file descriptor. Returns a bytes object.
8100[clinic start generated code]*/
8101
Larry Hastings2f936352014-08-05 14:04:04 +10008102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008103os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8104/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008105{
Victor Stinner8c62be82010-05-06 00:08:46 +00008106 Py_ssize_t n;
8107 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008108
8109 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008110 errno = EINVAL;
8111 return posix_error();
8112 }
Larry Hastings2f936352014-08-05 14:04:04 +10008113
8114#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008115 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008116 if (length > INT_MAX)
8117 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008118#endif
8119
8120 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008121 if (buffer == NULL)
8122 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008123
Victor Stinner66aab0c2015-03-19 22:53:20 +01008124 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8125 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008126 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008127 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008128 }
Larry Hastings2f936352014-08-05 14:04:04 +10008129
8130 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008131 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008132
Victor Stinner8c62be82010-05-06 00:08:46 +00008133 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008134}
8135
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8137 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008138static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008139iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8140{
8141 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008142 Py_ssize_t blen, total = 0;
8143
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008144 *iov = PyMem_New(struct iovec, cnt);
8145 if (*iov == NULL) {
8146 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008147 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008148 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008149
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008150 *buf = PyMem_New(Py_buffer, cnt);
8151 if (*buf == NULL) {
8152 PyMem_Del(*iov);
8153 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008154 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008155 }
8156
8157 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008158 PyObject *item = PySequence_GetItem(seq, i);
8159 if (item == NULL)
8160 goto fail;
8161 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8162 Py_DECREF(item);
8163 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008164 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008165 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008166 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008167 blen = (*buf)[i].len;
8168 (*iov)[i].iov_len = blen;
8169 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008170 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008171 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008172
8173fail:
8174 PyMem_Del(*iov);
8175 for (j = 0; j < i; j++) {
8176 PyBuffer_Release(&(*buf)[j]);
8177 }
8178 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008179 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008180}
8181
8182static void
8183iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8184{
8185 int i;
8186 PyMem_Del(iov);
8187 for (i = 0; i < cnt; i++) {
8188 PyBuffer_Release(&buf[i]);
8189 }
8190 PyMem_Del(buf);
8191}
8192#endif
8193
Larry Hastings2f936352014-08-05 14:04:04 +10008194
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008196/*[clinic input]
8197os.readv -> Py_ssize_t
8198
8199 fd: int
8200 buffers: object
8201 /
8202
8203Read from a file descriptor fd into an iterable of buffers.
8204
8205The buffers should be mutable buffers accepting bytes.
8206readv will transfer data into each buffer until it is full
8207and then move on to the next buffer in the sequence to hold
8208the rest of the data.
8209
8210readv returns the total number of bytes read,
8211which may be less than the total capacity of all the buffers.
8212[clinic start generated code]*/
8213
Larry Hastings2f936352014-08-05 14:04:04 +10008214static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008215os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8216/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008217{
8218 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008219 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008220 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008221 struct iovec *iov;
8222 Py_buffer *buf;
8223
Larry Hastings2f936352014-08-05 14:04:04 +10008224 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008225 PyErr_SetString(PyExc_TypeError,
8226 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008227 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008228 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008229
Larry Hastings2f936352014-08-05 14:04:04 +10008230 cnt = PySequence_Size(buffers);
8231
8232 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8233 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008234
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008235 do {
8236 Py_BEGIN_ALLOW_THREADS
8237 n = readv(fd, iov, cnt);
8238 Py_END_ALLOW_THREADS
8239 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008240
8241 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008242 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008243 if (!async_err)
8244 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008245 return -1;
8246 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008247
Larry Hastings2f936352014-08-05 14:04:04 +10008248 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008249}
Larry Hastings2f936352014-08-05 14:04:04 +10008250#endif /* HAVE_READV */
8251
Ross Lagerwall7807c352011-03-17 20:20:30 +02008252
8253#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008254/*[clinic input]
8255# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8256os.pread
8257
8258 fd: int
8259 length: int
8260 offset: Py_off_t
8261 /
8262
8263Read a number of bytes from a file descriptor starting at a particular offset.
8264
8265Read length bytes from file descriptor fd, starting at offset bytes from
8266the beginning of the file. The file offset remains unchanged.
8267[clinic start generated code]*/
8268
Larry Hastings2f936352014-08-05 14:04:04 +10008269static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008270os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8271/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008272{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008273 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008274 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008275 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008276
Larry Hastings2f936352014-08-05 14:04:04 +10008277 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008278 errno = EINVAL;
8279 return posix_error();
8280 }
Larry Hastings2f936352014-08-05 14:04:04 +10008281 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008282 if (buffer == NULL)
8283 return NULL;
8284 if (!_PyVerify_fd(fd)) {
8285 Py_DECREF(buffer);
8286 return posix_error();
8287 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008288
8289 do {
8290 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008291 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008292 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008293 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008294 Py_END_ALLOW_THREADS
8295 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8296
Ross Lagerwall7807c352011-03-17 20:20:30 +02008297 if (n < 0) {
8298 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008299 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008300 }
Larry Hastings2f936352014-08-05 14:04:04 +10008301 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008302 _PyBytes_Resize(&buffer, n);
8303 return buffer;
8304}
Larry Hastings2f936352014-08-05 14:04:04 +10008305#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008306
Larry Hastings2f936352014-08-05 14:04:04 +10008307
8308/*[clinic input]
8309os.write -> Py_ssize_t
8310
8311 fd: int
8312 data: Py_buffer
8313 /
8314
8315Write a bytes object to a file descriptor.
8316[clinic start generated code]*/
8317
Larry Hastings2f936352014-08-05 14:04:04 +10008318static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008319os_write_impl(PyObject *module, int fd, Py_buffer *data)
8320/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008321{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008322 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008323}
8324
8325#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008326PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008327"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008328sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008330Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331
Larry Hastings2f936352014-08-05 14:04:04 +10008332/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008333static PyObject *
8334posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8335{
8336 int in, out;
8337 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008338 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008339 off_t offset;
8340
8341#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8342#ifndef __APPLE__
8343 Py_ssize_t len;
8344#endif
8345 PyObject *headers = NULL, *trailers = NULL;
8346 Py_buffer *hbuf, *tbuf;
8347 off_t sbytes;
8348 struct sf_hdtr sf;
8349 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008350 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008351 static char *keywords[] = {"out", "in",
8352 "offset", "count",
8353 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008354
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008355 sf.headers = NULL;
8356 sf.trailers = NULL;
8357
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008358#ifdef __APPLE__
8359 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008360 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008361#else
8362 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008363 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008364#endif
8365 &headers, &trailers, &flags))
8366 return NULL;
8367 if (headers != NULL) {
8368 if (!PySequence_Check(headers)) {
8369 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008370 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008371 return NULL;
8372 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008373 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008374 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008375 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008376 (i = iov_setup(&(sf.headers), &hbuf,
8377 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008378 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008379#ifdef __APPLE__
8380 sbytes += i;
8381#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008382 }
8383 }
8384 if (trailers != NULL) {
8385 if (!PySequence_Check(trailers)) {
8386 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008387 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008388 return NULL;
8389 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008390 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008391 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008392 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008393 (i = iov_setup(&(sf.trailers), &tbuf,
8394 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008395 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008396#ifdef __APPLE__
8397 sbytes += i;
8398#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008399 }
8400 }
8401
Steve Dower8fc89802015-04-12 00:26:27 -04008402 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008403 do {
8404 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008405#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008406 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008407#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008408 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008409#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008410 Py_END_ALLOW_THREADS
8411 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008412 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008413
8414 if (sf.headers != NULL)
8415 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8416 if (sf.trailers != NULL)
8417 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8418
8419 if (ret < 0) {
8420 if ((errno == EAGAIN) || (errno == EBUSY)) {
8421 if (sbytes != 0) {
8422 // some data has been sent
8423 goto done;
8424 }
8425 else {
8426 // no data has been sent; upper application is supposed
8427 // to retry on EAGAIN or EBUSY
8428 return posix_error();
8429 }
8430 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008431 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008432 }
8433 goto done;
8434
8435done:
8436 #if !defined(HAVE_LARGEFILE_SUPPORT)
8437 return Py_BuildValue("l", sbytes);
8438 #else
8439 return Py_BuildValue("L", sbytes);
8440 #endif
8441
8442#else
8443 Py_ssize_t count;
8444 PyObject *offobj;
8445 static char *keywords[] = {"out", "in",
8446 "offset", "count", NULL};
8447 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8448 keywords, &out, &in, &offobj, &count))
8449 return NULL;
8450#ifdef linux
8451 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008452 do {
8453 Py_BEGIN_ALLOW_THREADS
8454 ret = sendfile(out, in, NULL, count);
8455 Py_END_ALLOW_THREADS
8456 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008457 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008458 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008459 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008460 }
8461#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008462 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008463 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008464
8465 do {
8466 Py_BEGIN_ALLOW_THREADS
8467 ret = sendfile(out, in, &offset, count);
8468 Py_END_ALLOW_THREADS
8469 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008470 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008471 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008472 return Py_BuildValue("n", ret);
8473#endif
8474}
Larry Hastings2f936352014-08-05 14:04:04 +10008475#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008476
Larry Hastings2f936352014-08-05 14:04:04 +10008477
8478/*[clinic input]
8479os.fstat
8480
8481 fd : int
8482
8483Perform a stat system call on the given file descriptor.
8484
8485Like stat(), but for an open file descriptor.
8486Equivalent to os.stat(fd).
8487[clinic start generated code]*/
8488
Larry Hastings2f936352014-08-05 14:04:04 +10008489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008490os_fstat_impl(PyObject *module, int fd)
8491/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008492{
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 STRUCT_STAT st;
8494 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008495 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008496
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008497 do {
8498 Py_BEGIN_ALLOW_THREADS
8499 res = FSTAT(fd, &st);
8500 Py_END_ALLOW_THREADS
8501 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008502 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008503#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008504 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008505#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008506 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008507#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008508 }
Tim Peters5aa91602002-01-30 05:46:57 +00008509
Victor Stinner4195b5c2012-02-08 23:03:19 +01008510 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008511}
8512
Larry Hastings2f936352014-08-05 14:04:04 +10008513
8514/*[clinic input]
8515os.isatty -> bool
8516 fd: int
8517 /
8518
8519Return True if the fd is connected to a terminal.
8520
8521Return True if the file descriptor is an open file descriptor
8522connected to the slave end of a terminal.
8523[clinic start generated code]*/
8524
Larry Hastings2f936352014-08-05 14:04:04 +10008525static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008526os_isatty_impl(PyObject *module, int fd)
8527/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008528{
Steve Dower8fc89802015-04-12 00:26:27 -04008529 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008530 if (!_PyVerify_fd(fd))
8531 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008532 _Py_BEGIN_SUPPRESS_IPH
8533 return_value = isatty(fd);
8534 _Py_END_SUPPRESS_IPH
8535 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008536}
8537
8538
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008539#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008540/*[clinic input]
8541os.pipe
8542
8543Create a pipe.
8544
8545Returns a tuple of two file descriptors:
8546 (read_fd, write_fd)
8547[clinic start generated code]*/
8548
Larry Hastings2f936352014-08-05 14:04:04 +10008549static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008550os_pipe_impl(PyObject *module)
8551/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008552{
Victor Stinner8c62be82010-05-06 00:08:46 +00008553 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008554#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008555 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008556 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008557 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008558#else
8559 int res;
8560#endif
8561
8562#ifdef MS_WINDOWS
8563 attr.nLength = sizeof(attr);
8564 attr.lpSecurityDescriptor = NULL;
8565 attr.bInheritHandle = FALSE;
8566
8567 Py_BEGIN_ALLOW_THREADS
8568 ok = CreatePipe(&read, &write, &attr, 0);
8569 if (ok) {
8570 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8571 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8572 if (fds[0] == -1 || fds[1] == -1) {
8573 CloseHandle(read);
8574 CloseHandle(write);
8575 ok = 0;
8576 }
8577 }
8578 Py_END_ALLOW_THREADS
8579
Victor Stinner8c62be82010-05-06 00:08:46 +00008580 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008581 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008582#else
8583
8584#ifdef HAVE_PIPE2
8585 Py_BEGIN_ALLOW_THREADS
8586 res = pipe2(fds, O_CLOEXEC);
8587 Py_END_ALLOW_THREADS
8588
8589 if (res != 0 && errno == ENOSYS)
8590 {
8591#endif
8592 Py_BEGIN_ALLOW_THREADS
8593 res = pipe(fds);
8594 Py_END_ALLOW_THREADS
8595
8596 if (res == 0) {
8597 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8598 close(fds[0]);
8599 close(fds[1]);
8600 return NULL;
8601 }
8602 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8603 close(fds[0]);
8604 close(fds[1]);
8605 return NULL;
8606 }
8607 }
8608#ifdef HAVE_PIPE2
8609 }
8610#endif
8611
8612 if (res != 0)
8613 return PyErr_SetFromErrno(PyExc_OSError);
8614#endif /* !MS_WINDOWS */
8615 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008616}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008617#endif /* HAVE_PIPE */
8618
Larry Hastings2f936352014-08-05 14:04:04 +10008619
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008620#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008621/*[clinic input]
8622os.pipe2
8623
8624 flags: int
8625 /
8626
8627Create a pipe with flags set atomically.
8628
8629Returns a tuple of two file descriptors:
8630 (read_fd, write_fd)
8631
8632flags can be constructed by ORing together one or more of these values:
8633O_NONBLOCK, O_CLOEXEC.
8634[clinic start generated code]*/
8635
Larry Hastings2f936352014-08-05 14:04:04 +10008636static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008637os_pipe2_impl(PyObject *module, int flags)
8638/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008639{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008640 int fds[2];
8641 int res;
8642
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008643 res = pipe2(fds, flags);
8644 if (res != 0)
8645 return posix_error();
8646 return Py_BuildValue("(ii)", fds[0], fds[1]);
8647}
8648#endif /* HAVE_PIPE2 */
8649
Larry Hastings2f936352014-08-05 14:04:04 +10008650
Ross Lagerwall7807c352011-03-17 20:20:30 +02008651#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008652/*[clinic input]
8653os.writev -> Py_ssize_t
8654 fd: int
8655 buffers: object
8656 /
8657
8658Iterate over buffers, and write the contents of each to a file descriptor.
8659
8660Returns the total number of bytes written.
8661buffers must be a sequence of bytes-like objects.
8662[clinic start generated code]*/
8663
Larry Hastings2f936352014-08-05 14:04:04 +10008664static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008665os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8666/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008667{
8668 int cnt;
8669 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008670 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008671 struct iovec *iov;
8672 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008673
8674 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008675 PyErr_SetString(PyExc_TypeError,
8676 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008677 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008678 }
Larry Hastings2f936352014-08-05 14:04:04 +10008679 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008680
Larry Hastings2f936352014-08-05 14:04:04 +10008681 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8682 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683 }
8684
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008685 do {
8686 Py_BEGIN_ALLOW_THREADS
8687 result = writev(fd, iov, cnt);
8688 Py_END_ALLOW_THREADS
8689 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008690
8691 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008693 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008694
Georg Brandl306336b2012-06-24 12:55:33 +02008695 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008696}
Larry Hastings2f936352014-08-05 14:04:04 +10008697#endif /* HAVE_WRITEV */
8698
8699
8700#ifdef HAVE_PWRITE
8701/*[clinic input]
8702os.pwrite -> Py_ssize_t
8703
8704 fd: int
8705 buffer: Py_buffer
8706 offset: Py_off_t
8707 /
8708
8709Write bytes to a file descriptor starting at a particular offset.
8710
8711Write buffer to fd, starting at offset bytes from the beginning of
8712the file. Returns the number of bytes writte. Does not change the
8713current file offset.
8714[clinic start generated code]*/
8715
Larry Hastings2f936352014-08-05 14:04:04 +10008716static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008717os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8718/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008719{
8720 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008721 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008722
8723 if (!_PyVerify_fd(fd)) {
8724 posix_error();
8725 return -1;
8726 }
8727
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008728 do {
8729 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008730 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008731 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008732 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008733 Py_END_ALLOW_THREADS
8734 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008735
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008736 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008737 posix_error();
8738 return size;
8739}
8740#endif /* HAVE_PWRITE */
8741
8742
8743#ifdef HAVE_MKFIFO
8744/*[clinic input]
8745os.mkfifo
8746
8747 path: path_t
8748 mode: int=0o666
8749 *
8750 dir_fd: dir_fd(requires='mkfifoat')=None
8751
8752Create a "fifo" (a POSIX named pipe).
8753
8754If dir_fd is not None, it should be a file descriptor open to a directory,
8755 and path should be relative; path will then be relative to that directory.
8756dir_fd may not be implemented on your platform.
8757 If it is unavailable, using it will raise a NotImplementedError.
8758[clinic start generated code]*/
8759
Larry Hastings2f936352014-08-05 14:04:04 +10008760static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008761os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8762/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008763{
8764 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008765 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008766
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008767 do {
8768 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008769#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008770 if (dir_fd != DEFAULT_DIR_FD)
8771 result = mkfifoat(dir_fd, path->narrow, mode);
8772 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008773#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008774 result = mkfifo(path->narrow, mode);
8775 Py_END_ALLOW_THREADS
8776 } while (result != 0 && errno == EINTR &&
8777 !(async_err = PyErr_CheckSignals()));
8778 if (result != 0)
8779 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008780
8781 Py_RETURN_NONE;
8782}
8783#endif /* HAVE_MKFIFO */
8784
8785
8786#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8787/*[clinic input]
8788os.mknod
8789
8790 path: path_t
8791 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008792 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008793 *
8794 dir_fd: dir_fd(requires='mknodat')=None
8795
8796Create a node in the file system.
8797
8798Create a node in the file system (file, device special file or named pipe)
8799at path. mode specifies both the permissions to use and the
8800type of node to be created, being combined (bitwise OR) with one of
8801S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8802device defines the newly created device special file (probably using
8803os.makedev()). Otherwise device is ignored.
8804
8805If dir_fd is not None, it should be a file descriptor open to a directory,
8806 and path should be relative; path will then be relative to that directory.
8807dir_fd may not be implemented on your platform.
8808 If it is unavailable, using it will raise a NotImplementedError.
8809[clinic start generated code]*/
8810
Larry Hastings2f936352014-08-05 14:04:04 +10008811static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008812os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008813 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008814/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008815{
8816 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008817 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008818
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008819 do {
8820 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008821#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008822 if (dir_fd != DEFAULT_DIR_FD)
8823 result = mknodat(dir_fd, path->narrow, mode, device);
8824 else
Larry Hastings2f936352014-08-05 14:04:04 +10008825#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008826 result = mknod(path->narrow, mode, device);
8827 Py_END_ALLOW_THREADS
8828 } while (result != 0 && errno == EINTR &&
8829 !(async_err = PyErr_CheckSignals()));
8830 if (result != 0)
8831 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008832
8833 Py_RETURN_NONE;
8834}
8835#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8836
8837
8838#ifdef HAVE_DEVICE_MACROS
8839/*[clinic input]
8840os.major -> unsigned_int
8841
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008842 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008843 /
8844
8845Extracts a device major number from a raw device number.
8846[clinic start generated code]*/
8847
Larry Hastings2f936352014-08-05 14:04:04 +10008848static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008849os_major_impl(PyObject *module, dev_t device)
8850/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008851{
8852 return major(device);
8853}
8854
8855
8856/*[clinic input]
8857os.minor -> unsigned_int
8858
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008859 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008860 /
8861
8862Extracts a device minor number from a raw device number.
8863[clinic start generated code]*/
8864
Larry Hastings2f936352014-08-05 14:04:04 +10008865static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008866os_minor_impl(PyObject *module, dev_t device)
8867/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008868{
8869 return minor(device);
8870}
8871
8872
8873/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008874os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008875
8876 major: int
8877 minor: int
8878 /
8879
8880Composes a raw device number from the major and minor device numbers.
8881[clinic start generated code]*/
8882
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008883static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008884os_makedev_impl(PyObject *module, int major, int minor)
8885/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008886{
8887 return makedev(major, minor);
8888}
8889#endif /* HAVE_DEVICE_MACROS */
8890
8891
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008892#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008893/*[clinic input]
8894os.ftruncate
8895
8896 fd: int
8897 length: Py_off_t
8898 /
8899
8900Truncate a file, specified by file descriptor, to a specific length.
8901[clinic start generated code]*/
8902
Larry Hastings2f936352014-08-05 14:04:04 +10008903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008904os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8905/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008906{
8907 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008908 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008909
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008910 if (!_PyVerify_fd(fd))
8911 return posix_error();
8912
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008913 do {
8914 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008915 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008916#ifdef MS_WINDOWS
8917 result = _chsize_s(fd, length);
8918#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008919 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008920#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008921 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008922 Py_END_ALLOW_THREADS
8923 } while (result != 0 && errno == EINTR &&
8924 !(async_err = PyErr_CheckSignals()));
8925 if (result != 0)
8926 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008927 Py_RETURN_NONE;
8928}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008929#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008930
8931
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008932#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008933/*[clinic input]
8934os.truncate
8935 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8936 length: Py_off_t
8937
8938Truncate a file, specified by path, to a specific length.
8939
8940On some platforms, path may also be specified as an open file descriptor.
8941 If this functionality is unavailable, using it raises an exception.
8942[clinic start generated code]*/
8943
Larry Hastings2f936352014-08-05 14:04:04 +10008944static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008945os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8946/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008947{
8948 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008949#ifdef MS_WINDOWS
8950 int fd;
8951#endif
8952
8953 if (path->fd != -1)
8954 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008955
8956 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008957 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008958#ifdef MS_WINDOWS
8959 if (path->wide)
8960 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008961 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008962 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008963 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008964 result = -1;
8965 else {
8966 result = _chsize_s(fd, length);
8967 close(fd);
8968 if (result < 0)
8969 errno = result;
8970 }
8971#else
8972 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008973#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008974 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008975 Py_END_ALLOW_THREADS
8976 if (result < 0)
8977 return path_error(path);
8978
8979 Py_RETURN_NONE;
8980}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008981#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008982
Ross Lagerwall7807c352011-03-17 20:20:30 +02008983
Victor Stinnerd6b17692014-09-30 12:20:05 +02008984/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8985 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8986 defined, which is the case in Python on AIX. AIX bug report:
8987 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8988#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8989# define POSIX_FADVISE_AIX_BUG
8990#endif
8991
Victor Stinnerec39e262014-09-30 12:35:58 +02008992
Victor Stinnerd6b17692014-09-30 12:20:05 +02008993#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008994/*[clinic input]
8995os.posix_fallocate
8996
8997 fd: int
8998 offset: Py_off_t
8999 length: Py_off_t
9000 /
9001
9002Ensure a file has allocated at least a particular number of bytes on disk.
9003
9004Ensure that the file specified by fd encompasses a range of bytes
9005starting at offset bytes from the beginning and continuing for length bytes.
9006[clinic start generated code]*/
9007
Larry Hastings2f936352014-08-05 14:04:04 +10009008static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009009os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009010 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009011/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009012{
9013 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009015
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009016 do {
9017 Py_BEGIN_ALLOW_THREADS
9018 result = posix_fallocate(fd, offset, length);
9019 Py_END_ALLOW_THREADS
9020 } while (result != 0 && errno == EINTR &&
9021 !(async_err = PyErr_CheckSignals()));
9022 if (result != 0)
9023 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009024 Py_RETURN_NONE;
9025}
Victor Stinnerec39e262014-09-30 12:35:58 +02009026#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10009027
Ross Lagerwall7807c352011-03-17 20:20:30 +02009028
Victor Stinnerd6b17692014-09-30 12:20:05 +02009029#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10009030/*[clinic input]
9031os.posix_fadvise
9032
9033 fd: int
9034 offset: Py_off_t
9035 length: Py_off_t
9036 advice: int
9037 /
9038
9039Announce an intention to access data in a specific pattern.
9040
9041Announce an intention to access data in a specific pattern, thus allowing
9042the kernel to make optimizations.
9043The advice applies to the region of the file specified by fd starting at
9044offset and continuing for length bytes.
9045advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9046POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9047POSIX_FADV_DONTNEED.
9048[clinic start generated code]*/
9049
Larry Hastings2f936352014-08-05 14:04:04 +10009050static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009051os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009052 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009053/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009054{
9055 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009056 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009057
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009058 do {
9059 Py_BEGIN_ALLOW_THREADS
9060 result = posix_fadvise(fd, offset, length, advice);
9061 Py_END_ALLOW_THREADS
9062 } while (result != 0 && errno == EINTR &&
9063 !(async_err = PyErr_CheckSignals()));
9064 if (result != 0)
9065 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009066 Py_RETURN_NONE;
9067}
Victor Stinnerec39e262014-09-30 12:35:58 +02009068#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009069
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009070#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009071
Fred Drake762e2061999-08-26 17:23:54 +00009072/* Save putenv() parameters as values here, so we can collect them when they
9073 * get re-set with another call for the same key. */
9074static PyObject *posix_putenv_garbage;
9075
Larry Hastings2f936352014-08-05 14:04:04 +10009076static void
9077posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009078{
Larry Hastings2f936352014-08-05 14:04:04 +10009079 /* Install the first arg and newstr in posix_putenv_garbage;
9080 * this will cause previous value to be collected. This has to
9081 * happen after the real putenv() call because the old value
9082 * was still accessible until then. */
9083 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9084 /* really not much we can do; just leak */
9085 PyErr_Clear();
9086 else
9087 Py_DECREF(value);
9088}
9089
9090
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009091#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009092/*[clinic input]
9093os.putenv
9094
9095 name: unicode
9096 value: unicode
9097 /
9098
9099Change or add an environment variable.
9100[clinic start generated code]*/
9101
Larry Hastings2f936352014-08-05 14:04:04 +10009102static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009103os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9104/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009105{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009106 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10009107
9108 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9109 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009110 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009111 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009112 }
Larry Hastings2f936352014-08-05 14:04:04 +10009113 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009114 PyErr_Format(PyExc_ValueError,
9115 "the environment variable is longer than %u characters",
9116 _MAX_ENV);
9117 goto error;
9118 }
9119
Larry Hastings2f936352014-08-05 14:04:04 +10009120 env = PyUnicode_AsUnicode(unicode);
9121 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009122 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009123 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009124 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009125 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009127
Larry Hastings2f936352014-08-05 14:04:04 +10009128 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009129 Py_RETURN_NONE;
9130
9131error:
Larry Hastings2f936352014-08-05 14:04:04 +10009132 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009133 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009134}
Larry Hastings2f936352014-08-05 14:04:04 +10009135#else /* MS_WINDOWS */
9136/*[clinic input]
9137os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009138
Larry Hastings2f936352014-08-05 14:04:04 +10009139 name: FSConverter
9140 value: FSConverter
9141 /
9142
9143Change or add an environment variable.
9144[clinic start generated code]*/
9145
Larry Hastings2f936352014-08-05 14:04:04 +10009146static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009147os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9148/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009149{
9150 PyObject *bytes = NULL;
9151 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009152 const char *name_string = PyBytes_AsString(name);
9153 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009154
9155 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9156 if (bytes == NULL) {
9157 PyErr_NoMemory();
9158 return NULL;
9159 }
9160
9161 env = PyBytes_AS_STRING(bytes);
9162 if (putenv(env)) {
9163 Py_DECREF(bytes);
9164 return posix_error();
9165 }
9166
9167 posix_putenv_garbage_setitem(name, bytes);
9168 Py_RETURN_NONE;
9169}
9170#endif /* MS_WINDOWS */
9171#endif /* HAVE_PUTENV */
9172
9173
9174#ifdef HAVE_UNSETENV
9175/*[clinic input]
9176os.unsetenv
9177 name: FSConverter
9178 /
9179
9180Delete an environment variable.
9181[clinic start generated code]*/
9182
Larry Hastings2f936352014-08-05 14:04:04 +10009183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009184os_unsetenv_impl(PyObject *module, PyObject *name)
9185/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009186{
Victor Stinner984890f2011-11-24 13:53:38 +01009187#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009188 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009189#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009190
Victor Stinner984890f2011-11-24 13:53:38 +01009191#ifdef HAVE_BROKEN_UNSETENV
9192 unsetenv(PyBytes_AS_STRING(name));
9193#else
Victor Stinner65170952011-11-22 22:16:17 +01009194 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009195 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009196 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009197#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009198
Victor Stinner8c62be82010-05-06 00:08:46 +00009199 /* Remove the key from posix_putenv_garbage;
9200 * this will cause it to be collected. This has to
9201 * happen after the real unsetenv() call because the
9202 * old value was still accessible until then.
9203 */
Victor Stinner65170952011-11-22 22:16:17 +01009204 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009205 /* really not much we can do; just leak */
9206 PyErr_Clear();
9207 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009208 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009209}
Larry Hastings2f936352014-08-05 14:04:04 +10009210#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009211
Larry Hastings2f936352014-08-05 14:04:04 +10009212
9213/*[clinic input]
9214os.strerror
9215
9216 code: int
9217 /
9218
9219Translate an error code to a message string.
9220[clinic start generated code]*/
9221
Larry Hastings2f936352014-08-05 14:04:04 +10009222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009223os_strerror_impl(PyObject *module, int code)
9224/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009225{
9226 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009227 if (message == NULL) {
9228 PyErr_SetString(PyExc_ValueError,
9229 "strerror() argument out of range");
9230 return NULL;
9231 }
Victor Stinner1b579672011-12-17 05:47:23 +01009232 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009233}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009234
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009235
Guido van Rossumc9641791998-08-04 15:26:23 +00009236#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009237#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009238/*[clinic input]
9239os.WCOREDUMP -> bool
9240
9241 status: int
9242 /
9243
9244Return True if the process returning status was dumped to a core file.
9245[clinic start generated code]*/
9246
Larry Hastings2f936352014-08-05 14:04:04 +10009247static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009248os_WCOREDUMP_impl(PyObject *module, int status)
9249/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009250{
9251 WAIT_TYPE wait_status;
9252 WAIT_STATUS_INT(wait_status) = status;
9253 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009254}
9255#endif /* WCOREDUMP */
9256
Larry Hastings2f936352014-08-05 14:04:04 +10009257
Fred Drake106c1a02002-04-23 15:58:02 +00009258#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009259/*[clinic input]
9260os.WIFCONTINUED -> bool
9261
9262 status: int
9263
9264Return True if a particular process was continued from a job control stop.
9265
9266Return True if the process returning status was continued from a
9267job control stop.
9268[clinic start generated code]*/
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009271os_WIFCONTINUED_impl(PyObject *module, int status)
9272/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009273{
9274 WAIT_TYPE wait_status;
9275 WAIT_STATUS_INT(wait_status) = status;
9276 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009277}
9278#endif /* WIFCONTINUED */
9279
Larry Hastings2f936352014-08-05 14:04:04 +10009280
Guido van Rossumc9641791998-08-04 15:26:23 +00009281#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009282/*[clinic input]
9283os.WIFSTOPPED -> bool
9284
9285 status: int
9286
9287Return True if the process returning status was stopped.
9288[clinic start generated code]*/
9289
Larry Hastings2f936352014-08-05 14:04:04 +10009290static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009291os_WIFSTOPPED_impl(PyObject *module, int status)
9292/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009293{
9294 WAIT_TYPE wait_status;
9295 WAIT_STATUS_INT(wait_status) = status;
9296 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009297}
9298#endif /* WIFSTOPPED */
9299
Larry Hastings2f936352014-08-05 14:04:04 +10009300
Guido van Rossumc9641791998-08-04 15:26:23 +00009301#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009302/*[clinic input]
9303os.WIFSIGNALED -> bool
9304
9305 status: int
9306
9307Return True if the process returning status was terminated by a signal.
9308[clinic start generated code]*/
9309
Larry Hastings2f936352014-08-05 14:04:04 +10009310static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009311os_WIFSIGNALED_impl(PyObject *module, int status)
9312/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009313{
9314 WAIT_TYPE wait_status;
9315 WAIT_STATUS_INT(wait_status) = status;
9316 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009317}
9318#endif /* WIFSIGNALED */
9319
Larry Hastings2f936352014-08-05 14:04:04 +10009320
Guido van Rossumc9641791998-08-04 15:26:23 +00009321#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009322/*[clinic input]
9323os.WIFEXITED -> bool
9324
9325 status: int
9326
9327Return True if the process returning status exited via the exit() system call.
9328[clinic start generated code]*/
9329
Larry Hastings2f936352014-08-05 14:04:04 +10009330static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009331os_WIFEXITED_impl(PyObject *module, int status)
9332/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009333{
9334 WAIT_TYPE wait_status;
9335 WAIT_STATUS_INT(wait_status) = status;
9336 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009337}
9338#endif /* WIFEXITED */
9339
Larry Hastings2f936352014-08-05 14:04:04 +10009340
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009341#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009342/*[clinic input]
9343os.WEXITSTATUS -> int
9344
9345 status: int
9346
9347Return the process return code from status.
9348[clinic start generated code]*/
9349
Larry Hastings2f936352014-08-05 14:04:04 +10009350static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009351os_WEXITSTATUS_impl(PyObject *module, int status)
9352/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009353{
9354 WAIT_TYPE wait_status;
9355 WAIT_STATUS_INT(wait_status) = status;
9356 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009357}
9358#endif /* WEXITSTATUS */
9359
Larry Hastings2f936352014-08-05 14:04:04 +10009360
Guido van Rossumc9641791998-08-04 15:26:23 +00009361#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009362/*[clinic input]
9363os.WTERMSIG -> int
9364
9365 status: int
9366
9367Return the signal that terminated the process that provided the status value.
9368[clinic start generated code]*/
9369
Larry Hastings2f936352014-08-05 14:04:04 +10009370static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009371os_WTERMSIG_impl(PyObject *module, int status)
9372/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009373{
9374 WAIT_TYPE wait_status;
9375 WAIT_STATUS_INT(wait_status) = status;
9376 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009377}
9378#endif /* WTERMSIG */
9379
Larry Hastings2f936352014-08-05 14:04:04 +10009380
Guido van Rossumc9641791998-08-04 15:26:23 +00009381#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009382/*[clinic input]
9383os.WSTOPSIG -> int
9384
9385 status: int
9386
9387Return the signal that stopped the process that provided the status value.
9388[clinic start generated code]*/
9389
Larry Hastings2f936352014-08-05 14:04:04 +10009390static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009391os_WSTOPSIG_impl(PyObject *module, int status)
9392/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009393{
9394 WAIT_TYPE wait_status;
9395 WAIT_STATUS_INT(wait_status) = status;
9396 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009397}
9398#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009399#endif /* HAVE_SYS_WAIT_H */
9400
9401
Thomas Wouters477c8d52006-05-27 19:21:47 +00009402#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009403#ifdef _SCO_DS
9404/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9405 needed definitions in sys/statvfs.h */
9406#define _SVID3
9407#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009408#include <sys/statvfs.h>
9409
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009410static PyObject*
9411_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9413 if (v == NULL)
9414 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009415
9416#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009417 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9418 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9419 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9420 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9421 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9422 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9423 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9424 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9425 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9426 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009427#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009428 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9429 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9430 PyStructSequence_SET_ITEM(v, 2,
9431 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9432 PyStructSequence_SET_ITEM(v, 3,
9433 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9434 PyStructSequence_SET_ITEM(v, 4,
9435 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9436 PyStructSequence_SET_ITEM(v, 5,
9437 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9438 PyStructSequence_SET_ITEM(v, 6,
9439 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9440 PyStructSequence_SET_ITEM(v, 7,
9441 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9442 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9443 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009444#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009445 if (PyErr_Occurred()) {
9446 Py_DECREF(v);
9447 return NULL;
9448 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009449
Victor Stinner8c62be82010-05-06 00:08:46 +00009450 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009451}
9452
Larry Hastings2f936352014-08-05 14:04:04 +10009453
9454/*[clinic input]
9455os.fstatvfs
9456 fd: int
9457 /
9458
9459Perform an fstatvfs system call on the given fd.
9460
9461Equivalent to statvfs(fd).
9462[clinic start generated code]*/
9463
Larry Hastings2f936352014-08-05 14:04:04 +10009464static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009465os_fstatvfs_impl(PyObject *module, int fd)
9466/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009467{
9468 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009469 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009470 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009471
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009472 do {
9473 Py_BEGIN_ALLOW_THREADS
9474 result = fstatvfs(fd, &st);
9475 Py_END_ALLOW_THREADS
9476 } while (result != 0 && errno == EINTR &&
9477 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009478 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009479 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009480
Victor Stinner8c62be82010-05-06 00:08:46 +00009481 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009482}
Larry Hastings2f936352014-08-05 14:04:04 +10009483#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009484
9485
Thomas Wouters477c8d52006-05-27 19:21:47 +00009486#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009487#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009488/*[clinic input]
9489os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009490
Larry Hastings2f936352014-08-05 14:04:04 +10009491 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9492
9493Perform a statvfs system call on the given path.
9494
9495path may always be specified as a string.
9496On some platforms, path may also be specified as an open file descriptor.
9497 If this functionality is unavailable, using it raises an exception.
9498[clinic start generated code]*/
9499
Larry Hastings2f936352014-08-05 14:04:04 +10009500static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009501os_statvfs_impl(PyObject *module, path_t *path)
9502/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009503{
9504 int result;
9505 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009506
9507 Py_BEGIN_ALLOW_THREADS
9508#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009509 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009510#ifdef __APPLE__
9511 /* handle weak-linking on Mac OS X 10.3 */
9512 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009513 fd_specified("statvfs", path->fd);
9514 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009515 }
9516#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009517 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009518 }
9519 else
9520#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009521 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009522 Py_END_ALLOW_THREADS
9523
9524 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009525 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009526 }
9527
Larry Hastings2f936352014-08-05 14:04:04 +10009528 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009529}
Larry Hastings2f936352014-08-05 14:04:04 +10009530#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9531
Guido van Rossum94f6f721999-01-06 18:42:14 +00009532
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009533#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009534/*[clinic input]
9535os._getdiskusage
9536
9537 path: Py_UNICODE
9538
9539Return disk usage statistics about the given path as a (total, free) tuple.
9540[clinic start generated code]*/
9541
Larry Hastings2f936352014-08-05 14:04:04 +10009542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009543os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9544/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009545{
9546 BOOL retval;
9547 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009548
9549 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009550 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009551 Py_END_ALLOW_THREADS
9552 if (retval == 0)
9553 return PyErr_SetFromWindowsErr(0);
9554
9555 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9556}
Larry Hastings2f936352014-08-05 14:04:04 +10009557#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009558
9559
Fred Drakec9680921999-12-13 16:37:25 +00009560/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9561 * It maps strings representing configuration variable names to
9562 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009563 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009564 * rarely-used constants. There are three separate tables that use
9565 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009566 *
9567 * This code is always included, even if none of the interfaces that
9568 * need it are included. The #if hackery needed to avoid it would be
9569 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009570 */
9571struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009572 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009573 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009574};
9575
Fred Drake12c6e2d1999-12-14 21:25:03 +00009576static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009577conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009578 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009579{
Christian Heimes217cfd12007-12-02 14:31:20 +00009580 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009581 int value = _PyLong_AsInt(arg);
9582 if (value == -1 && PyErr_Occurred())
9583 return 0;
9584 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009585 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009586 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009587 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009588 /* look up the value in the table using a binary search */
9589 size_t lo = 0;
9590 size_t mid;
9591 size_t hi = tablesize;
9592 int cmp;
9593 const char *confname;
9594 if (!PyUnicode_Check(arg)) {
9595 PyErr_SetString(PyExc_TypeError,
9596 "configuration names must be strings or integers");
9597 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009599 confname = _PyUnicode_AsString(arg);
9600 if (confname == NULL)
9601 return 0;
9602 while (lo < hi) {
9603 mid = (lo + hi) / 2;
9604 cmp = strcmp(confname, table[mid].name);
9605 if (cmp < 0)
9606 hi = mid;
9607 else if (cmp > 0)
9608 lo = mid + 1;
9609 else {
9610 *valuep = table[mid].value;
9611 return 1;
9612 }
9613 }
9614 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9615 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009616 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009617}
9618
9619
9620#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9621static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009622#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009623 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009624#endif
9625#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009626 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009627#endif
Fred Drakec9680921999-12-13 16:37:25 +00009628#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009629 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009630#endif
9631#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009632 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009633#endif
9634#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009635 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009636#endif
9637#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009638 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009639#endif
9640#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009641 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009642#endif
9643#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009644 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009645#endif
9646#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009647 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009648#endif
9649#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009651#endif
9652#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009653 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009654#endif
9655#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009656 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009657#endif
9658#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009660#endif
9661#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009662 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009663#endif
9664#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009666#endif
9667#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009668 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009669#endif
9670#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009671 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009672#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009673#ifdef _PC_ACL_ENABLED
9674 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9675#endif
9676#ifdef _PC_MIN_HOLE_SIZE
9677 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9678#endif
9679#ifdef _PC_ALLOC_SIZE_MIN
9680 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9681#endif
9682#ifdef _PC_REC_INCR_XFER_SIZE
9683 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9684#endif
9685#ifdef _PC_REC_MAX_XFER_SIZE
9686 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9687#endif
9688#ifdef _PC_REC_MIN_XFER_SIZE
9689 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9690#endif
9691#ifdef _PC_REC_XFER_ALIGN
9692 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9693#endif
9694#ifdef _PC_SYMLINK_MAX
9695 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9696#endif
9697#ifdef _PC_XATTR_ENABLED
9698 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9699#endif
9700#ifdef _PC_XATTR_EXISTS
9701 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9702#endif
9703#ifdef _PC_TIMESTAMP_RESOLUTION
9704 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9705#endif
Fred Drakec9680921999-12-13 16:37:25 +00009706};
9707
Fred Drakec9680921999-12-13 16:37:25 +00009708static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009709conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009710{
9711 return conv_confname(arg, valuep, posix_constants_pathconf,
9712 sizeof(posix_constants_pathconf)
9713 / sizeof(struct constdef));
9714}
9715#endif
9716
Larry Hastings2f936352014-08-05 14:04:04 +10009717
Fred Drakec9680921999-12-13 16:37:25 +00009718#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009719/*[clinic input]
9720os.fpathconf -> long
9721
9722 fd: int
9723 name: path_confname
9724 /
9725
9726Return the configuration limit name for the file descriptor fd.
9727
9728If there is no limit, return -1.
9729[clinic start generated code]*/
9730
Larry Hastings2f936352014-08-05 14:04:04 +10009731static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009732os_fpathconf_impl(PyObject *module, int fd, int name)
9733/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009734{
9735 long limit;
9736
9737 errno = 0;
9738 limit = fpathconf(fd, name);
9739 if (limit == -1 && errno != 0)
9740 posix_error();
9741
9742 return limit;
9743}
9744#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009745
9746
9747#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009748/*[clinic input]
9749os.pathconf -> long
9750 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9751 name: path_confname
9752
9753Return the configuration limit name for the file or directory path.
9754
9755If there is no limit, return -1.
9756On some platforms, path may also be specified as an open file descriptor.
9757 If this functionality is unavailable, using it raises an exception.
9758[clinic start generated code]*/
9759
Larry Hastings2f936352014-08-05 14:04:04 +10009760static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009761os_pathconf_impl(PyObject *module, path_t *path, int name)
9762/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009763{
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009765
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009767#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009768 if (path->fd != -1)
9769 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009770 else
9771#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009772 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 if (limit == -1 && errno != 0) {
9774 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009775 /* could be a path or name problem */
9776 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009777 else
Larry Hastings2f936352014-08-05 14:04:04 +10009778 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 }
Larry Hastings2f936352014-08-05 14:04:04 +10009780
9781 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009782}
Larry Hastings2f936352014-08-05 14:04:04 +10009783#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009784
9785#ifdef HAVE_CONFSTR
9786static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009787#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009789#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009790#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009792#endif
9793#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009795#endif
Fred Draked86ed291999-12-15 15:34:33 +00009796#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009798#endif
9799#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009801#endif
9802#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009804#endif
9805#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009807#endif
Fred Drakec9680921999-12-13 16:37:25 +00009808#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
Fred Draked86ed291999-12-15 15:34:33 +00009832#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009834#endif
Fred Drakec9680921999-12-13 16:37:25 +00009835#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009837#endif
Fred Draked86ed291999-12-15 15:34:33 +00009838#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
9841#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
9844#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009846#endif
9847#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009849#endif
Fred Drakec9680921999-12-13 16:37:25 +00009850#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009852#endif
9853#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009855#endif
9856#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009858#endif
9859#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009861#endif
9862#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009864#endif
9865#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009867#endif
9868#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009870#endif
9871#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009873#endif
9874#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009875 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009876#endif
9877#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009878 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009879#endif
9880#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009881 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009882#endif
9883#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009884 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009885#endif
9886#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009887 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009888#endif
9889#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009890 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009891#endif
9892#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009893 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009894#endif
9895#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009896 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009897#endif
Fred Draked86ed291999-12-15 15:34:33 +00009898#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009899 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009900#endif
9901#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009902 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009903#endif
9904#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009905 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009906#endif
9907#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009909#endif
9910#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009912#endif
9913#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009915#endif
9916#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009918#endif
9919#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009921#endif
9922#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009924#endif
9925#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009927#endif
9928#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009930#endif
9931#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009933#endif
9934#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009936#endif
Fred Drakec9680921999-12-13 16:37:25 +00009937};
9938
9939static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009940conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009941{
9942 return conv_confname(arg, valuep, posix_constants_confstr,
9943 sizeof(posix_constants_confstr)
9944 / sizeof(struct constdef));
9945}
9946
Larry Hastings2f936352014-08-05 14:04:04 +10009947
9948/*[clinic input]
9949os.confstr
9950
9951 name: confstr_confname
9952 /
9953
9954Return a string-valued system configuration variable.
9955[clinic start generated code]*/
9956
Larry Hastings2f936352014-08-05 14:04:04 +10009957static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009958os_confstr_impl(PyObject *module, int name)
9959/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009960{
9961 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009962 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009963 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009964
Victor Stinnercb043522010-09-10 23:49:04 +00009965 errno = 0;
9966 len = confstr(name, buffer, sizeof(buffer));
9967 if (len == 0) {
9968 if (errno) {
9969 posix_error();
9970 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009971 }
9972 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009973 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009974 }
9975 }
Victor Stinnercb043522010-09-10 23:49:04 +00009976
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009977 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009978 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009979 char *buf = PyMem_Malloc(len);
9980 if (buf == NULL)
9981 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009982 len2 = confstr(name, buf, len);
9983 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009984 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009985 PyMem_Free(buf);
9986 }
9987 else
9988 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009989 return result;
9990}
Larry Hastings2f936352014-08-05 14:04:04 +10009991#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009992
9993
9994#ifdef HAVE_SYSCONF
9995static struct constdef posix_constants_sysconf[] = {
9996#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
Fred Draked86ed291999-12-15 15:34:33 +000010026#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +000010028#endif
10029#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +000010031#endif
Fred Drakec9680921999-12-13 16:37:25 +000010032#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
Fred Drakec9680921999-12-13 16:37:25 +000010035#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
Fred Draked86ed291999-12-15 15:34:33 +000010050#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010052#endif
Fred Drakec9680921999-12-13 16:37:25 +000010053#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
Fred Draked86ed291999-12-15 15:34:33 +000010068#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010070#endif
Fred Drakec9680921999-12-13 16:37:25 +000010071#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
10089#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
Fred Draked86ed291999-12-15 15:34:33 +000010140#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010142#endif
Fred Drakec9680921999-12-13 16:37:25 +000010143#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
Fred Draked86ed291999-12-15 15:34:33 +000010152#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010154#endif
Fred Drakec9680921999-12-13 16:37:25 +000010155#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
Fred Draked86ed291999-12-15 15:34:33 +000010158#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010160#endif
10161#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010163#endif
Fred Drakec9680921999-12-13 16:37:25 +000010164#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
Fred Draked86ed291999-12-15 15:34:33 +000010176#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010178#endif
Fred Drakec9680921999-12-13 16:37:25 +000010179#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
Fred Draked86ed291999-12-15 15:34:33 +000010200#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010202#endif
Fred Drakec9680921999-12-13 16:37:25 +000010203#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
Fred Draked86ed291999-12-15 15:34:33 +000010209#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010211#endif
Fred Drakec9680921999-12-13 16:37:25 +000010212#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
Fred Draked86ed291999-12-15 15:34:33 +000010239#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010241#endif
10242#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010244#endif
Fred Drakec9680921999-12-13 16:37:25 +000010245#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
Fred Draked86ed291999-12-15 15:34:33 +000010350#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010352#endif
Fred Drakec9680921999-12-13 16:37:25 +000010353#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010400#endif
10401#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010403#endif
10404#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010406#endif
10407#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010409#endif
10410#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010412#endif
10413#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010415#endif
10416#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010418#endif
10419#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010421#endif
10422#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010424#endif
10425#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010426 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010427#endif
10428#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010429 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010430#endif
10431#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010432 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010433#endif
10434#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010435 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010436#endif
10437#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010438 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010439#endif
10440#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010441 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010442#endif
10443#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010444 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010445#endif
10446#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010448#endif
10449#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010450 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010451#endif
10452#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010453 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010454#endif
10455#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010457#endif
10458#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010459 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010460#endif
10461#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010463#endif
10464#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010466#endif
10467#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010468 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010469#endif
10470#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010471 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010472#endif
10473#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010474 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010475#endif
10476#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010477 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010478#endif
10479#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010481#endif
10482#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010484#endif
10485#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010486 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010487#endif
10488};
10489
10490static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010491conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010492{
10493 return conv_confname(arg, valuep, posix_constants_sysconf,
10494 sizeof(posix_constants_sysconf)
10495 / sizeof(struct constdef));
10496}
10497
Larry Hastings2f936352014-08-05 14:04:04 +100010498
10499/*[clinic input]
10500os.sysconf -> long
10501 name: sysconf_confname
10502 /
10503
10504Return an integer-valued system configuration variable.
10505[clinic start generated code]*/
10506
Larry Hastings2f936352014-08-05 14:04:04 +100010507static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010508os_sysconf_impl(PyObject *module, int name)
10509/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010510{
10511 long value;
10512
10513 errno = 0;
10514 value = sysconf(name);
10515 if (value == -1 && errno != 0)
10516 posix_error();
10517 return value;
10518}
10519#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010520
10521
Fred Drakebec628d1999-12-15 18:31:10 +000010522/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010523 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010524 * the exported dictionaries that are used to publish information about the
10525 * names available on the host platform.
10526 *
10527 * Sorting the table at runtime ensures that the table is properly ordered
10528 * when used, even for platforms we're not able to test on. It also makes
10529 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010530 */
Fred Drakebec628d1999-12-15 18:31:10 +000010531
10532static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010533cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010534{
10535 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010536 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010537 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010538 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010539
10540 return strcmp(c1->name, c2->name);
10541}
10542
10543static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010544setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010545 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010546{
Fred Drakebec628d1999-12-15 18:31:10 +000010547 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010548 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010549
10550 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10551 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010552 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010553 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010554
Barry Warsaw3155db32000-04-13 15:20:40 +000010555 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010556 PyObject *o = PyLong_FromLong(table[i].value);
10557 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10558 Py_XDECREF(o);
10559 Py_DECREF(d);
10560 return -1;
10561 }
10562 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010563 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010564 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010565}
10566
Fred Drakebec628d1999-12-15 18:31:10 +000010567/* Return -1 on failure, 0 on success. */
10568static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010569setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010570{
10571#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010572 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010573 sizeof(posix_constants_pathconf)
10574 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010575 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010576 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010577#endif
10578#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010579 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010580 sizeof(posix_constants_confstr)
10581 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010582 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010583 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010584#endif
10585#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010586 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010587 sizeof(posix_constants_sysconf)
10588 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010589 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010590 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010591#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010592 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010593}
Fred Draked86ed291999-12-15 15:34:33 +000010594
10595
Larry Hastings2f936352014-08-05 14:04:04 +100010596/*[clinic input]
10597os.abort
10598
10599Abort the interpreter immediately.
10600
10601This function 'dumps core' or otherwise fails in the hardest way possible
10602on the hosting operating system. This function never returns.
10603[clinic start generated code]*/
10604
Larry Hastings2f936352014-08-05 14:04:04 +100010605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010606os_abort_impl(PyObject *module)
10607/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010608{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010609 abort();
10610 /*NOTREACHED*/
10611 Py_FatalError("abort() called from Python code didn't abort!");
10612 return NULL;
10613}
Fred Drakebec628d1999-12-15 18:31:10 +000010614
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010615#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010616/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010617PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010618"startfile(filepath [, operation])\n\
10619\n\
10620Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010621\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010622When \"operation\" is not specified or \"open\", this acts like\n\
10623double-clicking the file in Explorer, or giving the file name as an\n\
10624argument to the DOS \"start\" command: the file is opened with whatever\n\
10625application (if any) its extension is associated.\n\
10626When another \"operation\" is given, it specifies what should be done with\n\
10627the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010628\n\
10629startfile returns as soon as the associated application is launched.\n\
10630There is no option to wait for the application to close, and no way\n\
10631to retrieve the application's exit status.\n\
10632\n\
10633The filepath is relative to the current directory. If you want to use\n\
10634an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010635the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010636
Steve Dower7d0e0c92015-01-24 08:18:24 -080010637/* Grab ShellExecute dynamically from shell32 */
10638static int has_ShellExecute = -1;
10639static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10640 LPCSTR, INT);
10641static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10642 LPCWSTR, INT);
10643static int
10644check_ShellExecute()
10645{
10646 HINSTANCE hShell32;
10647
10648 /* only recheck */
10649 if (-1 == has_ShellExecute) {
10650 Py_BEGIN_ALLOW_THREADS
10651 hShell32 = LoadLibraryW(L"SHELL32");
10652 Py_END_ALLOW_THREADS
10653 if (hShell32) {
10654 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10655 "ShellExecuteA");
10656 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10657 "ShellExecuteW");
10658 has_ShellExecute = Py_ShellExecuteA &&
10659 Py_ShellExecuteW;
10660 } else {
10661 has_ShellExecute = 0;
10662 }
10663 }
10664 return has_ShellExecute;
10665}
10666
10667
Tim Petersf58a7aa2000-09-22 10:05:54 +000010668static PyObject *
10669win32_startfile(PyObject *self, PyObject *args)
10670{
Victor Stinner8c62be82010-05-06 00:08:46 +000010671 PyObject *ofilepath;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010672 const char *filepath;
10673 const char *operation = NULL;
10674 const wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010676
Victor Stinnereb5657a2011-09-30 01:44:27 +020010677 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010678
10679 if(!check_ShellExecute()) {
10680 /* If the OS doesn't have ShellExecute, return a
10681 NotImplementedError. */
10682 return PyErr_Format(PyExc_NotImplementedError,
10683 "startfile not available on this platform");
10684 }
10685
Victor Stinner8c62be82010-05-06 00:08:46 +000010686 if (!PyArg_ParseTuple(args, "U|s:startfile",
10687 &unipath, &operation)) {
10688 PyErr_Clear();
10689 goto normal;
10690 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010691
Victor Stinner8c62be82010-05-06 00:08:46 +000010692 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010693 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010694 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010695 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010696 PyErr_Clear();
10697 operation = NULL;
10698 goto normal;
10699 }
10700 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010701
Victor Stinnereb5657a2011-09-30 01:44:27 +020010702 wpath = PyUnicode_AsUnicode(unipath);
10703 if (wpath == NULL)
10704 goto normal;
10705 if (uoperation) {
10706 woperation = PyUnicode_AsUnicode(uoperation);
10707 if (woperation == NULL)
10708 goto normal;
10709 }
10710 else
10711 woperation = NULL;
10712
Victor Stinner8c62be82010-05-06 00:08:46 +000010713 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010714 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10715 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010716 Py_END_ALLOW_THREADS
10717
Victor Stinnereb5657a2011-09-30 01:44:27 +020010718 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010719 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010720 win32_error_object("startfile", unipath);
10721 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 }
10723 Py_INCREF(Py_None);
10724 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010725
10726normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010727 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10728 PyUnicode_FSConverter, &ofilepath,
10729 &operation))
10730 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010731 if (win32_warn_bytes_api()) {
10732 Py_DECREF(ofilepath);
10733 return NULL;
10734 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010735 filepath = PyBytes_AsString(ofilepath);
10736 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010737 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10738 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 Py_END_ALLOW_THREADS
10740 if (rc <= (HINSTANCE)32) {
10741 PyObject *errval = win32_error("startfile", filepath);
10742 Py_DECREF(ofilepath);
10743 return errval;
10744 }
10745 Py_DECREF(ofilepath);
10746 Py_INCREF(Py_None);
10747 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010748}
Larry Hastings2f936352014-08-05 14:04:04 +100010749#endif /* MS_WINDOWS */
10750
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010751
Martin v. Löwis438b5342002-12-27 10:16:42 +000010752#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010753/*[clinic input]
10754os.getloadavg
10755
10756Return average recent system load information.
10757
10758Return the number of processes in the system run queue averaged over
10759the last 1, 5, and 15 minutes as a tuple of three floats.
10760Raises OSError if the load average was unobtainable.
10761[clinic start generated code]*/
10762
Larry Hastings2f936352014-08-05 14:04:04 +100010763static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010764os_getloadavg_impl(PyObject *module)
10765/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010766{
10767 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010768 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010769 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10770 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010771 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010772 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010773}
Larry Hastings2f936352014-08-05 14:04:04 +100010774#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010775
Larry Hastings2f936352014-08-05 14:04:04 +100010776
10777/*[clinic input]
10778os.device_encoding
10779 fd: int
10780
10781Return a string describing the encoding of a terminal's file descriptor.
10782
10783The file descriptor must be attached to a terminal.
10784If the device is not a terminal, return None.
10785[clinic start generated code]*/
10786
Larry Hastings2f936352014-08-05 14:04:04 +100010787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010788os_device_encoding_impl(PyObject *module, int fd)
10789/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010790{
Brett Cannonefb00c02012-02-29 18:31:31 -050010791 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010792}
10793
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010794
Larry Hastings2f936352014-08-05 14:04:04 +100010795#ifdef HAVE_SETRESUID
10796/*[clinic input]
10797os.setresuid
10798
10799 ruid: uid_t
10800 euid: uid_t
10801 suid: uid_t
10802 /
10803
10804Set the current process's real, effective, and saved user ids.
10805[clinic start generated code]*/
10806
Larry Hastings2f936352014-08-05 14:04:04 +100010807static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010808os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10809/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010810{
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 if (setresuid(ruid, euid, suid) < 0)
10812 return posix_error();
10813 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010814}
Larry Hastings2f936352014-08-05 14:04:04 +100010815#endif /* HAVE_SETRESUID */
10816
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010817
10818#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010819/*[clinic input]
10820os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010821
Larry Hastings2f936352014-08-05 14:04:04 +100010822 rgid: gid_t
10823 egid: gid_t
10824 sgid: gid_t
10825 /
10826
10827Set the current process's real, effective, and saved group ids.
10828[clinic start generated code]*/
10829
Larry Hastings2f936352014-08-05 14:04:04 +100010830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010831os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10832/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010833{
Victor Stinner8c62be82010-05-06 00:08:46 +000010834 if (setresgid(rgid, egid, sgid) < 0)
10835 return posix_error();
10836 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010837}
Larry Hastings2f936352014-08-05 14:04:04 +100010838#endif /* HAVE_SETRESGID */
10839
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010840
10841#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010842/*[clinic input]
10843os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010844
Larry Hastings2f936352014-08-05 14:04:04 +100010845Return a tuple of the current process's real, effective, and saved user ids.
10846[clinic start generated code]*/
10847
Larry Hastings2f936352014-08-05 14:04:04 +100010848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010849os_getresuid_impl(PyObject *module)
10850/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010851{
Victor Stinner8c62be82010-05-06 00:08:46 +000010852 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010853 if (getresuid(&ruid, &euid, &suid) < 0)
10854 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010855 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10856 _PyLong_FromUid(euid),
10857 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010858}
Larry Hastings2f936352014-08-05 14:04:04 +100010859#endif /* HAVE_GETRESUID */
10860
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010861
10862#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010863/*[clinic input]
10864os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010865
Larry Hastings2f936352014-08-05 14:04:04 +100010866Return a tuple of the current process's real, effective, and saved group ids.
10867[clinic start generated code]*/
10868
Larry Hastings2f936352014-08-05 14:04:04 +100010869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010870os_getresgid_impl(PyObject *module)
10871/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010872{
10873 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010874 if (getresgid(&rgid, &egid, &sgid) < 0)
10875 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010876 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10877 _PyLong_FromGid(egid),
10878 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010879}
Larry Hastings2f936352014-08-05 14:04:04 +100010880#endif /* HAVE_GETRESGID */
10881
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010882
Benjamin Peterson9428d532011-09-14 11:45:52 -040010883#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010884/*[clinic input]
10885os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010886
Larry Hastings2f936352014-08-05 14:04:04 +100010887 path: path_t(allow_fd=True)
10888 attribute: path_t
10889 *
10890 follow_symlinks: bool = True
10891
10892Return the value of extended attribute attribute on path.
10893
10894path may be either a string or an open file descriptor.
10895If follow_symlinks is False, and the last element of the path is a symbolic
10896 link, getxattr will examine the symbolic link itself instead of the file
10897 the link points to.
10898
10899[clinic start generated code]*/
10900
Larry Hastings2f936352014-08-05 14:04:04 +100010901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010902os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010903 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010904/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010905{
10906 Py_ssize_t i;
10907 PyObject *buffer = NULL;
10908
10909 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10910 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010911
Larry Hastings9cf065c2012-06-22 16:30:09 -070010912 for (i = 0; ; i++) {
10913 void *ptr;
10914 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010915 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010916 Py_ssize_t buffer_size = buffer_sizes[i];
10917 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010918 path_error(path);
10919 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010920 }
10921 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10922 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010923 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010924 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010925
Larry Hastings9cf065c2012-06-22 16:30:09 -070010926 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010927 if (path->fd >= 0)
10928 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010929 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010930 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010931 else
Larry Hastings2f936352014-08-05 14:04:04 +100010932 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010933 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010934
Larry Hastings9cf065c2012-06-22 16:30:09 -070010935 if (result < 0) {
10936 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010937 if (errno == ERANGE)
10938 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010939 path_error(path);
10940 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010941 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010942
Larry Hastings9cf065c2012-06-22 16:30:09 -070010943 if (result != buffer_size) {
10944 /* Can only shrink. */
10945 _PyBytes_Resize(&buffer, result);
10946 }
10947 break;
10948 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010949
Larry Hastings9cf065c2012-06-22 16:30:09 -070010950 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010951}
10952
Larry Hastings2f936352014-08-05 14:04:04 +100010953
10954/*[clinic input]
10955os.setxattr
10956
10957 path: path_t(allow_fd=True)
10958 attribute: path_t
10959 value: Py_buffer
10960 flags: int = 0
10961 *
10962 follow_symlinks: bool = True
10963
10964Set extended attribute attribute on path to value.
10965
10966path may be either a string or an open file descriptor.
10967If follow_symlinks is False, and the last element of the path is a symbolic
10968 link, setxattr will modify the symbolic link itself instead of the file
10969 the link points to.
10970
10971[clinic start generated code]*/
10972
Benjamin Peterson799bd802011-08-31 22:15:17 -040010973static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010974os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010975 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010976/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010977{
Larry Hastings2f936352014-08-05 14:04:04 +100010978 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010979
Larry Hastings2f936352014-08-05 14:04:04 +100010980 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010981 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010982
Benjamin Peterson799bd802011-08-31 22:15:17 -040010983 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010984 if (path->fd > -1)
10985 result = fsetxattr(path->fd, attribute->narrow,
10986 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010988 result = setxattr(path->narrow, attribute->narrow,
10989 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 else
Larry Hastings2f936352014-08-05 14:04:04 +100010991 result = lsetxattr(path->narrow, attribute->narrow,
10992 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010993 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010994
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010996 path_error(path);
10997 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010998 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010999
Larry Hastings2f936352014-08-05 14:04:04 +100011000 Py_RETURN_NONE;
11001}
11002
11003
11004/*[clinic input]
11005os.removexattr
11006
11007 path: path_t(allow_fd=True)
11008 attribute: path_t
11009 *
11010 follow_symlinks: bool = True
11011
11012Remove extended attribute attribute on path.
11013
11014path may be either a string or an open file descriptor.
11015If follow_symlinks is False, and the last element of the path is a symbolic
11016 link, removexattr will modify the symbolic link itself instead of the file
11017 the link points to.
11018
11019[clinic start generated code]*/
11020
Larry Hastings2f936352014-08-05 14:04:04 +100011021static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011022os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040011023 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011024/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011025{
11026 ssize_t result;
11027
11028 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
11029 return NULL;
11030
11031 Py_BEGIN_ALLOW_THREADS;
11032 if (path->fd > -1)
11033 result = fremovexattr(path->fd, attribute->narrow);
11034 else if (follow_symlinks)
11035 result = removexattr(path->narrow, attribute->narrow);
11036 else
11037 result = lremovexattr(path->narrow, attribute->narrow);
11038 Py_END_ALLOW_THREADS;
11039
11040 if (result) {
11041 return path_error(path);
11042 }
11043
11044 Py_RETURN_NONE;
11045}
11046
11047
11048/*[clinic input]
11049os.listxattr
11050
11051 path: path_t(allow_fd=True, nullable=True) = None
11052 *
11053 follow_symlinks: bool = True
11054
11055Return a list of extended attributes on path.
11056
11057path may be either None, a string, or an open file descriptor.
11058if path is None, listxattr will examine the current directory.
11059If follow_symlinks is False, and the last element of the path is a symbolic
11060 link, listxattr will examine the symbolic link itself instead of the file
11061 the link points to.
11062[clinic start generated code]*/
11063
Larry Hastings2f936352014-08-05 14:04:04 +100011064static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011065os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11066/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011067{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011068 Py_ssize_t i;
11069 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011070 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011071 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011072
Larry Hastings2f936352014-08-05 14:04:04 +100011073 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011074 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011075
Larry Hastings2f936352014-08-05 14:04:04 +100011076 name = path->narrow ? path->narrow : ".";
11077
Larry Hastings9cf065c2012-06-22 16:30:09 -070011078 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011079 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011080 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011081 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011082 Py_ssize_t buffer_size = buffer_sizes[i];
11083 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011084 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011085 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011086 break;
11087 }
11088 buffer = PyMem_MALLOC(buffer_size);
11089 if (!buffer) {
11090 PyErr_NoMemory();
11091 break;
11092 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011093
Larry Hastings9cf065c2012-06-22 16:30:09 -070011094 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011095 if (path->fd > -1)
11096 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011097 else if (follow_symlinks)
11098 length = listxattr(name, buffer, buffer_size);
11099 else
11100 length = llistxattr(name, buffer, buffer_size);
11101 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011102
Larry Hastings9cf065c2012-06-22 16:30:09 -070011103 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011104 if (errno == ERANGE) {
11105 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011106 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011107 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011108 }
Larry Hastings2f936352014-08-05 14:04:04 +100011109 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011110 break;
11111 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011112
Larry Hastings9cf065c2012-06-22 16:30:09 -070011113 result = PyList_New(0);
11114 if (!result) {
11115 goto exit;
11116 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011117
Larry Hastings9cf065c2012-06-22 16:30:09 -070011118 end = buffer + length;
11119 for (trace = start = buffer; trace != end; trace++) {
11120 if (!*trace) {
11121 int error;
11122 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11123 trace - start);
11124 if (!attribute) {
11125 Py_DECREF(result);
11126 result = NULL;
11127 goto exit;
11128 }
11129 error = PyList_Append(result, attribute);
11130 Py_DECREF(attribute);
11131 if (error) {
11132 Py_DECREF(result);
11133 result = NULL;
11134 goto exit;
11135 }
11136 start = trace + 1;
11137 }
11138 }
11139 break;
11140 }
11141exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011142 if (buffer)
11143 PyMem_FREE(buffer);
11144 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011145}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011146#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011147
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011148
Larry Hastings2f936352014-08-05 14:04:04 +100011149/*[clinic input]
11150os.urandom
11151
11152 size: Py_ssize_t
11153 /
11154
11155Return a bytes object containing random bytes suitable for cryptographic use.
11156[clinic start generated code]*/
11157
Larry Hastings2f936352014-08-05 14:04:04 +100011158static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011159os_urandom_impl(PyObject *module, Py_ssize_t size)
11160/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011161{
11162 PyObject *bytes;
11163 int result;
11164
Georg Brandl2fb477c2012-02-21 00:33:36 +010011165 if (size < 0)
11166 return PyErr_Format(PyExc_ValueError,
11167 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011168 bytes = PyBytes_FromStringAndSize(NULL, size);
11169 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011170 return NULL;
11171
Larry Hastings2f936352014-08-05 14:04:04 +100011172 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11173 PyBytes_GET_SIZE(bytes));
11174 if (result == -1) {
11175 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011176 return NULL;
11177 }
Larry Hastings2f936352014-08-05 14:04:04 +100011178 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011179}
11180
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011181/* Terminal size querying */
11182
11183static PyTypeObject TerminalSizeType;
11184
11185PyDoc_STRVAR(TerminalSize_docstring,
11186 "A tuple of (columns, lines) for holding terminal window size");
11187
11188static PyStructSequence_Field TerminalSize_fields[] = {
11189 {"columns", "width of the terminal window in characters"},
11190 {"lines", "height of the terminal window in characters"},
11191 {NULL, NULL}
11192};
11193
11194static PyStructSequence_Desc TerminalSize_desc = {
11195 "os.terminal_size",
11196 TerminalSize_docstring,
11197 TerminalSize_fields,
11198 2,
11199};
11200
11201#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011202/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011203PyDoc_STRVAR(termsize__doc__,
11204 "Return the size of the terminal window as (columns, lines).\n" \
11205 "\n" \
11206 "The optional argument fd (default standard output) specifies\n" \
11207 "which file descriptor should be queried.\n" \
11208 "\n" \
11209 "If the file descriptor is not connected to a terminal, an OSError\n" \
11210 "is thrown.\n" \
11211 "\n" \
11212 "This function will only be defined if an implementation is\n" \
11213 "available for this system.\n" \
11214 "\n" \
11215 "shutil.get_terminal_size is the high-level function which should \n" \
11216 "normally be used, os.get_terminal_size is the low-level implementation.");
11217
11218static PyObject*
11219get_terminal_size(PyObject *self, PyObject *args)
11220{
11221 int columns, lines;
11222 PyObject *termsize;
11223
11224 int fd = fileno(stdout);
11225 /* Under some conditions stdout may not be connected and
11226 * fileno(stdout) may point to an invalid file descriptor. For example
11227 * GUI apps don't have valid standard streams by default.
11228 *
11229 * If this happens, and the optional fd argument is not present,
11230 * the ioctl below will fail returning EBADF. This is what we want.
11231 */
11232
11233 if (!PyArg_ParseTuple(args, "|i", &fd))
11234 return NULL;
11235
11236#ifdef TERMSIZE_USE_IOCTL
11237 {
11238 struct winsize w;
11239 if (ioctl(fd, TIOCGWINSZ, &w))
11240 return PyErr_SetFromErrno(PyExc_OSError);
11241 columns = w.ws_col;
11242 lines = w.ws_row;
11243 }
11244#endif /* TERMSIZE_USE_IOCTL */
11245
11246#ifdef TERMSIZE_USE_CONIO
11247 {
11248 DWORD nhandle;
11249 HANDLE handle;
11250 CONSOLE_SCREEN_BUFFER_INFO csbi;
11251 switch (fd) {
11252 case 0: nhandle = STD_INPUT_HANDLE;
11253 break;
11254 case 1: nhandle = STD_OUTPUT_HANDLE;
11255 break;
11256 case 2: nhandle = STD_ERROR_HANDLE;
11257 break;
11258 default:
11259 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11260 }
11261 handle = GetStdHandle(nhandle);
11262 if (handle == NULL)
11263 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11264 if (handle == INVALID_HANDLE_VALUE)
11265 return PyErr_SetFromWindowsErr(0);
11266
11267 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11268 return PyErr_SetFromWindowsErr(0);
11269
11270 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11271 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11272 }
11273#endif /* TERMSIZE_USE_CONIO */
11274
11275 termsize = PyStructSequence_New(&TerminalSizeType);
11276 if (termsize == NULL)
11277 return NULL;
11278 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11279 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11280 if (PyErr_Occurred()) {
11281 Py_DECREF(termsize);
11282 return NULL;
11283 }
11284 return termsize;
11285}
11286#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11287
Larry Hastings2f936352014-08-05 14:04:04 +100011288
11289/*[clinic input]
11290os.cpu_count
11291
Charles-François Natali80d62e62015-08-13 20:37:08 +010011292Return the number of CPUs in the system; return None if indeterminable.
11293
11294This number is not equivalent to the number of CPUs the current process can
11295use. The number of usable CPUs can be obtained with
11296``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011297[clinic start generated code]*/
11298
Larry Hastings2f936352014-08-05 14:04:04 +100011299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011300os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011301/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011302{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011303 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011304#ifdef MS_WINDOWS
11305 SYSTEM_INFO sysinfo;
11306 GetSystemInfo(&sysinfo);
11307 ncpu = sysinfo.dwNumberOfProcessors;
11308#elif defined(__hpux)
11309 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11310#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11311 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011312#elif defined(__DragonFly__) || \
11313 defined(__OpenBSD__) || \
11314 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011315 defined(__NetBSD__) || \
11316 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011317 int mib[2];
11318 size_t len = sizeof(ncpu);
11319 mib[0] = CTL_HW;
11320 mib[1] = HW_NCPU;
11321 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11322 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011323#endif
11324 if (ncpu >= 1)
11325 return PyLong_FromLong(ncpu);
11326 else
11327 Py_RETURN_NONE;
11328}
11329
Victor Stinnerdaf45552013-08-28 00:53:59 +020011330
Larry Hastings2f936352014-08-05 14:04:04 +100011331/*[clinic input]
11332os.get_inheritable -> bool
11333
11334 fd: int
11335 /
11336
11337Get the close-on-exe flag of the specified file descriptor.
11338[clinic start generated code]*/
11339
Larry Hastings2f936352014-08-05 14:04:04 +100011340static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011341os_get_inheritable_impl(PyObject *module, int fd)
11342/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011343{
Steve Dower8fc89802015-04-12 00:26:27 -040011344 int return_value;
11345 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011346 posix_error();
11347 return -1;
11348 }
11349
Steve Dower8fc89802015-04-12 00:26:27 -040011350 _Py_BEGIN_SUPPRESS_IPH
11351 return_value = _Py_get_inheritable(fd);
11352 _Py_END_SUPPRESS_IPH
11353 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011354}
11355
11356
11357/*[clinic input]
11358os.set_inheritable
11359 fd: int
11360 inheritable: int
11361 /
11362
11363Set the inheritable flag of the specified file descriptor.
11364[clinic start generated code]*/
11365
Larry Hastings2f936352014-08-05 14:04:04 +100011366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011367os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11368/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011369{
Steve Dower8fc89802015-04-12 00:26:27 -040011370 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011371 if (!_PyVerify_fd(fd))
11372 return posix_error();
11373
Steve Dower8fc89802015-04-12 00:26:27 -040011374 _Py_BEGIN_SUPPRESS_IPH
11375 result = _Py_set_inheritable(fd, inheritable, NULL);
11376 _Py_END_SUPPRESS_IPH
11377 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011378 return NULL;
11379 Py_RETURN_NONE;
11380}
11381
11382
11383#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011384/*[clinic input]
11385os.get_handle_inheritable -> bool
11386 handle: Py_intptr_t
11387 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011388
Larry Hastings2f936352014-08-05 14:04:04 +100011389Get the close-on-exe flag of the specified file descriptor.
11390[clinic start generated code]*/
11391
Larry Hastings2f936352014-08-05 14:04:04 +100011392static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011393os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11394/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011395{
11396 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011397
11398 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11399 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011400 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011401 }
11402
Larry Hastings2f936352014-08-05 14:04:04 +100011403 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011404}
11405
Victor Stinnerdaf45552013-08-28 00:53:59 +020011406
Larry Hastings2f936352014-08-05 14:04:04 +100011407/*[clinic input]
11408os.set_handle_inheritable
11409 handle: Py_intptr_t
11410 inheritable: bool
11411 /
11412
11413Set the inheritable flag of the specified handle.
11414[clinic start generated code]*/
11415
Larry Hastings2f936352014-08-05 14:04:04 +100011416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011417os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011418 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011419/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011420{
11421 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011422 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11423 PyErr_SetFromWindowsErr(0);
11424 return NULL;
11425 }
11426 Py_RETURN_NONE;
11427}
Larry Hastings2f936352014-08-05 14:04:04 +100011428#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011429
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011430#ifndef MS_WINDOWS
11431PyDoc_STRVAR(get_blocking__doc__,
11432 "get_blocking(fd) -> bool\n" \
11433 "\n" \
11434 "Get the blocking mode of the file descriptor:\n" \
11435 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11436
11437static PyObject*
11438posix_get_blocking(PyObject *self, PyObject *args)
11439{
11440 int fd;
11441 int blocking;
11442
11443 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11444 return NULL;
11445
11446 if (!_PyVerify_fd(fd))
11447 return posix_error();
11448
Steve Dower8fc89802015-04-12 00:26:27 -040011449 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011450 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011451 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011452 if (blocking < 0)
11453 return NULL;
11454 return PyBool_FromLong(blocking);
11455}
11456
11457PyDoc_STRVAR(set_blocking__doc__,
11458 "set_blocking(fd, blocking)\n" \
11459 "\n" \
11460 "Set the blocking mode of the specified file descriptor.\n" \
11461 "Set the O_NONBLOCK flag if blocking is False,\n" \
11462 "clear the O_NONBLOCK flag otherwise.");
11463
11464static PyObject*
11465posix_set_blocking(PyObject *self, PyObject *args)
11466{
Steve Dower8fc89802015-04-12 00:26:27 -040011467 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011468
11469 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11470 return NULL;
11471
11472 if (!_PyVerify_fd(fd))
11473 return posix_error();
11474
Steve Dower8fc89802015-04-12 00:26:27 -040011475 _Py_BEGIN_SUPPRESS_IPH
11476 result = _Py_set_blocking(fd, blocking);
11477 _Py_END_SUPPRESS_IPH
11478 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011479 return NULL;
11480 Py_RETURN_NONE;
11481}
11482#endif /* !MS_WINDOWS */
11483
11484
Victor Stinner6036e442015-03-08 01:58:04 +010011485PyDoc_STRVAR(posix_scandir__doc__,
11486"scandir(path='.') -> iterator of DirEntry objects for given path");
11487
11488static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11489
11490typedef struct {
11491 PyObject_HEAD
11492 PyObject *name;
11493 PyObject *path;
11494 PyObject *stat;
11495 PyObject *lstat;
11496#ifdef MS_WINDOWS
11497 struct _Py_stat_struct win32_lstat;
11498 __int64 win32_file_index;
11499 int got_file_index;
11500#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011501#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011502 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011503#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011504 ino_t d_ino;
11505#endif
11506} DirEntry;
11507
11508static void
11509DirEntry_dealloc(DirEntry *entry)
11510{
11511 Py_XDECREF(entry->name);
11512 Py_XDECREF(entry->path);
11513 Py_XDECREF(entry->stat);
11514 Py_XDECREF(entry->lstat);
11515 Py_TYPE(entry)->tp_free((PyObject *)entry);
11516}
11517
11518/* Forward reference */
11519static int
11520DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11521
11522/* Set exception and return -1 on error, 0 for False, 1 for True */
11523static int
11524DirEntry_is_symlink(DirEntry *self)
11525{
11526#ifdef MS_WINDOWS
11527 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011528#elif defined(HAVE_DIRENT_D_TYPE)
11529 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011530 if (self->d_type != DT_UNKNOWN)
11531 return self->d_type == DT_LNK;
11532 else
11533 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011534#else
11535 /* POSIX without d_type */
11536 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011537#endif
11538}
11539
11540static PyObject *
11541DirEntry_py_is_symlink(DirEntry *self)
11542{
11543 int result;
11544
11545 result = DirEntry_is_symlink(self);
11546 if (result == -1)
11547 return NULL;
11548 return PyBool_FromLong(result);
11549}
11550
11551static PyObject *
11552DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11553{
11554 int result;
11555 struct _Py_stat_struct st;
11556
11557#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011558 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011559
11560 path = PyUnicode_AsUnicode(self->path);
11561 if (!path)
11562 return NULL;
11563
11564 if (follow_symlinks)
11565 result = win32_stat_w(path, &st);
11566 else
11567 result = win32_lstat_w(path, &st);
11568
11569 if (result != 0) {
11570 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11571 0, self->path);
11572 }
11573#else /* POSIX */
11574 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011575 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011576
11577 if (!PyUnicode_FSConverter(self->path, &bytes))
11578 return NULL;
11579 path = PyBytes_AS_STRING(bytes);
11580
11581 if (follow_symlinks)
11582 result = STAT(path, &st);
11583 else
11584 result = LSTAT(path, &st);
11585 Py_DECREF(bytes);
11586
11587 if (result != 0)
11588 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11589#endif
11590
11591 return _pystat_fromstructstat(&st);
11592}
11593
11594static PyObject *
11595DirEntry_get_lstat(DirEntry *self)
11596{
11597 if (!self->lstat) {
11598#ifdef MS_WINDOWS
11599 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11600#else /* POSIX */
11601 self->lstat = DirEntry_fetch_stat(self, 0);
11602#endif
11603 }
11604 Py_XINCREF(self->lstat);
11605 return self->lstat;
11606}
11607
11608static PyObject *
11609DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11610{
11611 if (!follow_symlinks)
11612 return DirEntry_get_lstat(self);
11613
11614 if (!self->stat) {
11615 int result = DirEntry_is_symlink(self);
11616 if (result == -1)
11617 return NULL;
11618 else if (result)
11619 self->stat = DirEntry_fetch_stat(self, 1);
11620 else
11621 self->stat = DirEntry_get_lstat(self);
11622 }
11623
11624 Py_XINCREF(self->stat);
11625 return self->stat;
11626}
11627
11628static PyObject *
11629DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11630{
11631 int follow_symlinks = 1;
11632
11633 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11634 follow_symlinks_keywords, &follow_symlinks))
11635 return NULL;
11636
11637 return DirEntry_get_stat(self, follow_symlinks);
11638}
11639
11640/* Set exception and return -1 on error, 0 for False, 1 for True */
11641static int
11642DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11643{
11644 PyObject *stat = NULL;
11645 PyObject *st_mode = NULL;
11646 long mode;
11647 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011648#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011649 int is_symlink;
11650 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011651#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011652#ifdef MS_WINDOWS
11653 unsigned long dir_bits;
11654#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011655 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011656
11657#ifdef MS_WINDOWS
11658 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11659 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011660#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011661 is_symlink = self->d_type == DT_LNK;
11662 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11663#endif
11664
Victor Stinner35a97c02015-03-08 02:59:09 +010011665#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011666 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011667#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011668 stat = DirEntry_get_stat(self, follow_symlinks);
11669 if (!stat) {
11670 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11671 /* If file doesn't exist (anymore), then return False
11672 (i.e., say it's not a file/directory) */
11673 PyErr_Clear();
11674 return 0;
11675 }
11676 goto error;
11677 }
11678 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11679 if (!st_mode)
11680 goto error;
11681
11682 mode = PyLong_AsLong(st_mode);
11683 if (mode == -1 && PyErr_Occurred())
11684 goto error;
11685 Py_CLEAR(st_mode);
11686 Py_CLEAR(stat);
11687 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011688#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011689 }
11690 else if (is_symlink) {
11691 assert(mode_bits != S_IFLNK);
11692 result = 0;
11693 }
11694 else {
11695 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11696#ifdef MS_WINDOWS
11697 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11698 if (mode_bits == S_IFDIR)
11699 result = dir_bits != 0;
11700 else
11701 result = dir_bits == 0;
11702#else /* POSIX */
11703 if (mode_bits == S_IFDIR)
11704 result = self->d_type == DT_DIR;
11705 else
11706 result = self->d_type == DT_REG;
11707#endif
11708 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011709#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011710
11711 return result;
11712
11713error:
11714 Py_XDECREF(st_mode);
11715 Py_XDECREF(stat);
11716 return -1;
11717}
11718
11719static PyObject *
11720DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11721{
11722 int result;
11723
11724 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11725 if (result == -1)
11726 return NULL;
11727 return PyBool_FromLong(result);
11728}
11729
11730static PyObject *
11731DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11732{
11733 int follow_symlinks = 1;
11734
11735 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11736 follow_symlinks_keywords, &follow_symlinks))
11737 return NULL;
11738
11739 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11740}
11741
11742static PyObject *
11743DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11744{
11745 int follow_symlinks = 1;
11746
11747 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11748 follow_symlinks_keywords, &follow_symlinks))
11749 return NULL;
11750
11751 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11752}
11753
11754static PyObject *
11755DirEntry_inode(DirEntry *self)
11756{
11757#ifdef MS_WINDOWS
11758 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011759 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011760 struct _Py_stat_struct stat;
11761
11762 path = PyUnicode_AsUnicode(self->path);
11763 if (!path)
11764 return NULL;
11765
11766 if (win32_lstat_w(path, &stat) != 0) {
11767 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11768 0, self->path);
11769 }
11770
11771 self->win32_file_index = stat.st_ino;
11772 self->got_file_index = 1;
11773 }
11774 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11775#else /* POSIX */
11776#ifdef HAVE_LARGEFILE_SUPPORT
11777 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11778#else
11779 return PyLong_FromLong((long)self->d_ino);
11780#endif
11781#endif
11782}
11783
11784static PyObject *
11785DirEntry_repr(DirEntry *self)
11786{
11787 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11788}
11789
Brett Cannon96881cd2016-06-10 14:37:21 -070011790static PyObject *
11791DirEntry_fspath(DirEntry *self)
11792{
11793 Py_INCREF(self->path);
11794 return self->path;
11795}
11796
Victor Stinner6036e442015-03-08 01:58:04 +010011797static PyMemberDef DirEntry_members[] = {
11798 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11799 "the entry's base filename, relative to scandir() \"path\" argument"},
11800 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11801 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11802 {NULL}
11803};
11804
11805static PyMethodDef DirEntry_methods[] = {
11806 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11807 "return True if the entry is a directory; cached per entry"
11808 },
11809 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11810 "return True if the entry is a file; cached per entry"
11811 },
11812 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11813 "return True if the entry is a symbolic link; cached per entry"
11814 },
11815 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11816 "return stat_result object for the entry; cached per entry"
11817 },
11818 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11819 "return inode of the entry; cached per entry",
11820 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011821 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11822 "returns the path for the entry",
11823 },
Victor Stinner6036e442015-03-08 01:58:04 +010011824 {NULL}
11825};
11826
Benjamin Peterson5646de42015-04-12 17:56:34 -040011827static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011828 PyVarObject_HEAD_INIT(NULL, 0)
11829 MODNAME ".DirEntry", /* tp_name */
11830 sizeof(DirEntry), /* tp_basicsize */
11831 0, /* tp_itemsize */
11832 /* methods */
11833 (destructor)DirEntry_dealloc, /* tp_dealloc */
11834 0, /* tp_print */
11835 0, /* tp_getattr */
11836 0, /* tp_setattr */
11837 0, /* tp_compare */
11838 (reprfunc)DirEntry_repr, /* tp_repr */
11839 0, /* tp_as_number */
11840 0, /* tp_as_sequence */
11841 0, /* tp_as_mapping */
11842 0, /* tp_hash */
11843 0, /* tp_call */
11844 0, /* tp_str */
11845 0, /* tp_getattro */
11846 0, /* tp_setattro */
11847 0, /* tp_as_buffer */
11848 Py_TPFLAGS_DEFAULT, /* tp_flags */
11849 0, /* tp_doc */
11850 0, /* tp_traverse */
11851 0, /* tp_clear */
11852 0, /* tp_richcompare */
11853 0, /* tp_weaklistoffset */
11854 0, /* tp_iter */
11855 0, /* tp_iternext */
11856 DirEntry_methods, /* tp_methods */
11857 DirEntry_members, /* tp_members */
11858};
11859
11860#ifdef MS_WINDOWS
11861
11862static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011863join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011864{
11865 Py_ssize_t path_len;
11866 Py_ssize_t size;
11867 wchar_t *result;
11868 wchar_t ch;
11869
11870 if (!path_wide) { /* Default arg: "." */
11871 path_wide = L".";
11872 path_len = 1;
11873 }
11874 else {
11875 path_len = wcslen(path_wide);
11876 }
11877
11878 /* The +1's are for the path separator and the NUL */
11879 size = path_len + 1 + wcslen(filename) + 1;
11880 result = PyMem_New(wchar_t, size);
11881 if (!result) {
11882 PyErr_NoMemory();
11883 return NULL;
11884 }
11885 wcscpy(result, path_wide);
11886 if (path_len > 0) {
11887 ch = result[path_len - 1];
11888 if (ch != SEP && ch != ALTSEP && ch != L':')
11889 result[path_len++] = SEP;
11890 wcscpy(result + path_len, filename);
11891 }
11892 return result;
11893}
11894
11895static PyObject *
11896DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11897{
11898 DirEntry *entry;
11899 BY_HANDLE_FILE_INFORMATION file_info;
11900 ULONG reparse_tag;
11901 wchar_t *joined_path;
11902
11903 entry = PyObject_New(DirEntry, &DirEntryType);
11904 if (!entry)
11905 return NULL;
11906 entry->name = NULL;
11907 entry->path = NULL;
11908 entry->stat = NULL;
11909 entry->lstat = NULL;
11910 entry->got_file_index = 0;
11911
11912 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11913 if (!entry->name)
11914 goto error;
11915
11916 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11917 if (!joined_path)
11918 goto error;
11919
11920 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11921 PyMem_Free(joined_path);
11922 if (!entry->path)
11923 goto error;
11924
11925 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11926 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11927
11928 return (PyObject *)entry;
11929
11930error:
11931 Py_DECREF(entry);
11932 return NULL;
11933}
11934
11935#else /* POSIX */
11936
11937static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011938join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011939{
11940 Py_ssize_t path_len;
11941 Py_ssize_t size;
11942 char *result;
11943
11944 if (!path_narrow) { /* Default arg: "." */
11945 path_narrow = ".";
11946 path_len = 1;
11947 }
11948 else {
11949 path_len = strlen(path_narrow);
11950 }
11951
11952 if (filename_len == -1)
11953 filename_len = strlen(filename);
11954
11955 /* The +1's are for the path separator and the NUL */
11956 size = path_len + 1 + filename_len + 1;
11957 result = PyMem_New(char, size);
11958 if (!result) {
11959 PyErr_NoMemory();
11960 return NULL;
11961 }
11962 strcpy(result, path_narrow);
11963 if (path_len > 0 && result[path_len - 1] != '/')
11964 result[path_len++] = '/';
11965 strcpy(result + path_len, filename);
11966 return result;
11967}
11968
11969static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011970DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011971 ino_t d_ino
11972#ifdef HAVE_DIRENT_D_TYPE
11973 , unsigned char d_type
11974#endif
11975 )
Victor Stinner6036e442015-03-08 01:58:04 +010011976{
11977 DirEntry *entry;
11978 char *joined_path;
11979
11980 entry = PyObject_New(DirEntry, &DirEntryType);
11981 if (!entry)
11982 return NULL;
11983 entry->name = NULL;
11984 entry->path = NULL;
11985 entry->stat = NULL;
11986 entry->lstat = NULL;
11987
11988 joined_path = join_path_filename(path->narrow, name, name_len);
11989 if (!joined_path)
11990 goto error;
11991
11992 if (!path->narrow || !PyBytes_Check(path->object)) {
11993 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11994 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11995 }
11996 else {
11997 entry->name = PyBytes_FromStringAndSize(name, name_len);
11998 entry->path = PyBytes_FromString(joined_path);
11999 }
12000 PyMem_Free(joined_path);
12001 if (!entry->name || !entry->path)
12002 goto error;
12003
Victor Stinner35a97c02015-03-08 02:59:09 +010012004#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010012005 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010012006#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012007 entry->d_ino = d_ino;
12008
12009 return (PyObject *)entry;
12010
12011error:
12012 Py_XDECREF(entry);
12013 return NULL;
12014}
12015
12016#endif
12017
12018
12019typedef struct {
12020 PyObject_HEAD
12021 path_t path;
12022#ifdef MS_WINDOWS
12023 HANDLE handle;
12024 WIN32_FIND_DATAW file_data;
12025 int first_time;
12026#else /* POSIX */
12027 DIR *dirp;
12028#endif
12029} ScandirIterator;
12030
12031#ifdef MS_WINDOWS
12032
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012033static int
12034ScandirIterator_is_closed(ScandirIterator *iterator)
12035{
12036 return iterator->handle == INVALID_HANDLE_VALUE;
12037}
12038
Victor Stinner6036e442015-03-08 01:58:04 +010012039static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012040ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012041{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012042 HANDLE handle = iterator->handle;
12043
12044 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012045 return;
12046
Victor Stinner6036e442015-03-08 01:58:04 +010012047 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012048 Py_BEGIN_ALLOW_THREADS
12049 FindClose(handle);
12050 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012051}
12052
12053static PyObject *
12054ScandirIterator_iternext(ScandirIterator *iterator)
12055{
12056 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12057 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012058 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012059
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012060 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012061 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012062 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012063
12064 while (1) {
12065 if (!iterator->first_time) {
12066 Py_BEGIN_ALLOW_THREADS
12067 success = FindNextFileW(iterator->handle, file_data);
12068 Py_END_ALLOW_THREADS
12069 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012070 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012071 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012072 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012073 break;
12074 }
12075 }
12076 iterator->first_time = 0;
12077
12078 /* Skip over . and .. */
12079 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012080 wcscmp(file_data->cFileName, L"..") != 0) {
12081 entry = DirEntry_from_find_data(&iterator->path, file_data);
12082 if (!entry)
12083 break;
12084 return entry;
12085 }
Victor Stinner6036e442015-03-08 01:58:04 +010012086
12087 /* Loop till we get a non-dot directory or finish iterating */
12088 }
12089
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012090 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012091 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012092 return NULL;
12093}
12094
12095#else /* POSIX */
12096
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012097static int
12098ScandirIterator_is_closed(ScandirIterator *iterator)
12099{
12100 return !iterator->dirp;
12101}
12102
Victor Stinner6036e442015-03-08 01:58:04 +010012103static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012104ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012105{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012106 DIR *dirp = iterator->dirp;
12107
12108 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012109 return;
12110
Victor Stinner6036e442015-03-08 01:58:04 +010012111 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012112 Py_BEGIN_ALLOW_THREADS
12113 closedir(dirp);
12114 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012115 return;
12116}
12117
12118static PyObject *
12119ScandirIterator_iternext(ScandirIterator *iterator)
12120{
12121 struct dirent *direntp;
12122 Py_ssize_t name_len;
12123 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012124 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012125
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012126 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012127 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012128 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012129
12130 while (1) {
12131 errno = 0;
12132 Py_BEGIN_ALLOW_THREADS
12133 direntp = readdir(iterator->dirp);
12134 Py_END_ALLOW_THREADS
12135
12136 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012137 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012138 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012139 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012140 break;
12141 }
12142
12143 /* Skip over . and .. */
12144 name_len = NAMLEN(direntp);
12145 is_dot = direntp->d_name[0] == '.' &&
12146 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12147 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012148 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012149 name_len, direntp->d_ino
12150#ifdef HAVE_DIRENT_D_TYPE
12151 , direntp->d_type
12152#endif
12153 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012154 if (!entry)
12155 break;
12156 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012157 }
12158
12159 /* Loop till we get a non-dot directory or finish iterating */
12160 }
12161
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012162 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012163 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012164 return NULL;
12165}
12166
12167#endif
12168
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012169static PyObject *
12170ScandirIterator_close(ScandirIterator *self, PyObject *args)
12171{
12172 ScandirIterator_closedir(self);
12173 Py_RETURN_NONE;
12174}
12175
12176static PyObject *
12177ScandirIterator_enter(PyObject *self, PyObject *args)
12178{
12179 Py_INCREF(self);
12180 return self;
12181}
12182
12183static PyObject *
12184ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12185{
12186 ScandirIterator_closedir(self);
12187 Py_RETURN_NONE;
12188}
12189
Victor Stinner6036e442015-03-08 01:58:04 +010012190static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012191ScandirIterator_finalize(ScandirIterator *iterator)
12192{
12193 PyObject *error_type, *error_value, *error_traceback;
12194
12195 /* Save the current exception, if any. */
12196 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12197
12198 if (!ScandirIterator_is_closed(iterator)) {
12199 ScandirIterator_closedir(iterator);
12200
12201 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12202 "unclosed scandir iterator %R", iterator)) {
12203 /* Spurious errors can appear at shutdown */
12204 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12205 PyErr_WriteUnraisable((PyObject *) iterator);
12206 }
12207 }
12208 }
12209
12210 Py_CLEAR(iterator->path.object);
12211 path_cleanup(&iterator->path);
12212
12213 /* Restore the saved exception. */
12214 PyErr_Restore(error_type, error_value, error_traceback);
12215}
12216
12217static void
Victor Stinner6036e442015-03-08 01:58:04 +010012218ScandirIterator_dealloc(ScandirIterator *iterator)
12219{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012220 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12221 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012222
Victor Stinner6036e442015-03-08 01:58:04 +010012223 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12224}
12225
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012226static PyMethodDef ScandirIterator_methods[] = {
12227 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12228 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12229 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12230 {NULL}
12231};
12232
Benjamin Peterson5646de42015-04-12 17:56:34 -040012233static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012234 PyVarObject_HEAD_INIT(NULL, 0)
12235 MODNAME ".ScandirIterator", /* tp_name */
12236 sizeof(ScandirIterator), /* tp_basicsize */
12237 0, /* tp_itemsize */
12238 /* methods */
12239 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12240 0, /* tp_print */
12241 0, /* tp_getattr */
12242 0, /* tp_setattr */
12243 0, /* tp_compare */
12244 0, /* tp_repr */
12245 0, /* tp_as_number */
12246 0, /* tp_as_sequence */
12247 0, /* tp_as_mapping */
12248 0, /* tp_hash */
12249 0, /* tp_call */
12250 0, /* tp_str */
12251 0, /* tp_getattro */
12252 0, /* tp_setattro */
12253 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012254 Py_TPFLAGS_DEFAULT
12255 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012256 0, /* tp_doc */
12257 0, /* tp_traverse */
12258 0, /* tp_clear */
12259 0, /* tp_richcompare */
12260 0, /* tp_weaklistoffset */
12261 PyObject_SelfIter, /* tp_iter */
12262 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012263 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012264 0, /* tp_members */
12265 0, /* tp_getset */
12266 0, /* tp_base */
12267 0, /* tp_dict */
12268 0, /* tp_descr_get */
12269 0, /* tp_descr_set */
12270 0, /* tp_dictoffset */
12271 0, /* tp_init */
12272 0, /* tp_alloc */
12273 0, /* tp_new */
12274 0, /* tp_free */
12275 0, /* tp_is_gc */
12276 0, /* tp_bases */
12277 0, /* tp_mro */
12278 0, /* tp_cache */
12279 0, /* tp_subclasses */
12280 0, /* tp_weaklist */
12281 0, /* tp_del */
12282 0, /* tp_version_tag */
12283 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012284};
12285
12286static PyObject *
12287posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12288{
12289 ScandirIterator *iterator;
12290 static char *keywords[] = {"path", NULL};
12291#ifdef MS_WINDOWS
12292 wchar_t *path_strW;
12293#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012294 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010012295#endif
12296
12297 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12298 if (!iterator)
12299 return NULL;
12300 memset(&iterator->path, 0, sizeof(path_t));
12301 iterator->path.function_name = "scandir";
12302 iterator->path.nullable = 1;
12303
12304#ifdef MS_WINDOWS
12305 iterator->handle = INVALID_HANDLE_VALUE;
12306#else
12307 iterator->dirp = NULL;
12308#endif
12309
12310 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12311 path_converter, &iterator->path))
12312 goto error;
12313
12314 /* path_converter doesn't keep path.object around, so do it
12315 manually for the lifetime of the iterator here (the refcount
12316 is decremented in ScandirIterator_dealloc)
12317 */
12318 Py_XINCREF(iterator->path.object);
12319
12320#ifdef MS_WINDOWS
12321 if (iterator->path.narrow) {
12322 PyErr_SetString(PyExc_TypeError,
12323 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12324 goto error;
12325 }
12326 iterator->first_time = 1;
12327
12328 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12329 if (!path_strW)
12330 goto error;
12331
12332 Py_BEGIN_ALLOW_THREADS
12333 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12334 Py_END_ALLOW_THREADS
12335
12336 PyMem_Free(path_strW);
12337
12338 if (iterator->handle == INVALID_HANDLE_VALUE) {
12339 path_error(&iterator->path);
12340 goto error;
12341 }
12342#else /* POSIX */
12343 if (iterator->path.narrow)
12344 path = iterator->path.narrow;
12345 else
12346 path = ".";
12347
12348 errno = 0;
12349 Py_BEGIN_ALLOW_THREADS
12350 iterator->dirp = opendir(path);
12351 Py_END_ALLOW_THREADS
12352
12353 if (!iterator->dirp) {
12354 path_error(&iterator->path);
12355 goto error;
12356 }
12357#endif
12358
12359 return (PyObject *)iterator;
12360
12361error:
12362 Py_DECREF(iterator);
12363 return NULL;
12364}
12365
Ethan Furman410ef8e2016-06-04 12:06:26 -070012366/*
12367 Return the file system path representation of the object.
12368
12369 If the object is str or bytes, then allow it to pass through with
12370 an incremented refcount. If the object defines __fspath__(), then
12371 return the result of that method. All other types raise a TypeError.
12372*/
12373PyObject *
12374PyOS_FSPath(PyObject *path)
12375{
Brett Cannon3f9183b2016-08-26 14:44:48 -070012376 /* For error message reasons, this function is manually inlined in
12377 path_converter(). */
Ethan Furman410ef8e2016-06-04 12:06:26 -070012378 _Py_IDENTIFIER(__fspath__);
12379 PyObject *func = NULL;
12380 PyObject *path_repr = NULL;
12381
12382 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12383 Py_INCREF(path);
12384 return path;
12385 }
12386
12387 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12388 if (NULL == func) {
12389 return PyErr_Format(PyExc_TypeError,
12390 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012391 "not %.200s",
12392 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012393 }
12394
12395 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12396 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012397 if (NULL == path_repr) {
12398 return NULL;
12399 }
12400
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012401 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12402 PyErr_Format(PyExc_TypeError,
12403 "expected %.200s.__fspath__() to return str or bytes, "
12404 "not %.200s", Py_TYPE(path)->tp_name,
12405 Py_TYPE(path_repr)->tp_name);
12406 Py_DECREF(path_repr);
12407 return NULL;
12408 }
12409
Ethan Furman410ef8e2016-06-04 12:06:26 -070012410 return path_repr;
12411}
12412
12413/*[clinic input]
12414os.fspath
12415
12416 path: object
12417
12418Return the file system path representation of the object.
12419
Brett Cannonb4f43e92016-06-09 14:32:08 -070012420If the object is str or bytes, then allow it to pass through as-is. If the
12421object defines __fspath__(), then return the result of that method. All other
12422types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012423[clinic start generated code]*/
12424
12425static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012426os_fspath_impl(PyObject *module, PyObject *path)
12427/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012428{
12429 return PyOS_FSPath(path);
12430}
Victor Stinner6036e442015-03-08 01:58:04 +010012431
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012432#include "clinic/posixmodule.c.h"
12433
Larry Hastings7726ac92014-01-31 22:03:12 -080012434/*[clinic input]
12435dump buffer
12436[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012437/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012438
Larry Hastings31826802013-10-19 00:09:25 -070012439
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012440static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012441
12442 OS_STAT_METHODDEF
12443 OS_ACCESS_METHODDEF
12444 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012445 OS_CHDIR_METHODDEF
12446 OS_CHFLAGS_METHODDEF
12447 OS_CHMOD_METHODDEF
12448 OS_FCHMOD_METHODDEF
12449 OS_LCHMOD_METHODDEF
12450 OS_CHOWN_METHODDEF
12451 OS_FCHOWN_METHODDEF
12452 OS_LCHOWN_METHODDEF
12453 OS_LCHFLAGS_METHODDEF
12454 OS_CHROOT_METHODDEF
12455 OS_CTERMID_METHODDEF
12456 OS_GETCWD_METHODDEF
12457 OS_GETCWDB_METHODDEF
12458 OS_LINK_METHODDEF
12459 OS_LISTDIR_METHODDEF
12460 OS_LSTAT_METHODDEF
12461 OS_MKDIR_METHODDEF
12462 OS_NICE_METHODDEF
12463 OS_GETPRIORITY_METHODDEF
12464 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012465#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012466 {"readlink", (PyCFunction)posix_readlink,
12467 METH_VARARGS | METH_KEYWORDS,
12468 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012469#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012470#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012471 {"readlink", (PyCFunction)win_readlink,
12472 METH_VARARGS | METH_KEYWORDS,
12473 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012474#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012475 OS_RENAME_METHODDEF
12476 OS_REPLACE_METHODDEF
12477 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012478 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012479 OS_SYMLINK_METHODDEF
12480 OS_SYSTEM_METHODDEF
12481 OS_UMASK_METHODDEF
12482 OS_UNAME_METHODDEF
12483 OS_UNLINK_METHODDEF
12484 OS_REMOVE_METHODDEF
12485 OS_UTIME_METHODDEF
12486 OS_TIMES_METHODDEF
12487 OS__EXIT_METHODDEF
12488 OS_EXECV_METHODDEF
12489 OS_EXECVE_METHODDEF
12490 OS_SPAWNV_METHODDEF
12491 OS_SPAWNVE_METHODDEF
12492 OS_FORK1_METHODDEF
12493 OS_FORK_METHODDEF
12494 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12495 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12496 OS_SCHED_GETPARAM_METHODDEF
12497 OS_SCHED_GETSCHEDULER_METHODDEF
12498 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12499 OS_SCHED_SETPARAM_METHODDEF
12500 OS_SCHED_SETSCHEDULER_METHODDEF
12501 OS_SCHED_YIELD_METHODDEF
12502 OS_SCHED_SETAFFINITY_METHODDEF
12503 OS_SCHED_GETAFFINITY_METHODDEF
12504 OS_OPENPTY_METHODDEF
12505 OS_FORKPTY_METHODDEF
12506 OS_GETEGID_METHODDEF
12507 OS_GETEUID_METHODDEF
12508 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012509#ifdef HAVE_GETGROUPLIST
12510 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12511#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012512 OS_GETGROUPS_METHODDEF
12513 OS_GETPID_METHODDEF
12514 OS_GETPGRP_METHODDEF
12515 OS_GETPPID_METHODDEF
12516 OS_GETUID_METHODDEF
12517 OS_GETLOGIN_METHODDEF
12518 OS_KILL_METHODDEF
12519 OS_KILLPG_METHODDEF
12520 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012521#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012522 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012523#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012524 OS_SETUID_METHODDEF
12525 OS_SETEUID_METHODDEF
12526 OS_SETREUID_METHODDEF
12527 OS_SETGID_METHODDEF
12528 OS_SETEGID_METHODDEF
12529 OS_SETREGID_METHODDEF
12530 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012531#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012532 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012533#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012534 OS_GETPGID_METHODDEF
12535 OS_SETPGRP_METHODDEF
12536 OS_WAIT_METHODDEF
12537 OS_WAIT3_METHODDEF
12538 OS_WAIT4_METHODDEF
12539 OS_WAITID_METHODDEF
12540 OS_WAITPID_METHODDEF
12541 OS_GETSID_METHODDEF
12542 OS_SETSID_METHODDEF
12543 OS_SETPGID_METHODDEF
12544 OS_TCGETPGRP_METHODDEF
12545 OS_TCSETPGRP_METHODDEF
12546 OS_OPEN_METHODDEF
12547 OS_CLOSE_METHODDEF
12548 OS_CLOSERANGE_METHODDEF
12549 OS_DEVICE_ENCODING_METHODDEF
12550 OS_DUP_METHODDEF
12551 OS_DUP2_METHODDEF
12552 OS_LOCKF_METHODDEF
12553 OS_LSEEK_METHODDEF
12554 OS_READ_METHODDEF
12555 OS_READV_METHODDEF
12556 OS_PREAD_METHODDEF
12557 OS_WRITE_METHODDEF
12558 OS_WRITEV_METHODDEF
12559 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012560#ifdef HAVE_SENDFILE
12561 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12562 posix_sendfile__doc__},
12563#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012564 OS_FSTAT_METHODDEF
12565 OS_ISATTY_METHODDEF
12566 OS_PIPE_METHODDEF
12567 OS_PIPE2_METHODDEF
12568 OS_MKFIFO_METHODDEF
12569 OS_MKNOD_METHODDEF
12570 OS_MAJOR_METHODDEF
12571 OS_MINOR_METHODDEF
12572 OS_MAKEDEV_METHODDEF
12573 OS_FTRUNCATE_METHODDEF
12574 OS_TRUNCATE_METHODDEF
12575 OS_POSIX_FALLOCATE_METHODDEF
12576 OS_POSIX_FADVISE_METHODDEF
12577 OS_PUTENV_METHODDEF
12578 OS_UNSETENV_METHODDEF
12579 OS_STRERROR_METHODDEF
12580 OS_FCHDIR_METHODDEF
12581 OS_FSYNC_METHODDEF
12582 OS_SYNC_METHODDEF
12583 OS_FDATASYNC_METHODDEF
12584 OS_WCOREDUMP_METHODDEF
12585 OS_WIFCONTINUED_METHODDEF
12586 OS_WIFSTOPPED_METHODDEF
12587 OS_WIFSIGNALED_METHODDEF
12588 OS_WIFEXITED_METHODDEF
12589 OS_WEXITSTATUS_METHODDEF
12590 OS_WTERMSIG_METHODDEF
12591 OS_WSTOPSIG_METHODDEF
12592 OS_FSTATVFS_METHODDEF
12593 OS_STATVFS_METHODDEF
12594 OS_CONFSTR_METHODDEF
12595 OS_SYSCONF_METHODDEF
12596 OS_FPATHCONF_METHODDEF
12597 OS_PATHCONF_METHODDEF
12598 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012599 OS__GETFULLPATHNAME_METHODDEF
12600 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012601 OS__GETDISKUSAGE_METHODDEF
12602 OS__GETFINALPATHNAME_METHODDEF
12603 OS__GETVOLUMEPATHNAME_METHODDEF
12604 OS_GETLOADAVG_METHODDEF
12605 OS_URANDOM_METHODDEF
12606 OS_SETRESUID_METHODDEF
12607 OS_SETRESGID_METHODDEF
12608 OS_GETRESUID_METHODDEF
12609 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012610
Larry Hastings2f936352014-08-05 14:04:04 +100012611 OS_GETXATTR_METHODDEF
12612 OS_SETXATTR_METHODDEF
12613 OS_REMOVEXATTR_METHODDEF
12614 OS_LISTXATTR_METHODDEF
12615
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012616#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12617 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12618#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012619 OS_CPU_COUNT_METHODDEF
12620 OS_GET_INHERITABLE_METHODDEF
12621 OS_SET_INHERITABLE_METHODDEF
12622 OS_GET_HANDLE_INHERITABLE_METHODDEF
12623 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012624#ifndef MS_WINDOWS
12625 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12626 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12627#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012628 {"scandir", (PyCFunction)posix_scandir,
12629 METH_VARARGS | METH_KEYWORDS,
12630 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012631 OS_FSPATH_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012632 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012633};
12634
12635
Brian Curtin52173d42010-12-02 18:29:18 +000012636#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012637static int
Brian Curtin52173d42010-12-02 18:29:18 +000012638enable_symlink()
12639{
12640 HANDLE tok;
12641 TOKEN_PRIVILEGES tok_priv;
12642 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012643
12644 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012645 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012646
12647 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012648 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012649
12650 tok_priv.PrivilegeCount = 1;
12651 tok_priv.Privileges[0].Luid = luid;
12652 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12653
12654 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12655 sizeof(TOKEN_PRIVILEGES),
12656 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012657 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012658
Brian Curtin3b4499c2010-12-28 14:31:47 +000012659 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12660 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012661}
12662#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12663
Barry Warsaw4a342091996-12-19 23:50:02 +000012664static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012666{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012667#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012669#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012670#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012672#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012673#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012675#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012676#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012678#endif
Fred Drakec9680921999-12-13 16:37:25 +000012679#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012681#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012682#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012684#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012685#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012687#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012688#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012690#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012691#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012693#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012694#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012696#endif
12697#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012699#endif
12700#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012702#endif
12703#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012705#endif
12706#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012708#endif
12709#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012711#endif
12712#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012714#endif
12715#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012717#endif
12718#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012719 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012720#endif
12721#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012723#endif
12724#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012726#endif
12727#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012729#endif
12730#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012732#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012733#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012735#endif
12736#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012738#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012739#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012741#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012742#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012744#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012745#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012746#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012748#endif
12749#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012751#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012752#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012753#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012755#endif
12756#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012758#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012759#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012761#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012762#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012764#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012765#ifdef O_TMPFILE
12766 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12767#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012768#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012770#endif
12771#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012773#endif
12774#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012776#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012777#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012778 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012779#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012780#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012781 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012782#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012783
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012784
Jesus Cea94363612012-06-22 18:32:07 +020012785#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012787#endif
12788#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012790#endif
12791
Tim Peters5aa91602002-01-30 05:46:57 +000012792/* MS Windows */
12793#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012794 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012796#endif
12797#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012798 /* Optimize for short life (keep in memory). */
12799 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012801#endif
12802#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012803 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012805#endif
12806#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012807 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012809#endif
12810#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012811 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012812 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012813#endif
12814
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012815/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012816#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012817 /* Send a SIGIO signal whenever input or output
12818 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012819 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012820#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012821#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012822 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012823 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012824#endif
12825#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012826 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012827 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012828#endif
12829#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012830 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012832#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012833#ifdef O_NOLINKS
12834 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012835 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012836#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012837#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012838 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012840#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012841
Victor Stinner8c62be82010-05-06 00:08:46 +000012842 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012843#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012844 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012845#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012846#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012847 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012848#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012849#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012850 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012851#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012852#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012853 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012854#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012855#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012856 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012857#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012858#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012859 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012860#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012861#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012862 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012863#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012864#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012866#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012867#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012869#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012870#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012872#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012873#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012874 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012875#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012876#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012877 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012878#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012879#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012880 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012881#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012882#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012883 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012884#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012885#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012886 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012887#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012888#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012889 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012890#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012891#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012892 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012893#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012894
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012895 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012896#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012897 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012898#endif /* ST_RDONLY */
12899#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012900 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012901#endif /* ST_NOSUID */
12902
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012903 /* GNU extensions */
12904#ifdef ST_NODEV
12905 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12906#endif /* ST_NODEV */
12907#ifdef ST_NOEXEC
12908 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12909#endif /* ST_NOEXEC */
12910#ifdef ST_SYNCHRONOUS
12911 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12912#endif /* ST_SYNCHRONOUS */
12913#ifdef ST_MANDLOCK
12914 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12915#endif /* ST_MANDLOCK */
12916#ifdef ST_WRITE
12917 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12918#endif /* ST_WRITE */
12919#ifdef ST_APPEND
12920 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12921#endif /* ST_APPEND */
12922#ifdef ST_NOATIME
12923 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12924#endif /* ST_NOATIME */
12925#ifdef ST_NODIRATIME
12926 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12927#endif /* ST_NODIRATIME */
12928#ifdef ST_RELATIME
12929 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12930#endif /* ST_RELATIME */
12931
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012932 /* FreeBSD sendfile() constants */
12933#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012934 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012935#endif
12936#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012937 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012938#endif
12939#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012940 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012941#endif
12942
Ross Lagerwall7807c352011-03-17 20:20:30 +020012943 /* constants for posix_fadvise */
12944#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012945 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012946#endif
12947#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012948 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012949#endif
12950#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012952#endif
12953#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012954 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012955#endif
12956#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012958#endif
12959#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012961#endif
12962
12963 /* constants for waitid */
12964#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12966 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12967 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012968#endif
12969#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012970 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012971#endif
12972#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012973 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012974#endif
12975#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012976 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012977#endif
12978#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012979 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012980#endif
12981#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012982 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012983#endif
12984#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012985 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012986#endif
12987#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012988 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012989#endif
12990
12991 /* constants for lockf */
12992#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012994#endif
12995#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012996 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012997#endif
12998#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012999 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013000#endif
13001#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013002 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013003#endif
13004
Guido van Rossum246bc171999-02-01 23:54:31 +000013005#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013006 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
13007 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
13008 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
13009 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
13010 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000013011#endif
13012
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013013#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013014#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013015 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013016#endif
13017#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013018 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013019#endif
13020#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013021 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070013022#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013023#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013024 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013025#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013026#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013027 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013028#endif
13029#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013030 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013031#endif
13032#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013033 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013034#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013035#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013036 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013037#endif
13038#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013039 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013040#endif
13041#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013042 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013043#endif
13044#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013045 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013046#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013047#endif
13048
Benjamin Peterson9428d532011-09-14 11:45:52 -040013049#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013050 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13051 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13052 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013053#endif
13054
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013055#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013056 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013057#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013058#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013059 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013060#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013061#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013062 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013063#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013064#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013065 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013066#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013067#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013068 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013069#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013070#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013071 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013072#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013073#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013074 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013075#endif
13076
Victor Stinner8c62be82010-05-06 00:08:46 +000013077 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013078}
13079
13080
Martin v. Löwis1a214512008-06-11 05:26:20 +000013081static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013082 PyModuleDef_HEAD_INIT,
13083 MODNAME,
13084 posix__doc__,
13085 -1,
13086 posix_methods,
13087 NULL,
13088 NULL,
13089 NULL,
13090 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013091};
13092
13093
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013094static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013095
13096#ifdef HAVE_FACCESSAT
13097 "HAVE_FACCESSAT",
13098#endif
13099
13100#ifdef HAVE_FCHDIR
13101 "HAVE_FCHDIR",
13102#endif
13103
13104#ifdef HAVE_FCHMOD
13105 "HAVE_FCHMOD",
13106#endif
13107
13108#ifdef HAVE_FCHMODAT
13109 "HAVE_FCHMODAT",
13110#endif
13111
13112#ifdef HAVE_FCHOWN
13113 "HAVE_FCHOWN",
13114#endif
13115
Larry Hastings00964ed2013-08-12 13:49:30 -040013116#ifdef HAVE_FCHOWNAT
13117 "HAVE_FCHOWNAT",
13118#endif
13119
Larry Hastings9cf065c2012-06-22 16:30:09 -070013120#ifdef HAVE_FEXECVE
13121 "HAVE_FEXECVE",
13122#endif
13123
13124#ifdef HAVE_FDOPENDIR
13125 "HAVE_FDOPENDIR",
13126#endif
13127
Georg Brandl306336b2012-06-24 12:55:33 +020013128#ifdef HAVE_FPATHCONF
13129 "HAVE_FPATHCONF",
13130#endif
13131
Larry Hastings9cf065c2012-06-22 16:30:09 -070013132#ifdef HAVE_FSTATAT
13133 "HAVE_FSTATAT",
13134#endif
13135
13136#ifdef HAVE_FSTATVFS
13137 "HAVE_FSTATVFS",
13138#endif
13139
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013140#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013141 "HAVE_FTRUNCATE",
13142#endif
13143
Larry Hastings9cf065c2012-06-22 16:30:09 -070013144#ifdef HAVE_FUTIMENS
13145 "HAVE_FUTIMENS",
13146#endif
13147
13148#ifdef HAVE_FUTIMES
13149 "HAVE_FUTIMES",
13150#endif
13151
13152#ifdef HAVE_FUTIMESAT
13153 "HAVE_FUTIMESAT",
13154#endif
13155
13156#ifdef HAVE_LINKAT
13157 "HAVE_LINKAT",
13158#endif
13159
13160#ifdef HAVE_LCHFLAGS
13161 "HAVE_LCHFLAGS",
13162#endif
13163
13164#ifdef HAVE_LCHMOD
13165 "HAVE_LCHMOD",
13166#endif
13167
13168#ifdef HAVE_LCHOWN
13169 "HAVE_LCHOWN",
13170#endif
13171
13172#ifdef HAVE_LSTAT
13173 "HAVE_LSTAT",
13174#endif
13175
13176#ifdef HAVE_LUTIMES
13177 "HAVE_LUTIMES",
13178#endif
13179
13180#ifdef HAVE_MKDIRAT
13181 "HAVE_MKDIRAT",
13182#endif
13183
13184#ifdef HAVE_MKFIFOAT
13185 "HAVE_MKFIFOAT",
13186#endif
13187
13188#ifdef HAVE_MKNODAT
13189 "HAVE_MKNODAT",
13190#endif
13191
13192#ifdef HAVE_OPENAT
13193 "HAVE_OPENAT",
13194#endif
13195
13196#ifdef HAVE_READLINKAT
13197 "HAVE_READLINKAT",
13198#endif
13199
13200#ifdef HAVE_RENAMEAT
13201 "HAVE_RENAMEAT",
13202#endif
13203
13204#ifdef HAVE_SYMLINKAT
13205 "HAVE_SYMLINKAT",
13206#endif
13207
13208#ifdef HAVE_UNLINKAT
13209 "HAVE_UNLINKAT",
13210#endif
13211
13212#ifdef HAVE_UTIMENSAT
13213 "HAVE_UTIMENSAT",
13214#endif
13215
13216#ifdef MS_WINDOWS
13217 "MS_WINDOWS",
13218#endif
13219
13220 NULL
13221};
13222
13223
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013224PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013225INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013226{
Victor Stinner8c62be82010-05-06 00:08:46 +000013227 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013228 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013229 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013230
Brian Curtin52173d42010-12-02 18:29:18 +000013231#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013232 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013233#endif
13234
Victor Stinner8c62be82010-05-06 00:08:46 +000013235 m = PyModule_Create(&posixmodule);
13236 if (m == NULL)
13237 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013238
Victor Stinner8c62be82010-05-06 00:08:46 +000013239 /* Initialize environ dictionary */
13240 v = convertenviron();
13241 Py_XINCREF(v);
13242 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13243 return NULL;
13244 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013245
Victor Stinner8c62be82010-05-06 00:08:46 +000013246 if (all_ins(m))
13247 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013248
Victor Stinner8c62be82010-05-06 00:08:46 +000013249 if (setup_confname_tables(m))
13250 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013251
Victor Stinner8c62be82010-05-06 00:08:46 +000013252 Py_INCREF(PyExc_OSError);
13253 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013254
Guido van Rossumb3d39562000-01-31 18:41:26 +000013255#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013256 if (posix_putenv_garbage == NULL)
13257 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013258#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013259
Victor Stinner8c62be82010-05-06 00:08:46 +000013260 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013261#if defined(HAVE_WAITID) && !defined(__APPLE__)
13262 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013263 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13264 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013265#endif
13266
Christian Heimes25827622013-10-12 01:27:08 +020013267 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013268 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13269 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13270 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013271 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13272 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013273 structseq_new = StatResultType.tp_new;
13274 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013275
Christian Heimes25827622013-10-12 01:27:08 +020013276 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013277 if (PyStructSequence_InitType2(&StatVFSResultType,
13278 &statvfs_result_desc) < 0)
13279 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013280#ifdef NEED_TICKS_PER_SECOND
13281# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013282 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013283# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013284 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013285# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013286 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013287# endif
13288#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013289
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013290#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013291 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013292 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13293 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013294 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013295#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013296
13297 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013298 if (PyStructSequence_InitType2(&TerminalSizeType,
13299 &TerminalSize_desc) < 0)
13300 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013301
13302 /* initialize scandir types */
13303 if (PyType_Ready(&ScandirIteratorType) < 0)
13304 return NULL;
13305 if (PyType_Ready(&DirEntryType) < 0)
13306 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013307 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013308#if defined(HAVE_WAITID) && !defined(__APPLE__)
13309 Py_INCREF((PyObject*) &WaitidResultType);
13310 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13311#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013312 Py_INCREF((PyObject*) &StatResultType);
13313 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13314 Py_INCREF((PyObject*) &StatVFSResultType);
13315 PyModule_AddObject(m, "statvfs_result",
13316 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013317
13318#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013319 Py_INCREF(&SchedParamType);
13320 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013321#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013322
Larry Hastings605a62d2012-06-24 04:33:36 -070013323 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013324 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13325 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013326 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13327
13328 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013329 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13330 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013331 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13332
Thomas Wouters477c8d52006-05-27 19:21:47 +000013333#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013334 /*
13335 * Step 2 of weak-linking support on Mac OS X.
13336 *
13337 * The code below removes functions that are not available on the
13338 * currently active platform.
13339 *
13340 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013341 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013342 * OSX 10.4.
13343 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013344#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013345 if (fstatvfs == NULL) {
13346 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13347 return NULL;
13348 }
13349 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013350#endif /* HAVE_FSTATVFS */
13351
13352#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013353 if (statvfs == NULL) {
13354 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13355 return NULL;
13356 }
13357 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013358#endif /* HAVE_STATVFS */
13359
13360# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013361 if (lchown == NULL) {
13362 if (PyObject_DelAttrString(m, "lchown") == -1) {
13363 return NULL;
13364 }
13365 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013366#endif /* HAVE_LCHOWN */
13367
13368
13369#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013370
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013371 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013372 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13373
Larry Hastings6fe20b32012-04-19 15:07:49 -070013374 billion = PyLong_FromLong(1000000000);
13375 if (!billion)
13376 return NULL;
13377
Larry Hastings9cf065c2012-06-22 16:30:09 -070013378 /* suppress "function not used" warnings */
13379 {
13380 int ignored;
13381 fd_specified("", -1);
13382 follow_symlinks_specified("", 1);
13383 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13384 dir_fd_converter(Py_None, &ignored);
13385 dir_fd_unavailable(Py_None, &ignored);
13386 }
13387
13388 /*
13389 * provide list of locally available functions
13390 * so os.py can populate support_* lists
13391 */
13392 list = PyList_New(0);
13393 if (!list)
13394 return NULL;
13395 for (trace = have_functions; *trace; trace++) {
13396 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13397 if (!unicode)
13398 return NULL;
13399 if (PyList_Append(list, unicode))
13400 return NULL;
13401 Py_DECREF(unicode);
13402 }
13403 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013404
13405 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013406 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013407
13408 initialized = 1;
13409
Victor Stinner8c62be82010-05-06 00:08:46 +000013410 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013411}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013412
13413#ifdef __cplusplus
13414}
13415#endif