blob: 10d6bcbba9779b642159b202ed1048dd06e2c398 [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;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300837 PyObject *bytes;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838 Py_ssize_t length;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300839 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840
841#define FORMAT_EXCEPTION(exc, fmt) \
842 PyErr_Format(exc, "%s%s" fmt, \
843 path->function_name ? path->function_name : "", \
844 path->function_name ? ": " : "", \
845 path->argument_name ? path->argument_name : "path")
846
847 /* Py_CLEANUP_SUPPORTED support */
848 if (o == NULL) {
849 path_cleanup(path);
850 return 1;
851 }
852
853 /* ensure it's always safe to call path_cleanup() */
854 path->cleanup = NULL;
855
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300856 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700857 path->wide = NULL;
858 path->narrow = NULL;
859 path->length = 0;
860 path->object = o;
861 path->fd = -1;
862 return 1;
863 }
864
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300865 if (PyUnicode_Check(o)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300867 const wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100868
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300869 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100870 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 return 0;
872 }
Victor Stinner59799a82013-11-13 14:17:30 +0100873 if (length > 32767) {
874 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 return 0;
876 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300877 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300878 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300879 return 0;
880 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881
882 path->wide = wide;
883 path->narrow = NULL;
884 path->length = length;
885 path->object = o;
886 path->fd = -1;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300887 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700888#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300889 if (!PyUnicode_FSConverter(o, &bytes)) {
890 return 0;
891 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892#endif
893 }
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300894 else if (PyBytes_Check(o)) {
895#ifdef MS_WINDOWS
896 if (win32_warn_bytes_api()) {
897 return 0;
898 }
899#endif
900 bytes = o;
901 Py_INCREF(bytes);
902 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300903 else if (PyObject_CheckBuffer(o)) {
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300904 if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
905 "%s%s%s should be %s, not %.200s",
906 path->function_name ? path->function_name : "",
907 path->function_name ? ": " : "",
908 path->argument_name ? path->argument_name : "path",
909 path->allow_fd && path->nullable ? "string, bytes, integer or None" :
910 path->allow_fd ? "string, bytes or integer" :
911 path->nullable ? "string, bytes or None" :
912 "string or bytes",
913 Py_TYPE(o)->tp_name)) {
914 return 0;
915 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300916#ifdef MS_WINDOWS
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300917 if (win32_warn_bytes_api()) {
918 return 0;
919 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300920#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300921 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700922 if (!bytes) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300923 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924 }
925 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300926 else if (path->allow_fd && PyIndex_Check(o)) {
927 if (!_fd_converter(o, &path->fd)) {
928 return 0;
929 }
930 path->wide = NULL;
931 path->narrow = NULL;
932 path->length = 0;
933 path->object = o;
934 return 1;
935 }
936 else {
937 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
938 path->function_name ? path->function_name : "",
939 path->function_name ? ": " : "",
940 path->argument_name ? path->argument_name : "path",
941 path->allow_fd && path->nullable ? "string, bytes, integer or None" :
942 path->allow_fd ? "string, bytes or integer" :
943 path->nullable ? "string, bytes or None" :
944 "string or bytes",
945 Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700946 return 0;
947 }
948
Larry Hastings9cf065c2012-06-22 16:30:09 -0700949 length = PyBytes_GET_SIZE(bytes);
950#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100951 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700952 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
953 Py_DECREF(bytes);
954 return 0;
955 }
956#endif
957
958 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200959 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300960 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700961 Py_DECREF(bytes);
962 return 0;
963 }
964
965 path->wide = NULL;
966 path->narrow = narrow;
967 path->length = length;
968 path->object = o;
969 path->fd = -1;
Serhiy Storchakad73c3182016-08-06 23:22:08 +0300970 if (bytes == o) {
971 Py_DECREF(bytes);
972 return 1;
973 }
974 else {
975 path->cleanup = bytes;
976 return Py_CLEANUP_SUPPORTED;
977 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978}
979
980static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200981argument_unavailable_error(const char *function_name, const char *argument_name)
982{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700983 PyErr_Format(PyExc_NotImplementedError,
984 "%s%s%s unavailable on this platform",
985 (function_name != NULL) ? function_name : "",
986 (function_name != NULL) ? ": ": "",
987 argument_name);
988}
989
990static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200991dir_fd_unavailable(PyObject *o, void *p)
992{
993 int dir_fd;
994 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700995 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200996 if (dir_fd != DEFAULT_DIR_FD) {
997 argument_unavailable_error(NULL, "dir_fd");
998 return 0;
999 }
1000 *(int *)p = dir_fd;
1001 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07001002}
1003
1004static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001005fd_specified(const char *function_name, int fd)
1006{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001007 if (fd == -1)
1008 return 0;
1009
1010 argument_unavailable_error(function_name, "fd");
1011 return 1;
1012}
1013
1014static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001015follow_symlinks_specified(const char *function_name, int follow_symlinks)
1016{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001017 if (follow_symlinks)
1018 return 0;
1019
1020 argument_unavailable_error(function_name, "follow_symlinks");
1021 return 1;
1022}
1023
1024static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001025path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
1026{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001027 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
1028 PyErr_Format(PyExc_ValueError,
1029 "%s: can't specify dir_fd without matching path",
1030 function_name);
1031 return 1;
1032 }
1033 return 0;
1034}
1035
1036static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001037dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1038{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001039 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1040 PyErr_Format(PyExc_ValueError,
1041 "%s: can't specify both dir_fd and fd",
1042 function_name);
1043 return 1;
1044 }
1045 return 0;
1046}
1047
1048static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001049fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1050 int follow_symlinks)
1051{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001052 if ((fd > 0) && (!follow_symlinks)) {
1053 PyErr_Format(PyExc_ValueError,
1054 "%s: cannot use fd and follow_symlinks together",
1055 function_name);
1056 return 1;
1057 }
1058 return 0;
1059}
1060
1061static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001062dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1063 int follow_symlinks)
1064{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001065 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1066 PyErr_Format(PyExc_ValueError,
1067 "%s: cannot use dir_fd and follow_symlinks together",
1068 function_name);
1069 return 1;
1070 }
1071 return 0;
1072}
1073
Larry Hastings2f936352014-08-05 14:04:04 +10001074#ifdef MS_WINDOWS
1075 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001076#else
Larry Hastings2f936352014-08-05 14:04:04 +10001077 typedef off_t Py_off_t;
1078#endif
1079
1080static int
1081Py_off_t_converter(PyObject *arg, void *addr)
1082{
1083#ifdef HAVE_LARGEFILE_SUPPORT
1084 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1085#else
1086 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001087#endif
1088 if (PyErr_Occurred())
1089 return 0;
1090 return 1;
1091}
Larry Hastings2f936352014-08-05 14:04:04 +10001092
1093static PyObject *
1094PyLong_FromPy_off_t(Py_off_t offset)
1095{
1096#ifdef HAVE_LARGEFILE_SUPPORT
1097 return PyLong_FromLongLong(offset);
1098#else
1099 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001100#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001101}
1102
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001103
Steve Dowerd81431f2015-03-06 14:47:02 -08001104#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1105/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1106 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001107 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001108#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001109#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001110#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001111#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001112#define _NO_CONSOLE_FILENO (intptr_t)-2
1113
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001114/* the special case of checking dup2. The target fd must be in a sensible range */
1115static int
1116_PyVerify_fd_dup2(int fd1, int fd2)
1117{
Victor Stinner8c62be82010-05-06 00:08:46 +00001118 if (!_PyVerify_fd(fd1))
1119 return 0;
1120 if (fd2 == _NO_CONSOLE_FILENO)
1121 return 0;
1122 if ((unsigned)fd2 < _NHANDLE_)
1123 return 1;
1124 else
1125 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001126}
1127#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001128#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001129#endif
1130
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001131#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001132
1133static int
Brian Curtind25aef52011-06-13 15:16:04 -05001134win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001135{
Martin Panter70214ad2016-08-04 02:38:59 +00001136 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1137 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001138 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001139
1140 if (0 == DeviceIoControl(
1141 reparse_point_handle,
1142 FSCTL_GET_REPARSE_POINT,
1143 NULL, 0, /* in buffer */
1144 target_buffer, sizeof(target_buffer),
1145 &n_bytes_returned,
1146 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001147 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001148
1149 if (reparse_tag)
1150 *reparse_tag = rdb->ReparseTag;
1151
Brian Curtind25aef52011-06-13 15:16:04 -05001152 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001153}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001154
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001155#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001156
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001157/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001158#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001159/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001160** environ directly, we must obtain it with _NSGetEnviron(). See also
1161** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001162*/
1163#include <crt_externs.h>
1164static char **environ;
1165#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001166extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001167#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001168
Barry Warsaw53699e91996-12-10 23:23:01 +00001169static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001170convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001171{
Victor Stinner8c62be82010-05-06 00:08:46 +00001172 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001173#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001174 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001175#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001176 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001177#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001178
Victor Stinner8c62be82010-05-06 00:08:46 +00001179 d = PyDict_New();
1180 if (d == NULL)
1181 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001182#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001183 if (environ == NULL)
1184 environ = *_NSGetEnviron();
1185#endif
1186#ifdef MS_WINDOWS
1187 /* _wenviron must be initialized in this way if the program is started
1188 through main() instead of wmain(). */
1189 _wgetenv(L"");
1190 if (_wenviron == NULL)
1191 return d;
1192 /* This part ignores errors */
1193 for (e = _wenviron; *e != NULL; e++) {
1194 PyObject *k;
1195 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001196 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001197 if (p == NULL)
1198 continue;
1199 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1200 if (k == NULL) {
1201 PyErr_Clear();
1202 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001203 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1205 if (v == NULL) {
1206 PyErr_Clear();
1207 Py_DECREF(k);
1208 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001209 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001210 if (PyDict_GetItem(d, k) == NULL) {
1211 if (PyDict_SetItem(d, k, v) != 0)
1212 PyErr_Clear();
1213 }
1214 Py_DECREF(k);
1215 Py_DECREF(v);
1216 }
1217#else
1218 if (environ == NULL)
1219 return d;
1220 /* This part ignores errors */
1221 for (e = environ; *e != NULL; e++) {
1222 PyObject *k;
1223 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001224 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 if (p == NULL)
1226 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001227 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001228 if (k == NULL) {
1229 PyErr_Clear();
1230 continue;
1231 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001232 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001233 if (v == NULL) {
1234 PyErr_Clear();
1235 Py_DECREF(k);
1236 continue;
1237 }
1238 if (PyDict_GetItem(d, k) == NULL) {
1239 if (PyDict_SetItem(d, k, v) != 0)
1240 PyErr_Clear();
1241 }
1242 Py_DECREF(k);
1243 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001244 }
1245#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001246 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001247}
1248
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001249/* Set a POSIX-specific error from errno, and return NULL */
1250
Barry Warsawd58d7641998-07-23 16:14:40 +00001251static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001252posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001253{
Victor Stinner8c62be82010-05-06 00:08:46 +00001254 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001255}
Mark Hammondef8b6542001-05-13 08:04:26 +00001256
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001257#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001258static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001259win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001260{
Victor Stinner8c62be82010-05-06 00:08:46 +00001261 /* XXX We should pass the function name along in the future.
1262 (winreg.c also wants to pass the function name.)
1263 This would however require an additional param to the
1264 Windows error object, which is non-trivial.
1265 */
1266 errno = GetLastError();
1267 if (filename)
1268 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1269 else
1270 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001271}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001272
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001273static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001274win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001275{
1276 /* XXX - see win32_error for comments on 'function' */
1277 errno = GetLastError();
1278 if (filename)
1279 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001280 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001281 errno,
1282 filename);
1283 else
1284 return PyErr_SetFromWindowsErr(errno);
1285}
1286
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001287#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001288
Larry Hastings9cf065c2012-06-22 16:30:09 -07001289static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001290path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001291{
1292#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001293 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1294 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001295#else
Victor Stinner292c8352012-10-30 02:17:38 +01001296 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001297#endif
1298}
1299
Larry Hastings31826802013-10-19 00:09:25 -07001300
Larry Hastingsb0827312014-02-09 22:05:19 -08001301static PyObject *
1302path_error2(path_t *path, path_t *path2)
1303{
1304#ifdef MS_WINDOWS
1305 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1306 0, path->object, path2->object);
1307#else
1308 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1309 path->object, path2->object);
1310#endif
1311}
1312
1313
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001314/* POSIX generic methods */
1315
Larry Hastings2f936352014-08-05 14:04:04 +10001316static int
1317fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001318{
Victor Stinner8c62be82010-05-06 00:08:46 +00001319 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001320 int *pointer = (int *)p;
1321 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001323 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001324 *pointer = fd;
1325 return 1;
1326}
1327
1328static PyObject *
1329posix_fildes_fd(int fd, int (*func)(int))
1330{
1331 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001332 int async_err = 0;
1333
Steve Dower8fc89802015-04-12 00:26:27 -04001334 if (!_PyVerify_fd(fd))
1335 return posix_error();
1336
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001337 do {
1338 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001339 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001340 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001341 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001342 Py_END_ALLOW_THREADS
1343 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1344 if (res != 0)
1345 return (!async_err) ? posix_error() : NULL;
1346 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001347}
Guido van Rossum21142a01999-01-08 21:05:37 +00001348
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001349
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001350#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001351/* This is a reimplementation of the C library's chdir function,
1352 but one that produces Win32 errors instead of DOS error codes.
1353 chdir is essentially a wrapper around SetCurrentDirectory; however,
1354 it also needs to set "magic" environment variables indicating
1355 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001356static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001357win32_chdir(LPCSTR path)
1358{
Victor Stinner75875072013-11-24 19:23:25 +01001359 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001360 int result;
1361 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001362
Victor Stinner8c62be82010-05-06 00:08:46 +00001363 if(!SetCurrentDirectoryA(path))
1364 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001365 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (!result)
1367 return FALSE;
1368 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001369 than MAX_PATH-1 (not including the final null character). */
1370 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001371 if (strncmp(new_path, "\\\\", 2) == 0 ||
1372 strncmp(new_path, "//", 2) == 0)
1373 /* UNC path, nothing to do. */
1374 return TRUE;
1375 env[1] = new_path[0];
1376 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001377}
1378
1379/* The Unicode version differs from the ANSI version
1380 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001381static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001382win32_wchdir(LPCWSTR path)
1383{
Victor Stinnered537822015-12-13 21:40:26 +01001384 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001385 int result;
1386 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001387
Victor Stinner8c62be82010-05-06 00:08:46 +00001388 if(!SetCurrentDirectoryW(path))
1389 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001390 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001391 if (!result)
1392 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001393 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001394 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001395 if (!new_path) {
1396 SetLastError(ERROR_OUTOFMEMORY);
1397 return FALSE;
1398 }
1399 result = GetCurrentDirectoryW(result, new_path);
1400 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001401 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001402 return FALSE;
1403 }
1404 }
1405 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1406 wcsncmp(new_path, L"//", 2) == 0)
1407 /* UNC path, nothing to do. */
1408 return TRUE;
1409 env[1] = new_path[0];
1410 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001411 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001412 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001414}
1415#endif
1416
Martin v. Löwis14694662006-02-03 12:54:16 +00001417#ifdef MS_WINDOWS
1418/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1419 - time stamps are restricted to second resolution
1420 - file modification times suffer from forth-and-back conversions between
1421 UTC and local time
1422 Therefore, we implement our own stat, based on the Win32 API directly.
1423*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001424#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001425#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001426
Guido van Rossumd8faa362007-04-27 19:54:29 +00001427static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001428attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001429{
Victor Stinner8c62be82010-05-06 00:08:46 +00001430 HANDLE hFindFile;
1431 WIN32_FIND_DATAA FileData;
1432 hFindFile = FindFirstFileA(pszFile, &FileData);
1433 if (hFindFile == INVALID_HANDLE_VALUE)
1434 return FALSE;
1435 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001436 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001437 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001438 info->dwFileAttributes = FileData.dwFileAttributes;
1439 info->ftCreationTime = FileData.ftCreationTime;
1440 info->ftLastAccessTime = FileData.ftLastAccessTime;
1441 info->ftLastWriteTime = FileData.ftLastWriteTime;
1442 info->nFileSizeHigh = FileData.nFileSizeHigh;
1443 info->nFileSizeLow = FileData.nFileSizeLow;
1444/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001445 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1446 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001447 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001448}
1449
Victor Stinner6036e442015-03-08 01:58:04 +01001450static void
1451find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1452 BY_HANDLE_FILE_INFORMATION *info,
1453 ULONG *reparse_tag)
1454{
1455 memset(info, 0, sizeof(*info));
1456 info->dwFileAttributes = pFileData->dwFileAttributes;
1457 info->ftCreationTime = pFileData->ftCreationTime;
1458 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1459 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1460 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1461 info->nFileSizeLow = pFileData->nFileSizeLow;
1462/* info->nNumberOfLinks = 1; */
1463 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1464 *reparse_tag = pFileData->dwReserved0;
1465 else
1466 *reparse_tag = 0;
1467}
1468
Guido van Rossumd8faa362007-04-27 19:54:29 +00001469static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001470attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001471{
Victor Stinner8c62be82010-05-06 00:08:46 +00001472 HANDLE hFindFile;
1473 WIN32_FIND_DATAW FileData;
1474 hFindFile = FindFirstFileW(pszFile, &FileData);
1475 if (hFindFile == INVALID_HANDLE_VALUE)
1476 return FALSE;
1477 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001478 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001479 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001480}
1481
Brian Curtind25aef52011-06-13 15:16:04 -05001482static BOOL
1483get_target_path(HANDLE hdl, wchar_t **target_path)
1484{
1485 int buf_size, result_length;
1486 wchar_t *buf;
1487
1488 /* We have a good handle to the target, use it to determine
1489 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001490 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1491 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001492 if(!buf_size)
1493 return FALSE;
1494
Victor Stinnerc36674a2016-03-16 14:30:16 +01001495 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001496 if (!buf) {
1497 SetLastError(ERROR_OUTOFMEMORY);
1498 return FALSE;
1499 }
1500
Steve Dower2ea51c92015-03-20 21:49:12 -07001501 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001502 buf, buf_size, VOLUME_NAME_DOS);
1503
1504 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001505 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001506 return FALSE;
1507 }
1508
1509 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001510 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001511 return FALSE;
1512 }
1513
1514 buf[result_length] = 0;
1515
1516 *target_path = buf;
1517 return TRUE;
1518}
1519
1520static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001521win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001522 BOOL traverse);
1523static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001524win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001525 BOOL traverse)
1526{
Victor Stinner26de69d2011-06-17 15:15:38 +02001527 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001528 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001530 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001531 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001532 const char *dot;
1533
1534 hFile = CreateFileA(
1535 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001536 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001537 0, /* share mode */
1538 NULL, /* security attributes */
1539 OPEN_EXISTING,
1540 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001541 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1542 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001543 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001544 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1545 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001546 NULL);
1547
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001548 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001549 /* Either the target doesn't exist, or we don't have access to
1550 get a handle to it. If the former, we need to return an error.
1551 If the latter, we can use attributes_from_dir. */
1552 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001553 return -1;
1554 /* Could not get attributes on open file. Fall back to
1555 reading the directory. */
1556 if (!attributes_from_dir(path, &info, &reparse_tag))
1557 /* Very strange. This should not fail now */
1558 return -1;
1559 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1560 if (traverse) {
1561 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001562 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001563 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001565 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001566 } else {
1567 if (!GetFileInformationByHandle(hFile, &info)) {
1568 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001569 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001570 }
1571 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001572 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1573 return -1;
1574
1575 /* Close the outer open file handle now that we're about to
1576 reopen it with different flags. */
1577 if (!CloseHandle(hFile))
1578 return -1;
1579
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001580 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001581 /* In order to call GetFinalPathNameByHandle we need to open
1582 the file without the reparse handling flag set. */
1583 hFile2 = CreateFileA(
1584 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1585 NULL, OPEN_EXISTING,
1586 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1587 NULL);
1588 if (hFile2 == INVALID_HANDLE_VALUE)
1589 return -1;
1590
1591 if (!get_target_path(hFile2, &target_path))
1592 return -1;
1593
1594 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001595 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001596 return code;
1597 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001598 } else
1599 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001600 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001601 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001602
1603 /* Set S_IEXEC if it is an .exe, .bat, ... */
1604 dot = strrchr(path, '.');
1605 if (dot) {
1606 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1607 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1608 result->st_mode |= 0111;
1609 }
1610 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001611}
1612
1613static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001614win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001615 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001616{
1617 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001618 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001619 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001620 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001621 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 const wchar_t *dot;
1623
1624 hFile = CreateFileW(
1625 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001626 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001627 0, /* share mode */
1628 NULL, /* security attributes */
1629 OPEN_EXISTING,
1630 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001631 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1632 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001633 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001634 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001635 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001636 NULL);
1637
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001638 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001639 /* Either the target doesn't exist, or we don't have access to
1640 get a handle to it. If the former, we need to return an error.
1641 If the latter, we can use attributes_from_dir. */
1642 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 return -1;
1644 /* Could not get attributes on open file. Fall back to
1645 reading the directory. */
1646 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1647 /* Very strange. This should not fail now */
1648 return -1;
1649 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1650 if (traverse) {
1651 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001652 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001653 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001655 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001656 } else {
1657 if (!GetFileInformationByHandle(hFile, &info)) {
1658 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001659 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001660 }
1661 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001662 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1663 return -1;
1664
1665 /* Close the outer open file handle now that we're about to
1666 reopen it with different flags. */
1667 if (!CloseHandle(hFile))
1668 return -1;
1669
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001671 /* In order to call GetFinalPathNameByHandle we need to open
1672 the file without the reparse handling flag set. */
1673 hFile2 = CreateFileW(
1674 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1675 NULL, OPEN_EXISTING,
1676 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1677 NULL);
1678 if (hFile2 == INVALID_HANDLE_VALUE)
1679 return -1;
1680
1681 if (!get_target_path(hFile2, &target_path))
1682 return -1;
1683
1684 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001685 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686 return code;
1687 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001688 } else
1689 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001690 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001691 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001692
1693 /* Set S_IEXEC if it is an .exe, .bat, ... */
1694 dot = wcsrchr(path, '.');
1695 if (dot) {
1696 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1697 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1698 result->st_mode |= 0111;
1699 }
1700 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001701}
1702
1703static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001704win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001705{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 /* Protocol violation: we explicitly clear errno, instead of
1707 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001708 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 errno = 0;
1710 return code;
1711}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001712
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001713static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001714win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715{
1716 /* Protocol violation: we explicitly clear errno, instead of
1717 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001718 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001719 errno = 0;
1720 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001721}
Brian Curtind25aef52011-06-13 15:16:04 -05001722/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001723
1724 In Posix, stat automatically traverses symlinks and returns the stat
1725 structure for the target. In Windows, the equivalent GetFileAttributes by
1726 default does not traverse symlinks and instead returns attributes for
1727 the symlink.
1728
1729 Therefore, win32_lstat will get the attributes traditionally, and
1730 win32_stat will first explicitly resolve the symlink target and then will
1731 call win32_lstat on that result.
1732
Ezio Melotti4969f702011-03-15 05:59:46 +02001733 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001734
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001735static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001736win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001737{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001738 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001739}
1740
Victor Stinner8c62be82010-05-06 00:08:46 +00001741static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001742win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001743{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001744 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001745}
1746
1747static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001748win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001749{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001750 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001751}
1752
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001753static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001754win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001755{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001756 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001757}
1758
Martin v. Löwis14694662006-02-03 12:54:16 +00001759#endif /* MS_WINDOWS */
1760
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001761PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001762"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001763This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001764 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1766\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001767Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1768or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001769\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001770See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771
1772static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 {"st_mode", "protection bits"},
1774 {"st_ino", "inode"},
1775 {"st_dev", "device"},
1776 {"st_nlink", "number of hard links"},
1777 {"st_uid", "user ID of owner"},
1778 {"st_gid", "group ID of owner"},
1779 {"st_size", "total size, in bytes"},
1780 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1781 {NULL, "integer time of last access"},
1782 {NULL, "integer time of last modification"},
1783 {NULL, "integer time of last change"},
1784 {"st_atime", "time of last access"},
1785 {"st_mtime", "time of last modification"},
1786 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001787 {"st_atime_ns", "time of last access in nanoseconds"},
1788 {"st_mtime_ns", "time of last modification in nanoseconds"},
1789 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001791 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001792#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001793#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001794 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001795#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001796#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001797 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001798#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001799#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001800 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001801#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001802#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001803 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001804#endif
1805#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001806 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001807#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001808#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1809 {"st_file_attributes", "Windows file attribute bits"},
1810#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001811 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001812};
1813
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001814#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001815#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001816#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001817#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001818#endif
1819
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001820#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001821#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1822#else
1823#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1824#endif
1825
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001826#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1828#else
1829#define ST_RDEV_IDX ST_BLOCKS_IDX
1830#endif
1831
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001832#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1833#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1834#else
1835#define ST_FLAGS_IDX ST_RDEV_IDX
1836#endif
1837
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001838#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001839#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001840#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001841#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001842#endif
1843
1844#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1845#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1846#else
1847#define ST_BIRTHTIME_IDX ST_GEN_IDX
1848#endif
1849
Zachary Ware63f277b2014-06-19 09:46:37 -05001850#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1851#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1852#else
1853#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1854#endif
1855
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 "stat_result", /* name */
1858 stat_result__doc__, /* doc */
1859 stat_result_fields,
1860 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861};
1862
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001863PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001864"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1865This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001866 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001867or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001868\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001869See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001870
1871static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001872 {"f_bsize", },
1873 {"f_frsize", },
1874 {"f_blocks", },
1875 {"f_bfree", },
1876 {"f_bavail", },
1877 {"f_files", },
1878 {"f_ffree", },
1879 {"f_favail", },
1880 {"f_flag", },
1881 {"f_namemax",},
1882 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001883};
1884
1885static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001886 "statvfs_result", /* name */
1887 statvfs_result__doc__, /* doc */
1888 statvfs_result_fields,
1889 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001890};
1891
Ross Lagerwall7807c352011-03-17 20:20:30 +02001892#if defined(HAVE_WAITID) && !defined(__APPLE__)
1893PyDoc_STRVAR(waitid_result__doc__,
1894"waitid_result: Result from waitid.\n\n\
1895This object may be accessed either as a tuple of\n\
1896 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1897or via the attributes si_pid, si_uid, and so on.\n\
1898\n\
1899See os.waitid for more information.");
1900
1901static PyStructSequence_Field waitid_result_fields[] = {
1902 {"si_pid", },
1903 {"si_uid", },
1904 {"si_signo", },
1905 {"si_status", },
1906 {"si_code", },
1907 {0}
1908};
1909
1910static PyStructSequence_Desc waitid_result_desc = {
1911 "waitid_result", /* name */
1912 waitid_result__doc__, /* doc */
1913 waitid_result_fields,
1914 5
1915};
1916static PyTypeObject WaitidResultType;
1917#endif
1918
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001919static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001920static PyTypeObject StatResultType;
1921static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001922#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001923static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001924#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001925static newfunc structseq_new;
1926
1927static PyObject *
1928statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1929{
Victor Stinner8c62be82010-05-06 00:08:46 +00001930 PyStructSequence *result;
1931 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001932
Victor Stinner8c62be82010-05-06 00:08:46 +00001933 result = (PyStructSequence*)structseq_new(type, args, kwds);
1934 if (!result)
1935 return NULL;
1936 /* If we have been initialized from a tuple,
1937 st_?time might be set to None. Initialize it
1938 from the int slots. */
1939 for (i = 7; i <= 9; i++) {
1940 if (result->ob_item[i+3] == Py_None) {
1941 Py_DECREF(Py_None);
1942 Py_INCREF(result->ob_item[i]);
1943 result->ob_item[i+3] = result->ob_item[i];
1944 }
1945 }
1946 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001947}
1948
1949
1950
1951/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001952static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001953
1954PyDoc_STRVAR(stat_float_times__doc__,
1955"stat_float_times([newval]) -> oldval\n\n\
1956Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001957\n\
1958If value is True, future calls to stat() return floats; if it is False,\n\
1959future calls return ints.\n\
1960If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001961
Larry Hastings2f936352014-08-05 14:04:04 +10001962/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001963static PyObject*
1964stat_float_times(PyObject* self, PyObject *args)
1965{
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 int newval = -1;
1967 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1968 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001969 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1970 "stat_float_times() is deprecated",
1971 1))
1972 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001973 if (newval == -1)
1974 /* Return old value */
1975 return PyBool_FromLong(_stat_float_times);
1976 _stat_float_times = newval;
1977 Py_INCREF(Py_None);
1978 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001979}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001980
Larry Hastings6fe20b32012-04-19 15:07:49 -07001981static PyObject *billion = NULL;
1982
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001983static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001984fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001985{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001986 PyObject *s = _PyLong_FromTime_t(sec);
1987 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1988 PyObject *s_in_ns = NULL;
1989 PyObject *ns_total = NULL;
1990 PyObject *float_s = NULL;
1991
1992 if (!(s && ns_fractional))
1993 goto exit;
1994
1995 s_in_ns = PyNumber_Multiply(s, billion);
1996 if (!s_in_ns)
1997 goto exit;
1998
1999 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
2000 if (!ns_total)
2001 goto exit;
2002
Victor Stinner4195b5c2012-02-08 23:03:19 +01002003 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07002004 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
2005 if (!float_s)
2006 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07002008 else {
2009 float_s = s;
2010 Py_INCREF(float_s);
2011 }
2012
2013 PyStructSequence_SET_ITEM(v, index, s);
2014 PyStructSequence_SET_ITEM(v, index+3, float_s);
2015 PyStructSequence_SET_ITEM(v, index+6, ns_total);
2016 s = NULL;
2017 float_s = NULL;
2018 ns_total = NULL;
2019exit:
2020 Py_XDECREF(s);
2021 Py_XDECREF(ns_fractional);
2022 Py_XDECREF(s_in_ns);
2023 Py_XDECREF(ns_total);
2024 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002025}
2026
Tim Peters5aa91602002-01-30 05:46:57 +00002027/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002028 (used by posix_stat() and posix_fstat()) */
2029static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002030_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002031{
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 unsigned long ansec, mnsec, cnsec;
2033 PyObject *v = PyStructSequence_New(&StatResultType);
2034 if (v == NULL)
2035 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002036
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002038#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 PyStructSequence_SET_ITEM(v, 1,
2040 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002041#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002043#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002044#ifdef MS_WINDOWS
2045 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002046#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002047 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002048#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002049 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002050#if defined(MS_WINDOWS)
2051 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2052 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2053#else
2054 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2055 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2056#endif
Fred Drake699f3522000-06-29 21:12:41 +00002057#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 PyStructSequence_SET_ITEM(v, 6,
2059 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002060#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002062#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002063
Martin v. Löwis14694662006-02-03 12:54:16 +00002064#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 ansec = st->st_atim.tv_nsec;
2066 mnsec = st->st_mtim.tv_nsec;
2067 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002068#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 ansec = st->st_atimespec.tv_nsec;
2070 mnsec = st->st_mtimespec.tv_nsec;
2071 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002072#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 ansec = st->st_atime_nsec;
2074 mnsec = st->st_mtime_nsec;
2075 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002077 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002078#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002079 fill_time(v, 7, st->st_atime, ansec);
2080 fill_time(v, 8, st->st_mtime, mnsec);
2081 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002082
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002083#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2085 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002086#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002087#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002088 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2089 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002090#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002091#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2093 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002094#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002095#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2097 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002098#endif
2099#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002101 PyObject *val;
2102 unsigned long bsec,bnsec;
2103 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002104#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002105 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002106#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002107 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002108#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002109 if (_stat_float_times) {
2110 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2111 } else {
2112 val = PyLong_FromLong((long)bsec);
2113 }
2114 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2115 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002116 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002117#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002118#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002119 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2120 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002121#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002122#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2123 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2124 PyLong_FromUnsignedLong(st->st_file_attributes));
2125#endif
Fred Drake699f3522000-06-29 21:12:41 +00002126
Victor Stinner8c62be82010-05-06 00:08:46 +00002127 if (PyErr_Occurred()) {
2128 Py_DECREF(v);
2129 return NULL;
2130 }
Fred Drake699f3522000-06-29 21:12:41 +00002131
Victor Stinner8c62be82010-05-06 00:08:46 +00002132 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002133}
2134
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002135/* POSIX methods */
2136
Guido van Rossum94f6f721999-01-06 18:42:14 +00002137
2138static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002139posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002140 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002141{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002142 STRUCT_STAT st;
2143 int result;
2144
2145#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2146 if (follow_symlinks_specified(function_name, follow_symlinks))
2147 return NULL;
2148#endif
2149
2150 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2151 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2152 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2153 return NULL;
2154
2155 Py_BEGIN_ALLOW_THREADS
2156 if (path->fd != -1)
2157 result = FSTAT(path->fd, &st);
2158 else
2159#ifdef MS_WINDOWS
2160 if (path->wide) {
2161 if (follow_symlinks)
2162 result = win32_stat_w(path->wide, &st);
2163 else
2164 result = win32_lstat_w(path->wide, &st);
2165 }
2166 else
2167#endif
2168#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2169 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2170 result = LSTAT(path->narrow, &st);
2171 else
2172#endif
2173#ifdef HAVE_FSTATAT
2174 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2175 result = fstatat(dir_fd, path->narrow, &st,
2176 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2177 else
2178#endif
2179 result = STAT(path->narrow, &st);
2180 Py_END_ALLOW_THREADS
2181
Victor Stinner292c8352012-10-30 02:17:38 +01002182 if (result != 0) {
2183 return path_error(path);
2184 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002185
2186 return _pystat_fromstructstat(&st);
2187}
2188
Larry Hastings2f936352014-08-05 14:04:04 +10002189/*[python input]
2190
2191for s in """
2192
2193FACCESSAT
2194FCHMODAT
2195FCHOWNAT
2196FSTATAT
2197LINKAT
2198MKDIRAT
2199MKFIFOAT
2200MKNODAT
2201OPENAT
2202READLINKAT
2203SYMLINKAT
2204UNLINKAT
2205
2206""".strip().split():
2207 s = s.strip()
2208 print("""
2209#ifdef HAVE_{s}
2210 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002211#else
Larry Hastings2f936352014-08-05 14:04:04 +10002212 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002213#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002214""".rstrip().format(s=s))
2215
2216for s in """
2217
2218FCHDIR
2219FCHMOD
2220FCHOWN
2221FDOPENDIR
2222FEXECVE
2223FPATHCONF
2224FSTATVFS
2225FTRUNCATE
2226
2227""".strip().split():
2228 s = s.strip()
2229 print("""
2230#ifdef HAVE_{s}
2231 #define PATH_HAVE_{s} 1
2232#else
2233 #define PATH_HAVE_{s} 0
2234#endif
2235
2236""".rstrip().format(s=s))
2237[python start generated code]*/
2238
2239#ifdef HAVE_FACCESSAT
2240 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2241#else
2242 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2243#endif
2244
2245#ifdef HAVE_FCHMODAT
2246 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_FCHOWNAT
2252 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_FSTATAT
2258 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_LINKAT
2264 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_MKDIRAT
2270 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2271#else
2272 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2273#endif
2274
2275#ifdef HAVE_MKFIFOAT
2276 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2277#else
2278 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2279#endif
2280
2281#ifdef HAVE_MKNODAT
2282 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2283#else
2284 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2285#endif
2286
2287#ifdef HAVE_OPENAT
2288 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2289#else
2290 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2291#endif
2292
2293#ifdef HAVE_READLINKAT
2294 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2295#else
2296 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2297#endif
2298
2299#ifdef HAVE_SYMLINKAT
2300 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2301#else
2302 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2303#endif
2304
2305#ifdef HAVE_UNLINKAT
2306 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2307#else
2308 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2309#endif
2310
2311#ifdef HAVE_FCHDIR
2312 #define PATH_HAVE_FCHDIR 1
2313#else
2314 #define PATH_HAVE_FCHDIR 0
2315#endif
2316
2317#ifdef HAVE_FCHMOD
2318 #define PATH_HAVE_FCHMOD 1
2319#else
2320 #define PATH_HAVE_FCHMOD 0
2321#endif
2322
2323#ifdef HAVE_FCHOWN
2324 #define PATH_HAVE_FCHOWN 1
2325#else
2326 #define PATH_HAVE_FCHOWN 0
2327#endif
2328
2329#ifdef HAVE_FDOPENDIR
2330 #define PATH_HAVE_FDOPENDIR 1
2331#else
2332 #define PATH_HAVE_FDOPENDIR 0
2333#endif
2334
2335#ifdef HAVE_FEXECVE
2336 #define PATH_HAVE_FEXECVE 1
2337#else
2338 #define PATH_HAVE_FEXECVE 0
2339#endif
2340
2341#ifdef HAVE_FPATHCONF
2342 #define PATH_HAVE_FPATHCONF 1
2343#else
2344 #define PATH_HAVE_FPATHCONF 0
2345#endif
2346
2347#ifdef HAVE_FSTATVFS
2348 #define PATH_HAVE_FSTATVFS 1
2349#else
2350 #define PATH_HAVE_FSTATVFS 0
2351#endif
2352
2353#ifdef HAVE_FTRUNCATE
2354 #define PATH_HAVE_FTRUNCATE 1
2355#else
2356 #define PATH_HAVE_FTRUNCATE 0
2357#endif
2358/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002359
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002360#ifdef MS_WINDOWS
2361 #undef PATH_HAVE_FTRUNCATE
2362 #define PATH_HAVE_FTRUNCATE 1
2363#endif
Larry Hastings31826802013-10-19 00:09:25 -07002364
Larry Hastings61272b72014-01-07 12:41:53 -08002365/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002366
2367class path_t_converter(CConverter):
2368
2369 type = "path_t"
2370 impl_by_reference = True
2371 parse_by_reference = True
2372
2373 converter = 'path_converter'
2374
2375 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002376 # right now path_t doesn't support default values.
2377 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002378 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002379 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings2f936352014-08-05 14:04:04 +10002381 if self.c_default not in (None, 'Py_None'):
2382 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002383
2384 self.nullable = nullable
2385 self.allow_fd = allow_fd
2386
Larry Hastings7726ac92014-01-31 22:03:12 -08002387 def pre_render(self):
2388 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002389 if isinstance(value, str):
2390 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002391 return str(int(bool(value)))
2392
2393 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002394 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002395 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002396 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002397 strify(self.nullable),
2398 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002399 )
2400
2401 def cleanup(self):
2402 return "path_cleanup(&" + self.name + ");\n"
2403
2404
2405class dir_fd_converter(CConverter):
2406 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002407
Larry Hastings2f936352014-08-05 14:04:04 +10002408 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002409 if self.default in (unspecified, None):
2410 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002411 if isinstance(requires, str):
2412 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2413 else:
2414 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002415
Larry Hastings2f936352014-08-05 14:04:04 +10002416class fildes_converter(CConverter):
2417 type = 'int'
2418 converter = 'fildes_converter'
2419
2420class uid_t_converter(CConverter):
2421 type = "uid_t"
2422 converter = '_Py_Uid_Converter'
2423
2424class gid_t_converter(CConverter):
2425 type = "gid_t"
2426 converter = '_Py_Gid_Converter'
2427
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002428class dev_t_converter(CConverter):
2429 type = 'dev_t'
2430 converter = '_Py_Dev_Converter'
2431
2432class dev_t_return_converter(unsigned_long_return_converter):
2433 type = 'dev_t'
2434 conversion_fn = '_PyLong_FromDev'
2435 unsigned_cast = '(dev_t)'
2436
Larry Hastings2f936352014-08-05 14:04:04 +10002437class FSConverter_converter(CConverter):
2438 type = 'PyObject *'
2439 converter = 'PyUnicode_FSConverter'
2440 def converter_init(self):
2441 if self.default is not unspecified:
2442 fail("FSConverter_converter does not support default values")
2443 self.c_default = 'NULL'
2444
2445 def cleanup(self):
2446 return "Py_XDECREF(" + self.name + ");\n"
2447
2448class pid_t_converter(CConverter):
2449 type = 'pid_t'
2450 format_unit = '" _Py_PARSE_PID "'
2451
2452class idtype_t_converter(int_converter):
2453 type = 'idtype_t'
2454
2455class id_t_converter(CConverter):
2456 type = 'id_t'
2457 format_unit = '" _Py_PARSE_PID "'
2458
2459class Py_intptr_t_converter(CConverter):
2460 type = 'Py_intptr_t'
2461 format_unit = '" _Py_PARSE_INTPTR "'
2462
2463class Py_off_t_converter(CConverter):
2464 type = 'Py_off_t'
2465 converter = 'Py_off_t_converter'
2466
2467class Py_off_t_return_converter(long_return_converter):
2468 type = 'Py_off_t'
2469 conversion_fn = 'PyLong_FromPy_off_t'
2470
2471class path_confname_converter(CConverter):
2472 type="int"
2473 converter="conv_path_confname"
2474
2475class confstr_confname_converter(path_confname_converter):
2476 converter='conv_confstr_confname'
2477
2478class sysconf_confname_converter(path_confname_converter):
2479 converter="conv_sysconf_confname"
2480
2481class sched_param_converter(CConverter):
2482 type = 'struct sched_param'
2483 converter = 'convert_sched_param'
2484 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002485
Larry Hastings61272b72014-01-07 12:41:53 -08002486[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002487/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002488
Larry Hastings61272b72014-01-07 12:41:53 -08002489/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002490
Larry Hastings2a727912014-01-16 11:32:01 -08002491os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002492
2493 path : path_t(allow_fd=True)
2494 Path to be examined; can be string, bytes, or open-file-descriptor int.
2495
2496 *
2497
Larry Hastings2f936352014-08-05 14:04:04 +10002498 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002499 If not None, it should be a file descriptor open to a directory,
2500 and path should be a relative string; path will then be relative to
2501 that directory.
2502
2503 follow_symlinks: bool = True
2504 If False, and the last element of the path is a symbolic link,
2505 stat will examine the symbolic link itself instead of the file
2506 the link points to.
2507
2508Perform a stat system call on the given path.
2509
2510dir_fd and follow_symlinks may not be implemented
2511 on your platform. If they are unavailable, using them will raise a
2512 NotImplementedError.
2513
2514It's an error to use dir_fd or follow_symlinks when specifying path as
2515 an open file descriptor.
2516
Larry Hastings61272b72014-01-07 12:41:53 -08002517[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002518
Larry Hastings31826802013-10-19 00:09:25 -07002519static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002520os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2521/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002522{
2523 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2524}
2525
Larry Hastings2f936352014-08-05 14:04:04 +10002526
2527/*[clinic input]
2528os.lstat
2529
2530 path : path_t
2531
2532 *
2533
2534 dir_fd : dir_fd(requires='fstatat') = None
2535
2536Perform a stat system call on the given path, without following symbolic links.
2537
2538Like stat(), but do not follow symbolic links.
2539Equivalent to stat(path, follow_symlinks=False).
2540[clinic start generated code]*/
2541
Larry Hastings2f936352014-08-05 14:04:04 +10002542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002543os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2544/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002545{
2546 int follow_symlinks = 0;
2547 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2548}
Larry Hastings31826802013-10-19 00:09:25 -07002549
Larry Hastings2f936352014-08-05 14:04:04 +10002550
Larry Hastings61272b72014-01-07 12:41:53 -08002551/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002552os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002553
2554 path: path_t(allow_fd=True)
2555 Path to be tested; can be string, bytes, or open-file-descriptor int.
2556
2557 mode: int
2558 Operating-system mode bitfield. Can be F_OK to test existence,
2559 or the inclusive-OR of R_OK, W_OK, and X_OK.
2560
2561 *
2562
Larry Hastings2f936352014-08-05 14:04:04 +10002563 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002564 If not None, it should be a file descriptor open to a directory,
2565 and path should be relative; path will then be relative to that
2566 directory.
2567
2568 effective_ids: bool = False
2569 If True, access will use the effective uid/gid instead of
2570 the real uid/gid.
2571
2572 follow_symlinks: bool = True
2573 If False, and the last element of the path is a symbolic link,
2574 access will examine the symbolic link itself instead of the file
2575 the link points to.
2576
2577Use the real uid/gid to test for access to a path.
2578
2579{parameters}
2580dir_fd, effective_ids, and follow_symlinks may not be implemented
2581 on your platform. If they are unavailable, using them will raise a
2582 NotImplementedError.
2583
2584Note that most operations will use the effective uid/gid, therefore this
2585 routine can be used in a suid/sgid environment to test if the invoking user
2586 has the specified access to the path.
2587
Larry Hastings61272b72014-01-07 12:41:53 -08002588[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002589
Larry Hastings2f936352014-08-05 14:04:04 +10002590static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002591os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002592 int effective_ids, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002593/*[clinic end generated code: output=cf84158bc90b1a77 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002594{
Larry Hastings2f936352014-08-05 14:04:04 +10002595 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002596
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002597#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002598 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002599#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002600 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002601#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002602
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603#ifndef HAVE_FACCESSAT
2604 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002605 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002606
2607 if (effective_ids) {
2608 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002609 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610 }
2611#endif
2612
2613#ifdef MS_WINDOWS
2614 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002615 if (path->wide != NULL)
2616 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002618 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619 Py_END_ALLOW_THREADS
2620
2621 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002622 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 * * we didn't get a -1, and
2624 * * write access wasn't requested,
2625 * * or the file isn't read-only,
2626 * * or it's a directory.
2627 * (Directories cannot be read-only on Windows.)
2628 */
Larry Hastings2f936352014-08-05 14:04:04 +10002629 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002630 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002631 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002632 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002633#else
2634
2635 Py_BEGIN_ALLOW_THREADS
2636#ifdef HAVE_FACCESSAT
2637 if ((dir_fd != DEFAULT_DIR_FD) ||
2638 effective_ids ||
2639 !follow_symlinks) {
2640 int flags = 0;
2641 if (!follow_symlinks)
2642 flags |= AT_SYMLINK_NOFOLLOW;
2643 if (effective_ids)
2644 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002645 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002646 }
2647 else
2648#endif
Larry Hastings31826802013-10-19 00:09:25 -07002649 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002650 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002651 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002652#endif
2653
Larry Hastings9cf065c2012-06-22 16:30:09 -07002654 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002655}
2656
Guido van Rossumd371ff11999-01-25 16:12:23 +00002657#ifndef F_OK
2658#define F_OK 0
2659#endif
2660#ifndef R_OK
2661#define R_OK 4
2662#endif
2663#ifndef W_OK
2664#define W_OK 2
2665#endif
2666#ifndef X_OK
2667#define X_OK 1
2668#endif
2669
Larry Hastings31826802013-10-19 00:09:25 -07002670
Guido van Rossumd371ff11999-01-25 16:12:23 +00002671#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002672/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002673os.ttyname -> DecodeFSDefault
2674
2675 fd: int
2676 Integer file descriptor handle.
2677
2678 /
2679
2680Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002681[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002682
Larry Hastings31826802013-10-19 00:09:25 -07002683static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002684os_ttyname_impl(PyObject *module, int fd)
2685/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002686{
2687 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002688
Larry Hastings31826802013-10-19 00:09:25 -07002689 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002690 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002691 posix_error();
2692 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002693}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002694#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002695
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002696#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002697/*[clinic input]
2698os.ctermid
2699
2700Return the name of the controlling terminal for this process.
2701[clinic start generated code]*/
2702
Larry Hastings2f936352014-08-05 14:04:04 +10002703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002704os_ctermid_impl(PyObject *module)
2705/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002706{
Victor Stinner8c62be82010-05-06 00:08:46 +00002707 char *ret;
2708 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002709
Greg Wardb48bc172000-03-01 21:51:56 +00002710#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002711 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002712#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002713 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002714#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002715 if (ret == NULL)
2716 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002717 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002718}
Larry Hastings2f936352014-08-05 14:04:04 +10002719#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002720
Larry Hastings2f936352014-08-05 14:04:04 +10002721
2722/*[clinic input]
2723os.chdir
2724
2725 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2726
2727Change the current working directory to the specified path.
2728
2729path may always be specified as a string.
2730On some platforms, path may also be specified as an open file descriptor.
2731 If this functionality is unavailable, using it raises an exception.
2732[clinic start generated code]*/
2733
Larry Hastings2f936352014-08-05 14:04:04 +10002734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002735os_chdir_impl(PyObject *module, path_t *path)
2736/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002737{
2738 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002739
2740 Py_BEGIN_ALLOW_THREADS
2741#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002742 if (path->wide)
2743 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002744 else
Larry Hastings2f936352014-08-05 14:04:04 +10002745 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002746 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002747#else
2748#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002749 if (path->fd != -1)
2750 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002751 else
2752#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002753 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002754#endif
2755 Py_END_ALLOW_THREADS
2756
2757 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002758 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002759 }
2760
Larry Hastings2f936352014-08-05 14:04:04 +10002761 Py_RETURN_NONE;
2762}
2763
2764
2765#ifdef HAVE_FCHDIR
2766/*[clinic input]
2767os.fchdir
2768
2769 fd: fildes
2770
2771Change to the directory of the given file descriptor.
2772
2773fd must be opened on a directory, not a file.
2774Equivalent to os.chdir(fd).
2775
2776[clinic start generated code]*/
2777
Fred Drake4d1e64b2002-04-15 19:40:07 +00002778static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002779os_fchdir_impl(PyObject *module, int fd)
2780/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002781{
Larry Hastings2f936352014-08-05 14:04:04 +10002782 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002783}
2784#endif /* HAVE_FCHDIR */
2785
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002786
Larry Hastings2f936352014-08-05 14:04:04 +10002787/*[clinic input]
2788os.chmod
2789
2790 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2791 Path to be modified. May always be specified as a str or bytes.
2792 On some platforms, path may also be specified as an open file descriptor.
2793 If this functionality is unavailable, using it raises an exception.
2794
2795 mode: int
2796 Operating-system mode bitfield.
2797
2798 *
2799
2800 dir_fd : dir_fd(requires='fchmodat') = None
2801 If not None, it should be a file descriptor open to a directory,
2802 and path should be relative; path will then be relative to that
2803 directory.
2804
2805 follow_symlinks: bool = True
2806 If False, and the last element of the path is a symbolic link,
2807 chmod will modify the symbolic link itself instead of the file
2808 the link points to.
2809
2810Change the access permissions of a file.
2811
2812It is an error to use dir_fd or follow_symlinks when specifying path as
2813 an open file descriptor.
2814dir_fd and follow_symlinks may not be implemented on your platform.
2815 If they are unavailable, using them will raise a NotImplementedError.
2816
2817[clinic start generated code]*/
2818
Larry Hastings2f936352014-08-05 14:04:04 +10002819static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002820os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002821 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002822/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002823{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002825
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002826#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002827 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002829
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830#ifdef HAVE_FCHMODAT
2831 int fchmodat_nofollow_unsupported = 0;
2832#endif
2833
Larry Hastings9cf065c2012-06-22 16:30:09 -07002834#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2835 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002836 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837#endif
2838
2839#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002840 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002841 if (path->wide)
2842 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002843 else
Larry Hastings2f936352014-08-05 14:04:04 +10002844 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002845 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002846 result = 0;
2847 else {
2848 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002849 attr &= ~FILE_ATTRIBUTE_READONLY;
2850 else
2851 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002852 if (path->wide)
2853 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854 else
Larry Hastings2f936352014-08-05 14:04:04 +10002855 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002856 }
2857 Py_END_ALLOW_THREADS
2858
2859 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002860 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861 }
2862#else /* MS_WINDOWS */
2863 Py_BEGIN_ALLOW_THREADS
2864#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002865 if (path->fd != -1)
2866 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002867 else
2868#endif
2869#ifdef HAVE_LCHMOD
2870 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002871 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872 else
2873#endif
2874#ifdef HAVE_FCHMODAT
2875 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2876 /*
2877 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2878 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002879 * and then says it isn't implemented yet.
2880 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002881 *
2882 * Once it is supported, os.chmod will automatically
2883 * support dir_fd and follow_symlinks=False. (Hopefully.)
2884 * Until then, we need to be careful what exception we raise.
2885 */
Larry Hastings2f936352014-08-05 14:04:04 +10002886 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2888 /*
2889 * But wait! We can't throw the exception without allowing threads,
2890 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2891 */
2892 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002893 result &&
2894 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2895 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002896 }
2897 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002898#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002899 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002900 Py_END_ALLOW_THREADS
2901
2902 if (result) {
2903#ifdef HAVE_FCHMODAT
2904 if (fchmodat_nofollow_unsupported) {
2905 if (dir_fd != DEFAULT_DIR_FD)
2906 dir_fd_and_follow_symlinks_invalid("chmod",
2907 dir_fd, follow_symlinks);
2908 else
2909 follow_symlinks_specified("chmod", follow_symlinks);
2910 }
2911 else
2912#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002913 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002914 }
2915#endif
2916
Larry Hastings2f936352014-08-05 14:04:04 +10002917 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002918}
2919
Larry Hastings9cf065c2012-06-22 16:30:09 -07002920
Christian Heimes4e30a842007-11-30 22:12:06 +00002921#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002922/*[clinic input]
2923os.fchmod
2924
2925 fd: int
2926 mode: int
2927
2928Change the access permissions of the file given by file descriptor fd.
2929
2930Equivalent to os.chmod(fd, mode).
2931[clinic start generated code]*/
2932
Larry Hastings2f936352014-08-05 14:04:04 +10002933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002934os_fchmod_impl(PyObject *module, int fd, int mode)
2935/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002936{
2937 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002938 int async_err = 0;
2939
2940 do {
2941 Py_BEGIN_ALLOW_THREADS
2942 res = fchmod(fd, mode);
2943 Py_END_ALLOW_THREADS
2944 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2945 if (res != 0)
2946 return (!async_err) ? posix_error() : NULL;
2947
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002949}
2950#endif /* HAVE_FCHMOD */
2951
Larry Hastings2f936352014-08-05 14:04:04 +10002952
Christian Heimes4e30a842007-11-30 22:12:06 +00002953#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002954/*[clinic input]
2955os.lchmod
2956
2957 path: path_t
2958 mode: int
2959
2960Change the access permissions of a file, without following symbolic links.
2961
2962If path is a symlink, this affects the link itself rather than the target.
2963Equivalent to chmod(path, mode, follow_symlinks=False)."
2964[clinic start generated code]*/
2965
Larry Hastings2f936352014-08-05 14:04:04 +10002966static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002967os_lchmod_impl(PyObject *module, path_t *path, int mode)
2968/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002969{
Victor Stinner8c62be82010-05-06 00:08:46 +00002970 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002971 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002972 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002973 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002974 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002975 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002976 return NULL;
2977 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002979}
2980#endif /* HAVE_LCHMOD */
2981
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002982
Thomas Wouterscf297e42007-02-23 15:07:44 +00002983#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002984/*[clinic input]
2985os.chflags
2986
2987 path: path_t
2988 flags: unsigned_long(bitwise=True)
2989 follow_symlinks: bool=True
2990
2991Set file flags.
2992
2993If follow_symlinks is False, and the last element of the path is a symbolic
2994 link, chflags will change flags on the symbolic link itself instead of the
2995 file the link points to.
2996follow_symlinks may not be implemented on your platform. If it is
2997unavailable, using it will raise a NotImplementedError.
2998
2999[clinic start generated code]*/
3000
Larry Hastings2f936352014-08-05 14:04:04 +10003001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003002os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04003003 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003004/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003005{
3006 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003007
3008#ifndef HAVE_LCHFLAGS
3009 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003010 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003011#endif
3012
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003014#ifdef HAVE_LCHFLAGS
3015 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10003016 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003017 else
3018#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003019 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003021
Larry Hastings2f936352014-08-05 14:04:04 +10003022 if (result)
3023 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003024
Larry Hastings2f936352014-08-05 14:04:04 +10003025 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003026}
3027#endif /* HAVE_CHFLAGS */
3028
Larry Hastings2f936352014-08-05 14:04:04 +10003029
Thomas Wouterscf297e42007-02-23 15:07:44 +00003030#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003031/*[clinic input]
3032os.lchflags
3033
3034 path: path_t
3035 flags: unsigned_long(bitwise=True)
3036
3037Set file flags.
3038
3039This function will not follow symbolic links.
3040Equivalent to chflags(path, flags, follow_symlinks=False).
3041[clinic start generated code]*/
3042
Larry Hastings2f936352014-08-05 14:04:04 +10003043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003044os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3045/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003046{
Victor Stinner8c62be82010-05-06 00:08:46 +00003047 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003048 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003049 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003050 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003051 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003052 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003053 }
Victor Stinner292c8352012-10-30 02:17:38 +01003054 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003055}
3056#endif /* HAVE_LCHFLAGS */
3057
Larry Hastings2f936352014-08-05 14:04:04 +10003058
Martin v. Löwis244edc82001-10-04 22:44:26 +00003059#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003060/*[clinic input]
3061os.chroot
3062 path: path_t
3063
3064Change root directory to path.
3065
3066[clinic start generated code]*/
3067
Larry Hastings2f936352014-08-05 14:04:04 +10003068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003069os_chroot_impl(PyObject *module, path_t *path)
3070/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003071{
3072 int res;
3073 Py_BEGIN_ALLOW_THREADS
3074 res = chroot(path->narrow);
3075 Py_END_ALLOW_THREADS
3076 if (res < 0)
3077 return path_error(path);
3078 Py_RETURN_NONE;
3079}
3080#endif /* HAVE_CHROOT */
3081
Martin v. Löwis244edc82001-10-04 22:44:26 +00003082
Guido van Rossum21142a01999-01-08 21:05:37 +00003083#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003084/*[clinic input]
3085os.fsync
3086
3087 fd: fildes
3088
3089Force write of fd to disk.
3090[clinic start generated code]*/
3091
Larry Hastings2f936352014-08-05 14:04:04 +10003092static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003093os_fsync_impl(PyObject *module, int fd)
3094/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003095{
3096 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003097}
3098#endif /* HAVE_FSYNC */
3099
Larry Hastings2f936352014-08-05 14:04:04 +10003100
Ross Lagerwall7807c352011-03-17 20:20:30 +02003101#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003102/*[clinic input]
3103os.sync
3104
3105Force write of everything to disk.
3106[clinic start generated code]*/
3107
Larry Hastings2f936352014-08-05 14:04:04 +10003108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003109os_sync_impl(PyObject *module)
3110/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003111{
3112 Py_BEGIN_ALLOW_THREADS
3113 sync();
3114 Py_END_ALLOW_THREADS
3115 Py_RETURN_NONE;
3116}
Larry Hastings2f936352014-08-05 14:04:04 +10003117#endif /* HAVE_SYNC */
3118
Ross Lagerwall7807c352011-03-17 20:20:30 +02003119
Guido van Rossum21142a01999-01-08 21:05:37 +00003120#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003121#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003122extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3123#endif
3124
Larry Hastings2f936352014-08-05 14:04:04 +10003125/*[clinic input]
3126os.fdatasync
3127
3128 fd: fildes
3129
3130Force write of fd to disk without forcing update of metadata.
3131[clinic start generated code]*/
3132
Larry Hastings2f936352014-08-05 14:04:04 +10003133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003134os_fdatasync_impl(PyObject *module, int fd)
3135/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003136{
3137 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003138}
3139#endif /* HAVE_FDATASYNC */
3140
3141
Fredrik Lundh10723342000-07-10 16:38:09 +00003142#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003143/*[clinic input]
3144os.chown
3145
3146 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3147 Path to be examined; can be string, bytes, or open-file-descriptor int.
3148
3149 uid: uid_t
3150
3151 gid: gid_t
3152
3153 *
3154
3155 dir_fd : dir_fd(requires='fchownat') = None
3156 If not None, it should be a file descriptor open to a directory,
3157 and path should be relative; path will then be relative to that
3158 directory.
3159
3160 follow_symlinks: bool = True
3161 If False, and the last element of the path is a symbolic link,
3162 stat will examine the symbolic link itself instead of the file
3163 the link points to.
3164
3165Change the owner and group id of path to the numeric uid and gid.\
3166
3167path may always be specified as a string.
3168On some platforms, path may also be specified as an open file descriptor.
3169 If this functionality is unavailable, using it raises an exception.
3170If dir_fd is not None, it should be a file descriptor open to a directory,
3171 and path should be relative; path will then be relative to that directory.
3172If follow_symlinks is False, and the last element of the path is a symbolic
3173 link, chown will modify the symbolic link itself instead of the file the
3174 link points to.
3175It is an error to use dir_fd or follow_symlinks when specifying path as
3176 an open file descriptor.
3177dir_fd and follow_symlinks may not be implemented on your platform.
3178 If they are unavailable, using them will raise a NotImplementedError.
3179
3180[clinic start generated code]*/
3181
Larry Hastings2f936352014-08-05 14:04:04 +10003182static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003183os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003184 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003185/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003186{
3187 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188
3189#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3190 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003191 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003193 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3194 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3195 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196
3197#ifdef __APPLE__
3198 /*
3199 * This is for Mac OS X 10.3, which doesn't have lchown.
3200 * (But we still have an lchown symbol because of weak-linking.)
3201 * It doesn't have fchownat either. So there's no possibility
3202 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003203 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003204 if ((!follow_symlinks) && (lchown == NULL)) {
3205 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003206 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003207 }
3208#endif
3209
Victor Stinner8c62be82010-05-06 00:08:46 +00003210 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003211#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003212 if (path->fd != -1)
3213 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003214 else
3215#endif
3216#ifdef HAVE_LCHOWN
3217 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003218 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003219 else
3220#endif
3221#ifdef HAVE_FCHOWNAT
3222 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003223 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003224 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3225 else
3226#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003227 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003229
Larry Hastings2f936352014-08-05 14:04:04 +10003230 if (result)
3231 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003232
Larry Hastings2f936352014-08-05 14:04:04 +10003233 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003234}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003235#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003236
Larry Hastings2f936352014-08-05 14:04:04 +10003237
Christian Heimes4e30a842007-11-30 22:12:06 +00003238#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003239/*[clinic input]
3240os.fchown
3241
3242 fd: int
3243 uid: uid_t
3244 gid: gid_t
3245
3246Change the owner and group id of the file specified by file descriptor.
3247
3248Equivalent to os.chown(fd, uid, gid).
3249
3250[clinic start generated code]*/
3251
Larry Hastings2f936352014-08-05 14:04:04 +10003252static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003253os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3254/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003255{
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003257 int async_err = 0;
3258
3259 do {
3260 Py_BEGIN_ALLOW_THREADS
3261 res = fchown(fd, uid, gid);
3262 Py_END_ALLOW_THREADS
3263 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3264 if (res != 0)
3265 return (!async_err) ? posix_error() : NULL;
3266
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003268}
3269#endif /* HAVE_FCHOWN */
3270
Larry Hastings2f936352014-08-05 14:04:04 +10003271
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003272#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003273/*[clinic input]
3274os.lchown
3275
3276 path : path_t
3277 uid: uid_t
3278 gid: gid_t
3279
3280Change the owner and group id of path to the numeric uid and gid.
3281
3282This function will not follow symbolic links.
3283Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3284[clinic start generated code]*/
3285
Larry Hastings2f936352014-08-05 14:04:04 +10003286static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003287os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3288/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003289{
Victor Stinner8c62be82010-05-06 00:08:46 +00003290 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003292 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003294 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003295 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003296 }
Larry Hastings2f936352014-08-05 14:04:04 +10003297 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003298}
3299#endif /* HAVE_LCHOWN */
3300
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003301
Barry Warsaw53699e91996-12-10 23:23:01 +00003302static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003303posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003304{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003305 char *buf, *tmpbuf;
3306 char *cwd;
3307 const size_t chunk = 1024;
3308 size_t buflen = 0;
3309 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003310
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003311#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003313 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003314 wchar_t *wbuf2 = wbuf;
3315 PyObject *resobj;
3316 DWORD len;
3317 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003318 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003319 /* If the buffer is large enough, len does not include the
3320 terminating \0. If the buffer is too small, len includes
3321 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003322 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003323 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003324 if (wbuf2)
3325 len = GetCurrentDirectoryW(len, wbuf2);
3326 }
3327 Py_END_ALLOW_THREADS
3328 if (!wbuf2) {
3329 PyErr_NoMemory();
3330 return NULL;
3331 }
3332 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003333 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003334 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003335 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003336 }
3337 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003338 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003339 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 return resobj;
3341 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003342
3343 if (win32_warn_bytes_api())
3344 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003345#endif
3346
Victor Stinner4403d7d2015-04-25 00:16:10 +02003347 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003349 do {
3350 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003351#ifdef MS_WINDOWS
3352 if (buflen > INT_MAX) {
3353 PyErr_NoMemory();
3354 break;
3355 }
3356#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003357 tmpbuf = PyMem_RawRealloc(buf, buflen);
3358 if (tmpbuf == NULL)
3359 break;
3360
3361 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003362#ifdef MS_WINDOWS
3363 cwd = getcwd(buf, (int)buflen);
3364#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003365 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003366#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003367 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003368 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003369
3370 if (cwd == NULL) {
3371 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003372 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003373 }
3374
Victor Stinner8c62be82010-05-06 00:08:46 +00003375 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003376 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3377 else
3378 obj = PyUnicode_DecodeFSDefault(buf);
3379 PyMem_RawFree(buf);
3380
3381 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003382}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003383
Larry Hastings2f936352014-08-05 14:04:04 +10003384
3385/*[clinic input]
3386os.getcwd
3387
3388Return a unicode string representing the current working directory.
3389[clinic start generated code]*/
3390
Larry Hastings2f936352014-08-05 14:04:04 +10003391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003392os_getcwd_impl(PyObject *module)
3393/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003394{
3395 return posix_getcwd(0);
3396}
3397
Larry Hastings2f936352014-08-05 14:04:04 +10003398
3399/*[clinic input]
3400os.getcwdb
3401
3402Return a bytes string representing the current working directory.
3403[clinic start generated code]*/
3404
Larry Hastings2f936352014-08-05 14:04:04 +10003405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003406os_getcwdb_impl(PyObject *module)
3407/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003408{
3409 return posix_getcwd(1);
3410}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003411
Larry Hastings2f936352014-08-05 14:04:04 +10003412
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3414#define HAVE_LINK 1
3415#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003416
Guido van Rossumb6775db1994-08-01 11:34:53 +00003417#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003418/*[clinic input]
3419
3420os.link
3421
3422 src : path_t
3423 dst : path_t
3424 *
3425 src_dir_fd : dir_fd = None
3426 dst_dir_fd : dir_fd = None
3427 follow_symlinks: bool = True
3428
3429Create a hard link to a file.
3430
3431If either src_dir_fd or dst_dir_fd is not None, it should be a file
3432 descriptor open to a directory, and the respective path string (src or dst)
3433 should be relative; the path will then be relative to that directory.
3434If follow_symlinks is False, and the last element of src is a symbolic
3435 link, link will create a link to the symbolic link itself instead of the
3436 file the link points to.
3437src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3438 platform. If they are unavailable, using them will raise a
3439 NotImplementedError.
3440[clinic start generated code]*/
3441
Larry Hastings2f936352014-08-05 14:04:04 +10003442static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003443os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003444 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003445/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003446{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447#ifdef MS_WINDOWS
3448 BOOL result;
3449#else
3450 int result;
3451#endif
3452
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453#ifndef HAVE_LINKAT
3454 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3455 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003456 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 }
3458#endif
3459
Larry Hastings2f936352014-08-05 14:04:04 +10003460 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 PyErr_SetString(PyExc_NotImplementedError,
3462 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003463 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003465
Brian Curtin1b9df392010-11-24 20:24:31 +00003466#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003467 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003468 if (src->wide)
3469 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 else
Larry Hastings2f936352014-08-05 14:04:04 +10003471 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003473
Larry Hastings2f936352014-08-05 14:04:04 +10003474 if (!result)
3475 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476#else
3477 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003478#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003479 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3480 (dst_dir_fd != DEFAULT_DIR_FD) ||
3481 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003482 result = linkat(src_dir_fd, src->narrow,
3483 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3485 else
3486#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003487 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003488 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003489
Larry Hastings2f936352014-08-05 14:04:04 +10003490 if (result)
3491 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003492#endif
3493
Larry Hastings2f936352014-08-05 14:04:04 +10003494 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003495}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496#endif
3497
Brian Curtin1b9df392010-11-24 20:24:31 +00003498
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003499#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003500static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003501_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003502{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 PyObject *v;
3504 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3505 BOOL result;
3506 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003507 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003509 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511
Gregory P. Smith40a21602013-03-20 20:52:50 -07003512 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 WIN32_FIND_DATAW wFileData;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003514 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003515
Gregory P. Smith40a21602013-03-20 20:52:50 -07003516 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003517 po_wchars = L".";
3518 len = 1;
3519 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003520 po_wchars = path->wide;
3521 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003522 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003524 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 if (!wnamebuf) {
3526 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003529 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003531 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003532 if (wch != SEP && wch != ALTSEP && wch != L':')
3533 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 wcscpy(wnamebuf + len, L"*.*");
3535 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 if ((list = PyList_New(0)) == NULL) {
3537 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003539 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003541 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 if (hFindFile == INVALID_HANDLE_VALUE) {
3543 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 if (error == ERROR_FILE_NOT_FOUND)
3545 goto exit;
3546 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003547 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003549 }
3550 do {
3551 /* Skip over . and .. */
3552 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3553 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 v = PyUnicode_FromWideChar(wFileData.cFileName,
3555 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003557 Py_DECREF(list);
3558 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 break;
3560 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 Py_DECREF(list);
3564 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 break;
3566 }
3567 Py_DECREF(v);
3568 }
3569 Py_BEGIN_ALLOW_THREADS
3570 result = FindNextFileW(hFindFile, &wFileData);
3571 Py_END_ALLOW_THREADS
3572 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3573 it got to the end of the directory. */
3574 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003576 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 }
3579 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003580
Larry Hastings9cf065c2012-06-22 16:30:09 -07003581 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003583 strcpy(namebuf, path->narrow);
3584 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003585 if (len > 0) {
3586 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003587 if (ch != '\\' && ch != '/' && ch != ':')
3588 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 strcpy(namebuf + len, "*.*");
3590 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003591
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003594
Antoine Pitroub73caab2010-08-09 23:39:31 +00003595 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003596 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003597 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003598 if (hFindFile == INVALID_HANDLE_VALUE) {
3599 int error = GetLastError();
3600 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003601 goto exit;
3602 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 }
3606 do {
3607 /* Skip over . and .. */
3608 if (strcmp(FileData.cFileName, ".") != 0 &&
3609 strcmp(FileData.cFileName, "..") != 0) {
3610 v = PyBytes_FromString(FileData.cFileName);
3611 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003612 Py_DECREF(list);
3613 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003614 break;
3615 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003618 Py_DECREF(list);
3619 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 break;
3621 }
3622 Py_DECREF(v);
3623 }
3624 Py_BEGIN_ALLOW_THREADS
3625 result = FindNextFile(hFindFile, &FileData);
3626 Py_END_ALLOW_THREADS
3627 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3628 it got to the end of the directory. */
3629 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003631 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003633 }
3634 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003635
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636exit:
3637 if (hFindFile != INVALID_HANDLE_VALUE) {
3638 if (FindClose(hFindFile) == FALSE) {
3639 if (list != NULL) {
3640 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003641 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642 }
3643 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003644 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003645 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003646
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003648} /* end of _listdir_windows_no_opendir */
3649
3650#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3651
3652static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003653_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003654{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003655 PyObject *v;
3656 DIR *dirp = NULL;
3657 struct dirent *ep;
3658 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003659#ifdef HAVE_FDOPENDIR
3660 int fd = -1;
3661#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003662
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003665 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003666 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003667 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003668 if (fd == -1)
3669 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670
Larry Hastingsfdaea062012-06-25 04:42:23 -07003671 return_str = 1;
3672
Larry Hastings9cf065c2012-06-22 16:30:09 -07003673 Py_BEGIN_ALLOW_THREADS
3674 dirp = fdopendir(fd);
3675 Py_END_ALLOW_THREADS
3676 }
3677 else
3678#endif
3679 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003680 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003681 if (path->narrow) {
3682 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003683 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003684 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003685 }
3686 else {
3687 name = ".";
3688 return_str = 1;
3689 }
3690
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691 Py_BEGIN_ALLOW_THREADS
3692 dirp = opendir(name);
3693 Py_END_ALLOW_THREADS
3694 }
3695
3696 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003697 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003698#ifdef HAVE_FDOPENDIR
3699 if (fd != -1) {
3700 Py_BEGIN_ALLOW_THREADS
3701 close(fd);
3702 Py_END_ALLOW_THREADS
3703 }
3704#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003705 goto exit;
3706 }
3707 if ((list = PyList_New(0)) == NULL) {
3708 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 }
3710 for (;;) {
3711 errno = 0;
3712 Py_BEGIN_ALLOW_THREADS
3713 ep = readdir(dirp);
3714 Py_END_ALLOW_THREADS
3715 if (ep == NULL) {
3716 if (errno == 0) {
3717 break;
3718 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003719 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003720 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003722 }
3723 }
3724 if (ep->d_name[0] == '.' &&
3725 (NAMLEN(ep) == 1 ||
3726 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3727 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003728 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003729 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3730 else
3731 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003732 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003733 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003734 break;
3735 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003736 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003737 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003738 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003739 break;
3740 }
3741 Py_DECREF(v);
3742 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003743
Larry Hastings9cf065c2012-06-22 16:30:09 -07003744exit:
3745 if (dirp != NULL) {
3746 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003747#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003748 if (fd > -1)
3749 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003750#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003751 closedir(dirp);
3752 Py_END_ALLOW_THREADS
3753 }
3754
Larry Hastings9cf065c2012-06-22 16:30:09 -07003755 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003756} /* end of _posix_listdir */
3757#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003758
Larry Hastings2f936352014-08-05 14:04:04 +10003759
3760/*[clinic input]
3761os.listdir
3762
3763 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3764
3765Return a list containing the names of the files in the directory.
3766
3767path can be specified as either str or bytes. If path is bytes,
3768 the filenames returned will also be bytes; in all other circumstances
3769 the filenames returned will be str.
3770If path is None, uses the path='.'.
3771On some platforms, path may also be specified as an open file descriptor;\
3772 the file descriptor must refer to a directory.
3773 If this functionality is unavailable, using it raises NotImplementedError.
3774
3775The list is in arbitrary order. It does not include the special
3776entries '.' and '..' even if they are present in the directory.
3777
3778
3779[clinic start generated code]*/
3780
Larry Hastings2f936352014-08-05 14:04:04 +10003781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003782os_listdir_impl(PyObject *module, path_t *path)
3783/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003784{
3785#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3786 return _listdir_windows_no_opendir(path, NULL);
3787#else
3788 return _posix_listdir(path, NULL);
3789#endif
3790}
3791
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003792#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003793/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003794/*[clinic input]
3795os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003796
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003797 path: path_t
3798 /
3799
3800[clinic start generated code]*/
3801
3802static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003803os__getfullpathname_impl(PyObject *module, path_t *path)
3804/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003805{
3806 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003807 {
Victor Stinner75875072013-11-24 19:23:25 +01003808 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003809 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003810 DWORD result;
3811 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003812
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003813 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003814 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003815 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003816 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003817 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003818 if (!woutbufp)
3819 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003820 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003821 }
3822 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003823 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003824 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003825 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003826 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003827 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003828 return v;
3829 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003830 else {
3831 char outbuf[MAX_PATH];
3832 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003833
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003834 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3835 outbuf, &temp)) {
3836 win32_error_object("GetFullPathName", path->object);
3837 return NULL;
3838 }
3839 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003840 }
Larry Hastings2f936352014-08-05 14:04:04 +10003841}
Brian Curtind40e6f72010-07-08 21:39:08 +00003842
Brian Curtind25aef52011-06-13 15:16:04 -05003843
Larry Hastings2f936352014-08-05 14:04:04 +10003844/*[clinic input]
3845os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003846
Larry Hastings2f936352014-08-05 14:04:04 +10003847 path: unicode
3848 /
3849
3850A helper function for samepath on windows.
3851[clinic start generated code]*/
3852
Larry Hastings2f936352014-08-05 14:04:04 +10003853static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003854os__getfinalpathname_impl(PyObject *module, PyObject *path)
3855/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003856{
3857 HANDLE hFile;
3858 int buf_size;
3859 wchar_t *target_path;
3860 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003861 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003862 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003863
Larry Hastings2f936352014-08-05 14:04:04 +10003864 path_wchar = PyUnicode_AsUnicode(path);
3865 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003866 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003867
Brian Curtind40e6f72010-07-08 21:39:08 +00003868 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003869 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003870 0, /* desired access */
3871 0, /* share mode */
3872 NULL, /* security attributes */
3873 OPEN_EXISTING,
3874 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3875 FILE_FLAG_BACKUP_SEMANTICS,
3876 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003877
Victor Stinnereb5657a2011-09-30 01:44:27 +02003878 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003879 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003880
3881 /* We have a good handle to the target, use it to determine the
3882 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003883 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003884
3885 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003886 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003887
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003888 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003889 if(!target_path)
3890 return PyErr_NoMemory();
3891
Steve Dower2ea51c92015-03-20 21:49:12 -07003892 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3893 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003894 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003895 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003896
3897 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003898 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003899
3900 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003901 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003902 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003903 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003904}
Brian Curtin62857742010-09-06 17:07:27 +00003905
Brian Curtin95d028f2011-06-09 09:10:38 -05003906PyDoc_STRVAR(posix__isdir__doc__,
3907"Return true if the pathname refers to an existing directory.");
3908
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003909/*[clinic input]
3910os._isdir
3911
3912 path: path_t
3913 /
3914
3915[clinic start generated code]*/
3916
Brian Curtin9c669cc2011-06-08 18:17:18 -05003917static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003918os__isdir_impl(PyObject *module, path_t *path)
3919/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003920{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003921 DWORD attributes;
3922
Steve Dowerb22a6772016-07-17 20:49:38 -07003923 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003924 if (!path->narrow)
3925 attributes = GetFileAttributesW(path->wide);
3926 else
3927 attributes = GetFileAttributesA(path->narrow);
Steve Dowerb22a6772016-07-17 20:49:38 -07003928 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003929
Brian Curtin9c669cc2011-06-08 18:17:18 -05003930 if (attributes == INVALID_FILE_ATTRIBUTES)
3931 Py_RETURN_FALSE;
3932
Brian Curtin9c669cc2011-06-08 18:17:18 -05003933 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3934 Py_RETURN_TRUE;
3935 else
3936 Py_RETURN_FALSE;
3937}
Tim Golden6b528062013-08-01 12:44:00 +01003938
Tim Golden6b528062013-08-01 12:44:00 +01003939
Larry Hastings2f936352014-08-05 14:04:04 +10003940/*[clinic input]
3941os._getvolumepathname
3942
3943 path: unicode
3944
3945A helper function for ismount on Win32.
3946[clinic start generated code]*/
3947
Larry Hastings2f936352014-08-05 14:04:04 +10003948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003949os__getvolumepathname_impl(PyObject *module, PyObject *path)
3950/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003951{
3952 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003953 const wchar_t *path_wchar;
3954 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003955 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003956 BOOL ret;
3957
Larry Hastings2f936352014-08-05 14:04:04 +10003958 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3959 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003960 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003961 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003962
3963 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003964 buflen = Py_MAX(buflen, MAX_PATH);
3965
3966 if (buflen > DWORD_MAX) {
3967 PyErr_SetString(PyExc_OverflowError, "path too long");
3968 return NULL;
3969 }
3970
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003971 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003972 if (mountpath == NULL)
3973 return PyErr_NoMemory();
3974
3975 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003976 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003977 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003978 Py_END_ALLOW_THREADS
3979
3980 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003981 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003982 goto exit;
3983 }
3984 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3985
3986exit:
3987 PyMem_Free(mountpath);
3988 return result;
3989}
Tim Golden6b528062013-08-01 12:44:00 +01003990
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003991#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003992
Larry Hastings2f936352014-08-05 14:04:04 +10003993
3994/*[clinic input]
3995os.mkdir
3996
3997 path : path_t
3998
3999 mode: int = 0o777
4000
4001 *
4002
4003 dir_fd : dir_fd(requires='mkdirat') = None
4004
4005# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
4006
4007Create a directory.
4008
4009If dir_fd is not None, it should be a file descriptor open to a directory,
4010 and path should be relative; path will then be relative to that directory.
4011dir_fd may not be implemented on your platform.
4012 If it is unavailable, using it will raise a NotImplementedError.
4013
4014The mode argument is ignored on Windows.
4015[clinic start generated code]*/
4016
Larry Hastings2f936352014-08-05 14:04:04 +10004017static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004018os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
4019/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004020{
4021 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004022
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004023#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004024 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004025 if (path->wide)
4026 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004027 else
Larry Hastings2f936352014-08-05 14:04:04 +10004028 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004030
Larry Hastings2f936352014-08-05 14:04:04 +10004031 if (!result)
4032 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004034 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004035#if HAVE_MKDIRAT
4036 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004037 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004038 else
4039#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004040#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004041 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004042#else
Larry Hastings2f936352014-08-05 14:04:04 +10004043 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004044#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004046 if (result < 0)
4047 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004048#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004049 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004050}
4051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004052
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004053/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4054#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004055#include <sys/resource.h>
4056#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004057
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004058
4059#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004060/*[clinic input]
4061os.nice
4062
4063 increment: int
4064 /
4065
4066Add increment to the priority of process and return the new priority.
4067[clinic start generated code]*/
4068
Larry Hastings2f936352014-08-05 14:04:04 +10004069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004070os_nice_impl(PyObject *module, int increment)
4071/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004072{
4073 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004074
Victor Stinner8c62be82010-05-06 00:08:46 +00004075 /* There are two flavours of 'nice': one that returns the new
4076 priority (as required by almost all standards out there) and the
4077 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4078 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004079
Victor Stinner8c62be82010-05-06 00:08:46 +00004080 If we are of the nice family that returns the new priority, we
4081 need to clear errno before the call, and check if errno is filled
4082 before calling posix_error() on a returnvalue of -1, because the
4083 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004084
Victor Stinner8c62be82010-05-06 00:08:46 +00004085 errno = 0;
4086 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004087#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004088 if (value == 0)
4089 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004090#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004091 if (value == -1 && errno != 0)
4092 /* either nice() or getpriority() returned an error */
4093 return posix_error();
4094 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004095}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004096#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004097
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004098
4099#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004100/*[clinic input]
4101os.getpriority
4102
4103 which: int
4104 who: int
4105
4106Return program scheduling priority.
4107[clinic start generated code]*/
4108
Larry Hastings2f936352014-08-05 14:04:04 +10004109static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004110os_getpriority_impl(PyObject *module, int which, int who)
4111/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004112{
4113 int retval;
4114
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004115 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004116 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004117 if (errno != 0)
4118 return posix_error();
4119 return PyLong_FromLong((long)retval);
4120}
4121#endif /* HAVE_GETPRIORITY */
4122
4123
4124#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004125/*[clinic input]
4126os.setpriority
4127
4128 which: int
4129 who: int
4130 priority: int
4131
4132Set program scheduling priority.
4133[clinic start generated code]*/
4134
Larry Hastings2f936352014-08-05 14:04:04 +10004135static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004136os_setpriority_impl(PyObject *module, int which, int who, int priority)
4137/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004138{
4139 int retval;
4140
4141 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004142 if (retval == -1)
4143 return posix_error();
4144 Py_RETURN_NONE;
4145}
4146#endif /* HAVE_SETPRIORITY */
4147
4148
Barry Warsaw53699e91996-12-10 23:23:01 +00004149static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004150internal_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 +00004151{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004152 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004153 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004155#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004156 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004157 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004158#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004159 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004160#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004161
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4163 (dst_dir_fd != DEFAULT_DIR_FD);
4164#ifndef HAVE_RENAMEAT
4165 if (dir_fd_specified) {
4166 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004167 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 }
4169#endif
4170
Larry Hastings2f936352014-08-05 14:04:04 +10004171 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172 PyErr_Format(PyExc_ValueError,
4173 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004174 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004175 }
4176
4177#ifdef MS_WINDOWS
4178 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004179 if (src->wide)
4180 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004181 else
Larry Hastings2f936352014-08-05 14:04:04 +10004182 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004183 Py_END_ALLOW_THREADS
4184
Larry Hastings2f936352014-08-05 14:04:04 +10004185 if (!result)
4186 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004187
4188#else
4189 Py_BEGIN_ALLOW_THREADS
4190#ifdef HAVE_RENAMEAT
4191 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004192 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004193 else
4194#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004195 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004196 Py_END_ALLOW_THREADS
4197
Larry Hastings2f936352014-08-05 14:04:04 +10004198 if (result)
4199 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004200#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004201 Py_RETURN_NONE;
4202}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004203
Larry Hastings2f936352014-08-05 14:04:04 +10004204
4205/*[clinic input]
4206os.rename
4207
4208 src : path_t
4209 dst : path_t
4210 *
4211 src_dir_fd : dir_fd = None
4212 dst_dir_fd : dir_fd = None
4213
4214Rename a file or directory.
4215
4216If either src_dir_fd or dst_dir_fd is not None, it should be a file
4217 descriptor open to a directory, and the respective path string (src or dst)
4218 should be relative; the path will then be relative to that directory.
4219src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4220 If they are unavailable, using them will raise a NotImplementedError.
4221[clinic start generated code]*/
4222
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004223static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004224os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004225 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004226/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004227{
Larry Hastings2f936352014-08-05 14:04:04 +10004228 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004229}
4230
Larry Hastings2f936352014-08-05 14:04:04 +10004231
4232/*[clinic input]
4233os.replace = os.rename
4234
4235Rename a file or directory, overwriting the destination.
4236
4237If either src_dir_fd or dst_dir_fd is not None, it should be a file
4238 descriptor open to a directory, and the respective path string (src or dst)
4239 should be relative; the path will then be relative to that directory.
4240src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4241 If they are unavailable, using them will raise a NotImplementedError."
4242[clinic start generated code]*/
4243
Larry Hastings2f936352014-08-05 14:04:04 +10004244static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004245os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4246 int dst_dir_fd)
4247/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004248{
4249 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4250}
4251
4252
4253/*[clinic input]
4254os.rmdir
4255
4256 path: path_t
4257 *
4258 dir_fd: dir_fd(requires='unlinkat') = None
4259
4260Remove a directory.
4261
4262If dir_fd is not None, it should be a file descriptor open to a directory,
4263 and path should be relative; path will then be relative to that directory.
4264dir_fd may not be implemented on your platform.
4265 If it is unavailable, using it will raise a NotImplementedError.
4266[clinic start generated code]*/
4267
Larry Hastings2f936352014-08-05 14:04:04 +10004268static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004269os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4270/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004271{
4272 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004273
4274 Py_BEGIN_ALLOW_THREADS
4275#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004276 if (path->wide)
4277 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004278 else
Larry Hastings2f936352014-08-05 14:04:04 +10004279 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004280 result = !result; /* Windows, success=1, UNIX, success=0 */
4281#else
4282#ifdef HAVE_UNLINKAT
4283 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004284 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004285 else
4286#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004287 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004288#endif
4289 Py_END_ALLOW_THREADS
4290
Larry Hastings2f936352014-08-05 14:04:04 +10004291 if (result)
4292 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004293
Larry Hastings2f936352014-08-05 14:04:04 +10004294 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004295}
4296
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004297
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004298#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004299#ifdef MS_WINDOWS
4300/*[clinic input]
4301os.system -> long
4302
4303 command: Py_UNICODE
4304
4305Execute the command in a subshell.
4306[clinic start generated code]*/
4307
Larry Hastings2f936352014-08-05 14:04:04 +10004308static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004309os_system_impl(PyObject *module, Py_UNICODE *command)
4310/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004311{
4312 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004313 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004314 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004315 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004316 return result;
4317}
4318#else /* MS_WINDOWS */
4319/*[clinic input]
4320os.system -> long
4321
4322 command: FSConverter
4323
4324Execute the command in a subshell.
4325[clinic start generated code]*/
4326
Larry Hastings2f936352014-08-05 14:04:04 +10004327static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004328os_system_impl(PyObject *module, PyObject *command)
4329/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004330{
4331 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004332 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004333 Py_BEGIN_ALLOW_THREADS
4334 result = system(bytes);
4335 Py_END_ALLOW_THREADS
4336 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004337}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004338#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004339#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004340
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004341
Larry Hastings2f936352014-08-05 14:04:04 +10004342/*[clinic input]
4343os.umask
4344
4345 mask: int
4346 /
4347
4348Set the current numeric umask and return the previous umask.
4349[clinic start generated code]*/
4350
Larry Hastings2f936352014-08-05 14:04:04 +10004351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004352os_umask_impl(PyObject *module, int mask)
4353/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004354{
4355 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004356 if (i < 0)
4357 return posix_error();
4358 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004359}
4360
Brian Curtind40e6f72010-07-08 21:39:08 +00004361#ifdef MS_WINDOWS
4362
4363/* override the default DeleteFileW behavior so that directory
4364symlinks can be removed with this function, the same as with
4365Unix symlinks */
4366BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4367{
4368 WIN32_FILE_ATTRIBUTE_DATA info;
4369 WIN32_FIND_DATAW find_data;
4370 HANDLE find_data_handle;
4371 int is_directory = 0;
4372 int is_link = 0;
4373
4374 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4375 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004376
Brian Curtind40e6f72010-07-08 21:39:08 +00004377 /* Get WIN32_FIND_DATA structure for the path to determine if
4378 it is a symlink */
4379 if(is_directory &&
4380 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4381 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4382
4383 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004384 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4385 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4386 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4387 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004388 FindClose(find_data_handle);
4389 }
4390 }
4391 }
4392
4393 if (is_directory && is_link)
4394 return RemoveDirectoryW(lpFileName);
4395
4396 return DeleteFileW(lpFileName);
4397}
4398#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004400
Larry Hastings2f936352014-08-05 14:04:04 +10004401/*[clinic input]
4402os.unlink
4403
4404 path: path_t
4405 *
4406 dir_fd: dir_fd(requires='unlinkat')=None
4407
4408Remove a file (same as remove()).
4409
4410If dir_fd is not None, it should be a file descriptor open to a directory,
4411 and path should be relative; path will then be relative to that directory.
4412dir_fd may not be implemented on your platform.
4413 If it is unavailable, using it will raise a NotImplementedError.
4414
4415[clinic start generated code]*/
4416
Larry Hastings2f936352014-08-05 14:04:04 +10004417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004418os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4419/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004420{
4421 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004422
4423 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004424 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004425#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004426 if (path->wide)
4427 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004428 else
Larry Hastings2f936352014-08-05 14:04:04 +10004429 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004430 result = !result; /* Windows, success=1, UNIX, success=0 */
4431#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004432#ifdef HAVE_UNLINKAT
4433 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004434 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004435 else
4436#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004437 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004438#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004439 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004440 Py_END_ALLOW_THREADS
4441
Larry Hastings2f936352014-08-05 14:04:04 +10004442 if (result)
4443 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004444
Larry Hastings2f936352014-08-05 14:04:04 +10004445 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004446}
4447
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004448
Larry Hastings2f936352014-08-05 14:04:04 +10004449/*[clinic input]
4450os.remove = os.unlink
4451
4452Remove a file (same as unlink()).
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[clinic start generated code]*/
4459
Larry Hastings2f936352014-08-05 14:04:04 +10004460static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004461os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4462/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004463{
4464 return os_unlink_impl(module, path, dir_fd);
4465}
4466
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004467
Larry Hastings605a62d2012-06-24 04:33:36 -07004468static PyStructSequence_Field uname_result_fields[] = {
4469 {"sysname", "operating system name"},
4470 {"nodename", "name of machine on network (implementation-defined)"},
4471 {"release", "operating system release"},
4472 {"version", "operating system version"},
4473 {"machine", "hardware identifier"},
4474 {NULL}
4475};
4476
4477PyDoc_STRVAR(uname_result__doc__,
4478"uname_result: Result from os.uname().\n\n\
4479This object may be accessed either as a tuple of\n\
4480 (sysname, nodename, release, version, machine),\n\
4481or via the attributes sysname, nodename, release, version, and machine.\n\
4482\n\
4483See os.uname for more information.");
4484
4485static PyStructSequence_Desc uname_result_desc = {
4486 "uname_result", /* name */
4487 uname_result__doc__, /* doc */
4488 uname_result_fields,
4489 5
4490};
4491
4492static PyTypeObject UnameResultType;
4493
4494
4495#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004496/*[clinic input]
4497os.uname
4498
4499Return an object identifying the current operating system.
4500
4501The object behaves like a named tuple with the following fields:
4502 (sysname, nodename, release, version, machine)
4503
4504[clinic start generated code]*/
4505
Larry Hastings2f936352014-08-05 14:04:04 +10004506static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004507os_uname_impl(PyObject *module)
4508/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004509{
Victor Stinner8c62be82010-05-06 00:08:46 +00004510 struct utsname u;
4511 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004512 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004513
Victor Stinner8c62be82010-05-06 00:08:46 +00004514 Py_BEGIN_ALLOW_THREADS
4515 res = uname(&u);
4516 Py_END_ALLOW_THREADS
4517 if (res < 0)
4518 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004519
4520 value = PyStructSequence_New(&UnameResultType);
4521 if (value == NULL)
4522 return NULL;
4523
4524#define SET(i, field) \
4525 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004526 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004527 if (!o) { \
4528 Py_DECREF(value); \
4529 return NULL; \
4530 } \
4531 PyStructSequence_SET_ITEM(value, i, o); \
4532 } \
4533
4534 SET(0, u.sysname);
4535 SET(1, u.nodename);
4536 SET(2, u.release);
4537 SET(3, u.version);
4538 SET(4, u.machine);
4539
4540#undef SET
4541
4542 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004543}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004544#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004545
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004546
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547
4548typedef struct {
4549 int now;
4550 time_t atime_s;
4551 long atime_ns;
4552 time_t mtime_s;
4553 long mtime_ns;
4554} utime_t;
4555
4556/*
Victor Stinner484df002014-10-09 13:52:31 +02004557 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558 * they also intentionally leak the declaration of a pointer named "time"
4559 */
4560#define UTIME_TO_TIMESPEC \
4561 struct timespec ts[2]; \
4562 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004563 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564 time = NULL; \
4565 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004566 ts[0].tv_sec = ut->atime_s; \
4567 ts[0].tv_nsec = ut->atime_ns; \
4568 ts[1].tv_sec = ut->mtime_s; \
4569 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570 time = ts; \
4571 } \
4572
4573#define UTIME_TO_TIMEVAL \
4574 struct timeval tv[2]; \
4575 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004576 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577 time = NULL; \
4578 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004579 tv[0].tv_sec = ut->atime_s; \
4580 tv[0].tv_usec = ut->atime_ns / 1000; \
4581 tv[1].tv_sec = ut->mtime_s; \
4582 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583 time = tv; \
4584 } \
4585
4586#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004587 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004589 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590 time = NULL; \
4591 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004592 u.actime = ut->atime_s; \
4593 u.modtime = ut->mtime_s; \
4594 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595 }
4596
4597#define UTIME_TO_TIME_T \
4598 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004599 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004600 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004601 time = NULL; \
4602 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004603 timet[0] = ut->atime_s; \
4604 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004605 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606 } \
4607
4608
Victor Stinner528a9ab2015-09-03 21:30:26 +02004609#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610
4611static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004612utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613{
4614#ifdef HAVE_UTIMENSAT
4615 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4616 UTIME_TO_TIMESPEC;
4617 return utimensat(dir_fd, path, time, flags);
4618#elif defined(HAVE_FUTIMESAT)
4619 UTIME_TO_TIMEVAL;
4620 /*
4621 * follow_symlinks will never be false here;
4622 * we only allow !follow_symlinks and dir_fd together
4623 * if we have utimensat()
4624 */
4625 assert(follow_symlinks);
4626 return futimesat(dir_fd, path, time);
4627#endif
4628}
4629
Larry Hastings2f936352014-08-05 14:04:04 +10004630 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4631#else
4632 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633#endif
4634
Victor Stinner528a9ab2015-09-03 21:30:26 +02004635#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004636
4637static int
Victor Stinner484df002014-10-09 13:52:31 +02004638utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639{
4640#ifdef HAVE_FUTIMENS
4641 UTIME_TO_TIMESPEC;
4642 return futimens(fd, time);
4643#else
4644 UTIME_TO_TIMEVAL;
4645 return futimes(fd, time);
4646#endif
4647}
4648
Larry Hastings2f936352014-08-05 14:04:04 +10004649 #define PATH_UTIME_HAVE_FD 1
4650#else
4651 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004652#endif
4653
Victor Stinner5ebae872015-09-22 01:29:33 +02004654#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4655# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4656#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004657
Victor Stinner4552ced2015-09-21 22:37:15 +02004658#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004659
4660static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004661utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004662{
4663#ifdef HAVE_UTIMENSAT
4664 UTIME_TO_TIMESPEC;
4665 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4666#else
4667 UTIME_TO_TIMEVAL;
4668 return lutimes(path, time);
4669#endif
4670}
4671
4672#endif
4673
4674#ifndef MS_WINDOWS
4675
4676static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004677utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004678{
4679#ifdef HAVE_UTIMENSAT
4680 UTIME_TO_TIMESPEC;
4681 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4682#elif defined(HAVE_UTIMES)
4683 UTIME_TO_TIMEVAL;
4684 return utimes(path, time);
4685#elif defined(HAVE_UTIME_H)
4686 UTIME_TO_UTIMBUF;
4687 return utime(path, time);
4688#else
4689 UTIME_TO_TIME_T;
4690 return utime(path, time);
4691#endif
4692}
4693
4694#endif
4695
Larry Hastings76ad59b2012-05-03 00:30:07 -07004696static int
4697split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4698{
4699 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004700 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004701 divmod = PyNumber_Divmod(py_long, billion);
4702 if (!divmod)
4703 goto exit;
4704 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4705 if ((*s == -1) && PyErr_Occurred())
4706 goto exit;
4707 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004708 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004709 goto exit;
4710
4711 result = 1;
4712exit:
4713 Py_XDECREF(divmod);
4714 return result;
4715}
4716
Larry Hastings2f936352014-08-05 14:04:04 +10004717
4718/*[clinic input]
4719os.utime
4720
4721 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4722 times: object = NULL
4723 *
4724 ns: object = NULL
4725 dir_fd: dir_fd(requires='futimensat') = None
4726 follow_symlinks: bool=True
4727
Martin Panter0ff89092015-09-09 01:56:53 +00004728# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004729
4730Set the access and modified time of path.
4731
4732path may always be specified as a string.
4733On some platforms, path may also be specified as an open file descriptor.
4734 If this functionality is unavailable, using it raises an exception.
4735
4736If times is not None, it must be a tuple (atime, mtime);
4737 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004738If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004739 atime_ns and mtime_ns should be expressed as integer nanoseconds
4740 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004741If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004742Specifying tuples for both times and ns is an error.
4743
4744If dir_fd is not None, it should be a file descriptor open to a directory,
4745 and path should be relative; path will then be relative to that directory.
4746If follow_symlinks is False, and the last element of the path is a symbolic
4747 link, utime will modify the symbolic link itself instead of the file the
4748 link points to.
4749It is an error to use dir_fd or follow_symlinks when specifying path
4750 as an open file descriptor.
4751dir_fd and follow_symlinks may not be available on your platform.
4752 If they are unavailable, using them will raise a NotImplementedError.
4753
4754[clinic start generated code]*/
4755
Larry Hastings2f936352014-08-05 14:04:04 +10004756static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004757os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4758 int dir_fd, int follow_symlinks)
4759/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004760{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761#ifdef MS_WINDOWS
4762 HANDLE hFile;
4763 FILETIME atime, mtime;
4764#else
4765 int result;
4766#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004767
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004769 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004770
Christian Heimesb3c87242013-08-01 00:08:16 +02004771 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004772
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 if (times && (times != Py_None) && ns) {
4774 PyErr_SetString(PyExc_ValueError,
4775 "utime: you may specify either 'times'"
4776 " or 'ns' but not both");
4777 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004778 }
4779
4780 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004781 time_t a_sec, m_sec;
4782 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004783 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784 PyErr_SetString(PyExc_TypeError,
4785 "utime: 'times' must be either"
4786 " a tuple of two ints or None");
4787 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004788 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004790 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004791 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004792 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004793 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004795 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004796 utime.atime_s = a_sec;
4797 utime.atime_ns = a_nsec;
4798 utime.mtime_s = m_sec;
4799 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004800 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004802 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 PyErr_SetString(PyExc_TypeError,
4804 "utime: 'ns' must be a tuple of two ints");
4805 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004806 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004808 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004810 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 &utime.mtime_s, &utime.mtime_ns)) {
4812 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004813 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814 }
4815 else {
4816 /* times and ns are both None/unspecified. use "now". */
4817 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004818 }
4819
Victor Stinner4552ced2015-09-21 22:37:15 +02004820#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821 if (follow_symlinks_specified("utime", follow_symlinks))
4822 goto exit;
4823#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004824
Larry Hastings2f936352014-08-05 14:04:04 +10004825 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4826 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4827 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004829
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830#if !defined(HAVE_UTIMENSAT)
4831 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004832 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833 "utime: cannot use dir_fd and follow_symlinks "
4834 "together on this platform");
4835 goto exit;
4836 }
4837#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004838
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004839#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004841 if (path->wide)
4842 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 NULL, OPEN_EXISTING,
4844 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845 else
Larry Hastings2f936352014-08-05 14:04:04 +10004846 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004847 NULL, OPEN_EXISTING,
4848 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004849 Py_END_ALLOW_THREADS
4850 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004851 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004853 }
4854
Larry Hastings9cf065c2012-06-22 16:30:09 -07004855 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004856 GetSystemTimeAsFileTime(&mtime);
4857 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004858 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004860 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4861 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004862 }
4863 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4864 /* Avoid putting the file name into the error here,
4865 as that may confuse the user into believing that
4866 something is wrong with the file, when it also
4867 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004868 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004869 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004870 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004871#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004872 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004873
Victor Stinner4552ced2015-09-21 22:37:15 +02004874#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004876 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004877 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004878#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004879
Victor Stinner528a9ab2015-09-03 21:30:26 +02004880#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004881 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004882 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004883 else
4884#endif
4885
Victor Stinner528a9ab2015-09-03 21:30:26 +02004886#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004887 if (path->fd != -1)
4888 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004889 else
4890#endif
4891
Larry Hastings2f936352014-08-05 14:04:04 +10004892 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004893
4894 Py_END_ALLOW_THREADS
4895
4896 if (result < 0) {
4897 /* see previous comment about not putting filename in error here */
4898 return_value = posix_error();
4899 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004900 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004901
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004902#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004903
4904 Py_INCREF(Py_None);
4905 return_value = Py_None;
4906
4907exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004908#ifdef MS_WINDOWS
4909 if (hFile != INVALID_HANDLE_VALUE)
4910 CloseHandle(hFile);
4911#endif
4912 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004913}
4914
Guido van Rossum3b066191991-06-04 19:40:25 +00004915/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004916
Larry Hastings2f936352014-08-05 14:04:04 +10004917
4918/*[clinic input]
4919os._exit
4920
4921 status: int
4922
4923Exit to the system with specified status, without normal exit processing.
4924[clinic start generated code]*/
4925
Larry Hastings2f936352014-08-05 14:04:04 +10004926static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004927os__exit_impl(PyObject *module, int status)
4928/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004929{
4930 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004931 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004932}
4933
Martin v. Löwis114619e2002-10-07 06:44:21 +00004934#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4935static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004936free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004937{
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 Py_ssize_t i;
4939 for (i = 0; i < count; i++)
4940 PyMem_Free(array[i]);
4941 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004942}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004943
Antoine Pitrou69f71142009-05-24 21:25:49 +00004944static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004945int fsconvert_strdup(PyObject *o, char**out)
4946{
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 PyObject *bytes;
4948 Py_ssize_t size;
4949 if (!PyUnicode_FSConverter(o, &bytes))
4950 return 0;
4951 size = PyBytes_GET_SIZE(bytes);
4952 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004953 if (!*out) {
4954 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004956 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 memcpy(*out, PyBytes_AsString(bytes), size+1);
4958 Py_DECREF(bytes);
4959 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004960}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004961#endif
4962
Ross Lagerwall7807c352011-03-17 20:20:30 +02004963#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004964static char**
4965parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4966{
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 char **envlist;
4968 Py_ssize_t i, pos, envc;
4969 PyObject *keys=NULL, *vals=NULL;
4970 PyObject *key, *val, *key2, *val2;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004971 char *p;
4972 const char *k, *v;
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004974
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 i = PyMapping_Size(env);
4976 if (i < 0)
4977 return NULL;
4978 envlist = PyMem_NEW(char *, i + 1);
4979 if (envlist == NULL) {
4980 PyErr_NoMemory();
4981 return NULL;
4982 }
4983 envc = 0;
4984 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004985 if (!keys)
4986 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004987 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004988 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004989 goto error;
4990 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4991 PyErr_Format(PyExc_TypeError,
4992 "env.keys() or env.values() is not a list");
4993 goto error;
4994 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 for (pos = 0; pos < i; pos++) {
4997 key = PyList_GetItem(keys, pos);
4998 val = PyList_GetItem(vals, pos);
4999 if (!key || !val)
5000 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005001
Victor Stinner8c62be82010-05-06 00:08:46 +00005002 if (PyUnicode_FSConverter(key, &key2) == 0)
5003 goto error;
5004 if (PyUnicode_FSConverter(val, &val2) == 0) {
5005 Py_DECREF(key2);
5006 goto error;
5007 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00005008
Victor Stinner8c62be82010-05-06 00:08:46 +00005009 k = PyBytes_AsString(key2);
5010 v = PyBytes_AsString(val2);
5011 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005012
Victor Stinner8c62be82010-05-06 00:08:46 +00005013 p = PyMem_NEW(char, len);
5014 if (p == NULL) {
5015 PyErr_NoMemory();
5016 Py_DECREF(key2);
5017 Py_DECREF(val2);
5018 goto error;
5019 }
5020 PyOS_snprintf(p, len, "%s=%s", k, v);
5021 envlist[envc++] = p;
5022 Py_DECREF(key2);
5023 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00005024 }
5025 Py_DECREF(vals);
5026 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005027
Victor Stinner8c62be82010-05-06 00:08:46 +00005028 envlist[envc] = 0;
5029 *envc_ptr = envc;
5030 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005031
5032error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005033 Py_XDECREF(keys);
5034 Py_XDECREF(vals);
5035 while (--envc >= 0)
5036 PyMem_DEL(envlist[envc]);
5037 PyMem_DEL(envlist);
5038 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005039}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005040
Ross Lagerwall7807c352011-03-17 20:20:30 +02005041static char**
5042parse_arglist(PyObject* argv, Py_ssize_t *argc)
5043{
5044 int i;
5045 char **argvlist = PyMem_NEW(char *, *argc+1);
5046 if (argvlist == NULL) {
5047 PyErr_NoMemory();
5048 return NULL;
5049 }
5050 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005051 PyObject* item = PySequence_ITEM(argv, i);
5052 if (item == NULL)
5053 goto fail;
5054 if (!fsconvert_strdup(item, &argvlist[i])) {
5055 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 goto fail;
5057 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005058 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 }
5060 argvlist[*argc] = NULL;
5061 return argvlist;
5062fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005063 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005064 free_string_array(argvlist, *argc);
5065 return NULL;
5066}
5067#endif
5068
Larry Hastings2f936352014-08-05 14:04:04 +10005069
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005071/*[clinic input]
5072os.execv
5073
5074 path: FSConverter
5075 Path of executable file.
5076 argv: object
5077 Tuple or list of strings.
5078 /
5079
5080Execute an executable path with arguments, replacing current process.
5081[clinic start generated code]*/
5082
Larry Hastings2f936352014-08-05 14:04:04 +10005083static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005084os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5085/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005086{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005087 const char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005088 char **argvlist;
5089 Py_ssize_t argc;
5090
5091 /* execv has two arguments: (path, argv), where
5092 argv is a list or tuple of strings. */
5093
Larry Hastings2f936352014-08-05 14:04:04 +10005094 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005095 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5096 PyErr_SetString(PyExc_TypeError,
5097 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 return NULL;
5099 }
5100 argc = PySequence_Size(argv);
5101 if (argc < 1) {
5102 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 return NULL;
5104 }
5105
5106 argvlist = parse_arglist(argv, &argc);
5107 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 return NULL;
5109 }
5110
Larry Hastings2f936352014-08-05 14:04:04 +10005111 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005112
5113 /* If we get here it's definitely an error */
5114
5115 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 return posix_error();
5117}
5118
Larry Hastings2f936352014-08-05 14:04:04 +10005119
5120/*[clinic input]
5121os.execve
5122
5123 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5124 Path of executable file.
5125 argv: object
5126 Tuple or list of strings.
5127 env: object
5128 Dictionary of strings mapping to strings.
5129
5130Execute an executable path with arguments, replacing current process.
5131[clinic start generated code]*/
5132
Larry Hastings2f936352014-08-05 14:04:04 +10005133static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005134os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5135/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005136{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005137 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005138 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005139 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005140
Victor Stinner8c62be82010-05-06 00:08:46 +00005141 /* execve has three arguments: (path, argv, env), where
5142 argv is a list or tuple of strings and env is a dictionary
5143 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005144
Ross Lagerwall7807c352011-03-17 20:20:30 +02005145 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005146 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005147 "execve: argv must be a tuple or list");
5148 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005150 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 if (!PyMapping_Check(env)) {
5152 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005153 "execve: environment must be a mapping object");
5154 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005156
Ross Lagerwall7807c352011-03-17 20:20:30 +02005157 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005158 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005159 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005161
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 envlist = parse_envlist(env, &envc);
5163 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005164 goto fail;
5165
Larry Hastings9cf065c2012-06-22 16:30:09 -07005166#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005167 if (path->fd > -1)
5168 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005169 else
5170#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005171 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005172
5173 /* If we get here it's definitely an error */
5174
Larry Hastings2f936352014-08-05 14:04:04 +10005175 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005176
5177 while (--envc >= 0)
5178 PyMem_DEL(envlist[envc]);
5179 PyMem_DEL(envlist);
5180 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005181 if (argvlist)
5182 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005183 return NULL;
5184}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005185#endif /* HAVE_EXECV */
5186
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005187
Guido van Rossuma1065681999-01-25 23:20:23 +00005188#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005189/*[clinic input]
5190os.spawnv
5191
5192 mode: int
5193 Mode of process creation.
5194 path: FSConverter
5195 Path of executable file.
5196 argv: object
5197 Tuple or list of strings.
5198 /
5199
5200Execute the program specified by path in a new process.
5201[clinic start generated code]*/
5202
Larry Hastings2f936352014-08-05 14:04:04 +10005203static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005204os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5205/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005206{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005207 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005209 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 Py_ssize_t argc;
5211 Py_intptr_t spawnval;
5212 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005213
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 /* spawnv has three arguments: (mode, path, argv), where
5215 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005216
Larry Hastings2f936352014-08-05 14:04:04 +10005217 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005218 if (PyList_Check(argv)) {
5219 argc = PyList_Size(argv);
5220 getitem = PyList_GetItem;
5221 }
5222 else if (PyTuple_Check(argv)) {
5223 argc = PyTuple_Size(argv);
5224 getitem = PyTuple_GetItem;
5225 }
5226 else {
5227 PyErr_SetString(PyExc_TypeError,
5228 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005229 return NULL;
5230 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005231
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 argvlist = PyMem_NEW(char *, argc+1);
5233 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 return PyErr_NoMemory();
5235 }
5236 for (i = 0; i < argc; i++) {
5237 if (!fsconvert_strdup((*getitem)(argv, i),
5238 &argvlist[i])) {
5239 free_string_array(argvlist, i);
5240 PyErr_SetString(
5241 PyExc_TypeError,
5242 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005243 return NULL;
5244 }
5245 }
5246 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005247
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 if (mode == _OLD_P_OVERLAY)
5249 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005250
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005252 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005254
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005256
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 if (spawnval == -1)
5258 return posix_error();
5259 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005260 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005261}
5262
5263
Larry Hastings2f936352014-08-05 14:04:04 +10005264/*[clinic input]
5265os.spawnve
5266
5267 mode: int
5268 Mode of process creation.
5269 path: FSConverter
5270 Path of executable file.
5271 argv: object
5272 Tuple or list of strings.
5273 env: object
5274 Dictionary of strings mapping to strings.
5275 /
5276
5277Execute the program specified by path in a new process.
5278[clinic start generated code]*/
5279
Larry Hastings2f936352014-08-05 14:04:04 +10005280static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005281os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5282 PyObject *env)
5283/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005284{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005285 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 char **argvlist;
5287 char **envlist;
5288 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005289 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 Py_intptr_t spawnval;
5291 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5292 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 /* spawnve has four arguments: (mode, path, argv, env), where
5295 argv is a list or tuple of strings and env is a dictionary
5296 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005297
Larry Hastings2f936352014-08-05 14:04:04 +10005298 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 if (PyList_Check(argv)) {
5300 argc = PyList_Size(argv);
5301 getitem = PyList_GetItem;
5302 }
5303 else if (PyTuple_Check(argv)) {
5304 argc = PyTuple_Size(argv);
5305 getitem = PyTuple_GetItem;
5306 }
5307 else {
5308 PyErr_SetString(PyExc_TypeError,
5309 "spawnve() arg 2 must be a tuple or list");
5310 goto fail_0;
5311 }
5312 if (!PyMapping_Check(env)) {
5313 PyErr_SetString(PyExc_TypeError,
5314 "spawnve() arg 3 must be a mapping object");
5315 goto fail_0;
5316 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005317
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 argvlist = PyMem_NEW(char *, argc+1);
5319 if (argvlist == NULL) {
5320 PyErr_NoMemory();
5321 goto fail_0;
5322 }
5323 for (i = 0; i < argc; i++) {
5324 if (!fsconvert_strdup((*getitem)(argv, i),
5325 &argvlist[i]))
5326 {
5327 lastarg = i;
5328 goto fail_1;
5329 }
5330 }
5331 lastarg = argc;
5332 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005333
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 envlist = parse_envlist(env, &envc);
5335 if (envlist == NULL)
5336 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005337
Victor Stinner8c62be82010-05-06 00:08:46 +00005338 if (mode == _OLD_P_OVERLAY)
5339 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005340
Victor Stinner8c62be82010-05-06 00:08:46 +00005341 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005342 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005343 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005344
Victor Stinner8c62be82010-05-06 00:08:46 +00005345 if (spawnval == -1)
5346 (void) posix_error();
5347 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005348 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005349
Victor Stinner8c62be82010-05-06 00:08:46 +00005350 while (--envc >= 0)
5351 PyMem_DEL(envlist[envc]);
5352 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005353 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005354 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005355 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005356 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005357}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005358
Guido van Rossuma1065681999-01-25 23:20:23 +00005359#endif /* HAVE_SPAWNV */
5360
5361
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005362#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005363/*[clinic input]
5364os.fork1
5365
5366Fork a child process with a single multiplexed (i.e., not bound) thread.
5367
5368Return 0 to child process and PID of child to parent process.
5369[clinic start generated code]*/
5370
Larry Hastings2f936352014-08-05 14:04:04 +10005371static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005372os_fork1_impl(PyObject *module)
5373/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005374{
Victor Stinner8c62be82010-05-06 00:08:46 +00005375 pid_t pid;
5376 int result = 0;
5377 _PyImport_AcquireLock();
5378 pid = fork1();
5379 if (pid == 0) {
5380 /* child: this clobbers and resets the import lock. */
5381 PyOS_AfterFork();
5382 } else {
5383 /* parent: release the import lock. */
5384 result = _PyImport_ReleaseLock();
5385 }
5386 if (pid == -1)
5387 return posix_error();
5388 if (result < 0) {
5389 /* Don't clobber the OSError if the fork failed. */
5390 PyErr_SetString(PyExc_RuntimeError,
5391 "not holding the import lock");
5392 return NULL;
5393 }
5394 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005395}
Larry Hastings2f936352014-08-05 14:04:04 +10005396#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005397
5398
Guido van Rossumad0ee831995-03-01 10:34:45 +00005399#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005400/*[clinic input]
5401os.fork
5402
5403Fork a child process.
5404
5405Return 0 to child process and PID of child to parent process.
5406[clinic start generated code]*/
5407
Larry Hastings2f936352014-08-05 14:04:04 +10005408static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005409os_fork_impl(PyObject *module)
5410/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005411{
Victor Stinner8c62be82010-05-06 00:08:46 +00005412 pid_t pid;
5413 int result = 0;
5414 _PyImport_AcquireLock();
5415 pid = fork();
5416 if (pid == 0) {
5417 /* child: this clobbers and resets the import lock. */
5418 PyOS_AfterFork();
5419 } else {
5420 /* parent: release the import lock. */
5421 result = _PyImport_ReleaseLock();
5422 }
5423 if (pid == -1)
5424 return posix_error();
5425 if (result < 0) {
5426 /* Don't clobber the OSError if the fork failed. */
5427 PyErr_SetString(PyExc_RuntimeError,
5428 "not holding the import lock");
5429 return NULL;
5430 }
5431 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005432}
Larry Hastings2f936352014-08-05 14:04:04 +10005433#endif /* HAVE_FORK */
5434
Guido van Rossum85e3b011991-06-03 12:42:10 +00005435
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005436#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005437#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005438/*[clinic input]
5439os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005440
Larry Hastings2f936352014-08-05 14:04:04 +10005441 policy: int
5442
5443Get the maximum scheduling priority for policy.
5444[clinic start generated code]*/
5445
Larry Hastings2f936352014-08-05 14:04:04 +10005446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005447os_sched_get_priority_max_impl(PyObject *module, int policy)
5448/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005449{
5450 int max;
5451
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005452 max = sched_get_priority_max(policy);
5453 if (max < 0)
5454 return posix_error();
5455 return PyLong_FromLong(max);
5456}
5457
Larry Hastings2f936352014-08-05 14:04:04 +10005458
5459/*[clinic input]
5460os.sched_get_priority_min
5461
5462 policy: int
5463
5464Get the minimum scheduling priority for policy.
5465[clinic start generated code]*/
5466
Larry Hastings2f936352014-08-05 14:04:04 +10005467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005468os_sched_get_priority_min_impl(PyObject *module, int policy)
5469/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005470{
5471 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005472 if (min < 0)
5473 return posix_error();
5474 return PyLong_FromLong(min);
5475}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005476#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5477
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005478
Larry Hastings2f936352014-08-05 14:04:04 +10005479#ifdef HAVE_SCHED_SETSCHEDULER
5480/*[clinic input]
5481os.sched_getscheduler
5482 pid: pid_t
5483 /
5484
5485Get the scheduling policy for the process identifiedy by pid.
5486
5487Passing 0 for pid returns the scheduling policy for the calling process.
5488[clinic start generated code]*/
5489
Larry Hastings2f936352014-08-05 14:04:04 +10005490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005491os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5492/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005493{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005494 int policy;
5495
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 policy = sched_getscheduler(pid);
5497 if (policy < 0)
5498 return posix_error();
5499 return PyLong_FromLong(policy);
5500}
Larry Hastings2f936352014-08-05 14:04:04 +10005501#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005502
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005503
5504#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005505/*[clinic input]
5506class os.sched_param "PyObject *" "&SchedParamType"
5507
5508@classmethod
5509os.sched_param.__new__
5510
5511 sched_priority: object
5512 A scheduling parameter.
5513
5514Current has only one field: sched_priority");
5515[clinic start generated code]*/
5516
Larry Hastings2f936352014-08-05 14:04:04 +10005517static PyObject *
5518os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005519/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005520{
5521 PyObject *res;
5522
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005523 res = PyStructSequence_New(type);
5524 if (!res)
5525 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005526 Py_INCREF(sched_priority);
5527 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005528 return res;
5529}
5530
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005531
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005532PyDoc_VAR(os_sched_param__doc__);
5533
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005534static PyStructSequence_Field sched_param_fields[] = {
5535 {"sched_priority", "the scheduling priority"},
5536 {0}
5537};
5538
5539static PyStructSequence_Desc sched_param_desc = {
5540 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005541 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005542 sched_param_fields,
5543 1
5544};
5545
5546static int
5547convert_sched_param(PyObject *param, struct sched_param *res)
5548{
5549 long priority;
5550
5551 if (Py_TYPE(param) != &SchedParamType) {
5552 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5553 return 0;
5554 }
5555 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5556 if (priority == -1 && PyErr_Occurred())
5557 return 0;
5558 if (priority > INT_MAX || priority < INT_MIN) {
5559 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5560 return 0;
5561 }
5562 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5563 return 1;
5564}
Larry Hastings2f936352014-08-05 14:04:04 +10005565#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005566
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005567
5568#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005569/*[clinic input]
5570os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005571
Larry Hastings2f936352014-08-05 14:04:04 +10005572 pid: pid_t
5573 policy: int
5574 param: sched_param
5575 /
5576
5577Set the scheduling policy for the process identified by pid.
5578
5579If pid is 0, the calling process is changed.
5580param is an instance of sched_param.
5581[clinic start generated code]*/
5582
Larry Hastings2f936352014-08-05 14:04:04 +10005583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005584os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005585 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005586/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005587{
Jesus Cea9c822272011-09-10 01:40:52 +02005588 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005589 ** sched_setscheduler() returns 0 in Linux, but the previous
5590 ** scheduling policy under Solaris/Illumos, and others.
5591 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005592 */
Larry Hastings2f936352014-08-05 14:04:04 +10005593 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005594 return posix_error();
5595 Py_RETURN_NONE;
5596}
Larry Hastings2f936352014-08-05 14:04:04 +10005597#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005598
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005599
5600#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005601/*[clinic input]
5602os.sched_getparam
5603 pid: pid_t
5604 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005605
Larry Hastings2f936352014-08-05 14:04:04 +10005606Returns scheduling parameters for the process identified by pid.
5607
5608If pid is 0, returns parameters for the calling process.
5609Return value is an instance of sched_param.
5610[clinic start generated code]*/
5611
Larry Hastings2f936352014-08-05 14:04:04 +10005612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005613os_sched_getparam_impl(PyObject *module, pid_t pid)
5614/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005615{
5616 struct sched_param param;
5617 PyObject *result;
5618 PyObject *priority;
5619
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005620 if (sched_getparam(pid, &param))
5621 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005622 result = PyStructSequence_New(&SchedParamType);
5623 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005624 return NULL;
5625 priority = PyLong_FromLong(param.sched_priority);
5626 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005627 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005628 return NULL;
5629 }
Larry Hastings2f936352014-08-05 14:04:04 +10005630 PyStructSequence_SET_ITEM(result, 0, priority);
5631 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005632}
5633
Larry Hastings2f936352014-08-05 14:04:04 +10005634
5635/*[clinic input]
5636os.sched_setparam
5637 pid: pid_t
5638 param: sched_param
5639 /
5640
5641Set scheduling parameters for the process identified by pid.
5642
5643If pid is 0, sets parameters for the calling process.
5644param should be an instance of sched_param.
5645[clinic start generated code]*/
5646
Larry Hastings2f936352014-08-05 14:04:04 +10005647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005648os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005649 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005650/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005651{
5652 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005653 return posix_error();
5654 Py_RETURN_NONE;
5655}
Larry Hastings2f936352014-08-05 14:04:04 +10005656#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005657
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005658
5659#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005660/*[clinic input]
5661os.sched_rr_get_interval -> double
5662 pid: pid_t
5663 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005664
Larry Hastings2f936352014-08-05 14:04:04 +10005665Return the round-robin quantum for the process identified by pid, in seconds.
5666
5667Value returned is a float.
5668[clinic start generated code]*/
5669
Larry Hastings2f936352014-08-05 14:04:04 +10005670static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005671os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5672/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005673{
5674 struct timespec interval;
5675 if (sched_rr_get_interval(pid, &interval)) {
5676 posix_error();
5677 return -1.0;
5678 }
5679 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5680}
5681#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005682
Larry Hastings2f936352014-08-05 14:04:04 +10005683
5684/*[clinic input]
5685os.sched_yield
5686
5687Voluntarily relinquish the CPU.
5688[clinic start generated code]*/
5689
Larry Hastings2f936352014-08-05 14:04:04 +10005690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005691os_sched_yield_impl(PyObject *module)
5692/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005693{
5694 if (sched_yield())
5695 return posix_error();
5696 Py_RETURN_NONE;
5697}
5698
Benjamin Peterson2740af82011-08-02 17:41:34 -05005699#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005700/* The minimum number of CPUs allocated in a cpu_set_t */
5701static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005702
Larry Hastings2f936352014-08-05 14:04:04 +10005703/*[clinic input]
5704os.sched_setaffinity
5705 pid: pid_t
5706 mask : object
5707 /
5708
5709Set the CPU affinity of the process identified by pid to mask.
5710
5711mask should be an iterable of integers identifying CPUs.
5712[clinic start generated code]*/
5713
Larry Hastings2f936352014-08-05 14:04:04 +10005714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005715os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5716/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005717{
Antoine Pitrou84869872012-08-04 16:16:35 +02005718 int ncpus;
5719 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005720 cpu_set_t *cpu_set = NULL;
5721 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005722
Larry Hastings2f936352014-08-05 14:04:04 +10005723 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005724 if (iterator == NULL)
5725 return NULL;
5726
5727 ncpus = NCPUS_START;
5728 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005729 cpu_set = CPU_ALLOC(ncpus);
5730 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005731 PyErr_NoMemory();
5732 goto error;
5733 }
Larry Hastings2f936352014-08-05 14:04:04 +10005734 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005735
5736 while ((item = PyIter_Next(iterator))) {
5737 long cpu;
5738 if (!PyLong_Check(item)) {
5739 PyErr_Format(PyExc_TypeError,
5740 "expected an iterator of ints, "
5741 "but iterator yielded %R",
5742 Py_TYPE(item));
5743 Py_DECREF(item);
5744 goto error;
5745 }
5746 cpu = PyLong_AsLong(item);
5747 Py_DECREF(item);
5748 if (cpu < 0) {
5749 if (!PyErr_Occurred())
5750 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5751 goto error;
5752 }
5753 if (cpu > INT_MAX - 1) {
5754 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5755 goto error;
5756 }
5757 if (cpu >= ncpus) {
5758 /* Grow CPU mask to fit the CPU number */
5759 int newncpus = ncpus;
5760 cpu_set_t *newmask;
5761 size_t newsetsize;
5762 while (newncpus <= cpu) {
5763 if (newncpus > INT_MAX / 2)
5764 newncpus = cpu + 1;
5765 else
5766 newncpus = newncpus * 2;
5767 }
5768 newmask = CPU_ALLOC(newncpus);
5769 if (newmask == NULL) {
5770 PyErr_NoMemory();
5771 goto error;
5772 }
5773 newsetsize = CPU_ALLOC_SIZE(newncpus);
5774 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005775 memcpy(newmask, cpu_set, setsize);
5776 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005777 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005778 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005779 ncpus = newncpus;
5780 }
Larry Hastings2f936352014-08-05 14:04:04 +10005781 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005782 }
5783 Py_CLEAR(iterator);
5784
Larry Hastings2f936352014-08-05 14:04:04 +10005785 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005786 posix_error();
5787 goto error;
5788 }
Larry Hastings2f936352014-08-05 14:04:04 +10005789 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005790 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005791
5792error:
Larry Hastings2f936352014-08-05 14:04:04 +10005793 if (cpu_set)
5794 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005795 Py_XDECREF(iterator);
5796 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005797}
5798
Larry Hastings2f936352014-08-05 14:04:04 +10005799
5800/*[clinic input]
5801os.sched_getaffinity
5802 pid: pid_t
5803 /
5804
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005805Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005806
5807The affinity is returned as a set of CPU identifiers.
5808[clinic start generated code]*/
5809
Larry Hastings2f936352014-08-05 14:04:04 +10005810static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005811os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005812/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005813{
Antoine Pitrou84869872012-08-04 16:16:35 +02005814 int cpu, ncpus, count;
5815 size_t setsize;
5816 cpu_set_t *mask = NULL;
5817 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818
Antoine Pitrou84869872012-08-04 16:16:35 +02005819 ncpus = NCPUS_START;
5820 while (1) {
5821 setsize = CPU_ALLOC_SIZE(ncpus);
5822 mask = CPU_ALLOC(ncpus);
5823 if (mask == NULL)
5824 return PyErr_NoMemory();
5825 if (sched_getaffinity(pid, setsize, mask) == 0)
5826 break;
5827 CPU_FREE(mask);
5828 if (errno != EINVAL)
5829 return posix_error();
5830 if (ncpus > INT_MAX / 2) {
5831 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5832 "a large enough CPU set");
5833 return NULL;
5834 }
5835 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005836 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005837
5838 res = PySet_New(NULL);
5839 if (res == NULL)
5840 goto error;
5841 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5842 if (CPU_ISSET_S(cpu, setsize, mask)) {
5843 PyObject *cpu_num = PyLong_FromLong(cpu);
5844 --count;
5845 if (cpu_num == NULL)
5846 goto error;
5847 if (PySet_Add(res, cpu_num)) {
5848 Py_DECREF(cpu_num);
5849 goto error;
5850 }
5851 Py_DECREF(cpu_num);
5852 }
5853 }
5854 CPU_FREE(mask);
5855 return res;
5856
5857error:
5858 if (mask)
5859 CPU_FREE(mask);
5860 Py_XDECREF(res);
5861 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005862}
5863
Benjamin Peterson2740af82011-08-02 17:41:34 -05005864#endif /* HAVE_SCHED_SETAFFINITY */
5865
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005866#endif /* HAVE_SCHED_H */
5867
Larry Hastings2f936352014-08-05 14:04:04 +10005868
Neal Norwitzb59798b2003-03-21 01:43:31 +00005869/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005870/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5871#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005872#define DEV_PTY_FILE "/dev/ptc"
5873#define HAVE_DEV_PTMX
5874#else
5875#define DEV_PTY_FILE "/dev/ptmx"
5876#endif
5877
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005878#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005879#ifdef HAVE_PTY_H
5880#include <pty.h>
5881#else
5882#ifdef HAVE_LIBUTIL_H
5883#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005884#else
5885#ifdef HAVE_UTIL_H
5886#include <util.h>
5887#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005888#endif /* HAVE_LIBUTIL_H */
5889#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005890#ifdef HAVE_STROPTS_H
5891#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005892#endif
5893#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005894
Larry Hastings2f936352014-08-05 14:04:04 +10005895
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005896#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005897/*[clinic input]
5898os.openpty
5899
5900Open a pseudo-terminal.
5901
5902Return a tuple of (master_fd, slave_fd) containing open file descriptors
5903for both the master and slave ends.
5904[clinic start generated code]*/
5905
Larry Hastings2f936352014-08-05 14:04:04 +10005906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005907os_openpty_impl(PyObject *module)
5908/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005909{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005910 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005911#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005913#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005914#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005916#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005918#endif
5919#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005920
Thomas Wouters70c21a12000-07-14 14:28:33 +00005921#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005923 goto posix_error;
5924
5925 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5926 goto error;
5927 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5928 goto error;
5929
Neal Norwitzb59798b2003-03-21 01:43:31 +00005930#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5932 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005933 goto posix_error;
5934 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5935 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005936
Victor Stinnerdaf45552013-08-28 00:53:59 +02005937 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005938 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005939 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005940
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005941#else
Victor Stinner000de532013-11-25 23:19:58 +01005942 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005944 goto posix_error;
5945
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005947
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 /* change permission of slave */
5949 if (grantpt(master_fd) < 0) {
5950 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005951 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005952 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953
Victor Stinner8c62be82010-05-06 00:08:46 +00005954 /* unlock slave */
5955 if (unlockpt(master_fd) < 0) {
5956 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005959
Victor Stinner8c62be82010-05-06 00:08:46 +00005960 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005961
Victor Stinner8c62be82010-05-06 00:08:46 +00005962 slave_name = ptsname(master_fd); /* get name of slave */
5963 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005964 goto posix_error;
5965
5966 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005967 if (slave_fd == -1)
5968 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005969
5970 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5971 goto posix_error;
5972
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005973#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5975 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005976#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005977 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005978#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005979#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005980#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005981
Victor Stinner8c62be82010-05-06 00:08:46 +00005982 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005983
Victor Stinnerdaf45552013-08-28 00:53:59 +02005984posix_error:
5985 posix_error();
5986error:
5987 if (master_fd != -1)
5988 close(master_fd);
5989 if (slave_fd != -1)
5990 close(slave_fd);
5991 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005992}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005993#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005994
Larry Hastings2f936352014-08-05 14:04:04 +10005995
Fred Drake8cef4cf2000-06-28 16:40:38 +00005996#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005997/*[clinic input]
5998os.forkpty
5999
6000Fork a new process with a new pseudo-terminal as controlling tty.
6001
6002Returns a tuple of (pid, master_fd).
6003Like fork(), return pid of 0 to the child process,
6004and pid of child to the parent process.
6005To both, return fd of newly opened pseudo-terminal.
6006[clinic start generated code]*/
6007
Larry Hastings2f936352014-08-05 14:04:04 +10006008static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006009os_forkpty_impl(PyObject *module)
6010/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00006011{
Victor Stinner8c62be82010-05-06 00:08:46 +00006012 int master_fd = -1, result = 0;
6013 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00006014
Victor Stinner8c62be82010-05-06 00:08:46 +00006015 _PyImport_AcquireLock();
6016 pid = forkpty(&master_fd, NULL, NULL, NULL);
6017 if (pid == 0) {
6018 /* child: this clobbers and resets the import lock. */
6019 PyOS_AfterFork();
6020 } else {
6021 /* parent: release the import lock. */
6022 result = _PyImport_ReleaseLock();
6023 }
6024 if (pid == -1)
6025 return posix_error();
6026 if (result < 0) {
6027 /* Don't clobber the OSError if the fork failed. */
6028 PyErr_SetString(PyExc_RuntimeError,
6029 "not holding the import lock");
6030 return NULL;
6031 }
6032 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006033}
Larry Hastings2f936352014-08-05 14:04:04 +10006034#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006035
Ross Lagerwall7807c352011-03-17 20:20:30 +02006036
Guido van Rossumad0ee831995-03-01 10:34:45 +00006037#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006038/*[clinic input]
6039os.getegid
6040
6041Return the current process's effective group id.
6042[clinic start generated code]*/
6043
Larry Hastings2f936352014-08-05 14:04:04 +10006044static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006045os_getegid_impl(PyObject *module)
6046/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006047{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006048 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006049}
Larry Hastings2f936352014-08-05 14:04:04 +10006050#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006051
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006052
Guido van Rossumad0ee831995-03-01 10:34:45 +00006053#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006054/*[clinic input]
6055os.geteuid
6056
6057Return the current process's effective user id.
6058[clinic start generated code]*/
6059
Larry Hastings2f936352014-08-05 14:04:04 +10006060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006061os_geteuid_impl(PyObject *module)
6062/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006063{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006064 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006065}
Larry Hastings2f936352014-08-05 14:04:04 +10006066#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006068
Guido van Rossumad0ee831995-03-01 10:34:45 +00006069#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006070/*[clinic input]
6071os.getgid
6072
6073Return the current process's group id.
6074[clinic start generated code]*/
6075
Larry Hastings2f936352014-08-05 14:04:04 +10006076static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006077os_getgid_impl(PyObject *module)
6078/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006079{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006080 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006081}
Larry Hastings2f936352014-08-05 14:04:04 +10006082#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006083
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006084
Larry Hastings2f936352014-08-05 14:04:04 +10006085/*[clinic input]
6086os.getpid
6087
6088Return the current process id.
6089[clinic start generated code]*/
6090
Larry Hastings2f936352014-08-05 14:04:04 +10006091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006092os_getpid_impl(PyObject *module)
6093/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006094{
Victor Stinner8c62be82010-05-06 00:08:46 +00006095 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006096}
6097
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006098#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006099
6100/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006101PyDoc_STRVAR(posix_getgrouplist__doc__,
6102"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6103Returns a list of groups to which a user belongs.\n\n\
6104 user: username to lookup\n\
6105 group: base group id of the user");
6106
6107static PyObject *
6108posix_getgrouplist(PyObject *self, PyObject *args)
6109{
6110#ifdef NGROUPS_MAX
6111#define MAX_GROUPS NGROUPS_MAX
6112#else
6113 /* defined to be 16 on Solaris7, so this should be a small number */
6114#define MAX_GROUPS 64
6115#endif
6116
6117 const char *user;
6118 int i, ngroups;
6119 PyObject *list;
6120#ifdef __APPLE__
6121 int *groups, basegid;
6122#else
6123 gid_t *groups, basegid;
6124#endif
6125 ngroups = MAX_GROUPS;
6126
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006127#ifdef __APPLE__
6128 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006129 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006130#else
6131 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6132 _Py_Gid_Converter, &basegid))
6133 return NULL;
6134#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006135
6136#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006137 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006138#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006139 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006140#endif
6141 if (groups == NULL)
6142 return PyErr_NoMemory();
6143
6144 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6145 PyMem_Del(groups);
6146 return posix_error();
6147 }
6148
6149 list = PyList_New(ngroups);
6150 if (list == NULL) {
6151 PyMem_Del(groups);
6152 return NULL;
6153 }
6154
6155 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006156#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006157 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006158#else
6159 PyObject *o = _PyLong_FromGid(groups[i]);
6160#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006161 if (o == NULL) {
6162 Py_DECREF(list);
6163 PyMem_Del(groups);
6164 return NULL;
6165 }
6166 PyList_SET_ITEM(list, i, o);
6167 }
6168
6169 PyMem_Del(groups);
6170
6171 return list;
6172}
Larry Hastings2f936352014-08-05 14:04:04 +10006173#endif /* HAVE_GETGROUPLIST */
6174
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006175
Fred Drakec9680921999-12-13 16:37:25 +00006176#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006177/*[clinic input]
6178os.getgroups
6179
6180Return list of supplemental group IDs for the process.
6181[clinic start generated code]*/
6182
Larry Hastings2f936352014-08-05 14:04:04 +10006183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006184os_getgroups_impl(PyObject *module)
6185/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006186{
6187 PyObject *result = NULL;
6188
Fred Drakec9680921999-12-13 16:37:25 +00006189#ifdef NGROUPS_MAX
6190#define MAX_GROUPS NGROUPS_MAX
6191#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006192 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006193#define MAX_GROUPS 64
6194#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006196
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006197 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006198 * This is a helper variable to store the intermediate result when
6199 * that happens.
6200 *
6201 * To keep the code readable the OSX behaviour is unconditional,
6202 * according to the POSIX spec this should be safe on all unix-y
6203 * systems.
6204 */
6205 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006206 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006207
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006208#ifdef __APPLE__
6209 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6210 * there are more groups than can fit in grouplist. Therefore, on OS X
6211 * always first call getgroups with length 0 to get the actual number
6212 * of groups.
6213 */
6214 n = getgroups(0, NULL);
6215 if (n < 0) {
6216 return posix_error();
6217 } else if (n <= MAX_GROUPS) {
6218 /* groups will fit in existing array */
6219 alt_grouplist = grouplist;
6220 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006221 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006222 if (alt_grouplist == NULL) {
6223 errno = EINVAL;
6224 return posix_error();
6225 }
6226 }
6227
6228 n = getgroups(n, alt_grouplist);
6229 if (n == -1) {
6230 if (alt_grouplist != grouplist) {
6231 PyMem_Free(alt_grouplist);
6232 }
6233 return posix_error();
6234 }
6235#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006237 if (n < 0) {
6238 if (errno == EINVAL) {
6239 n = getgroups(0, NULL);
6240 if (n == -1) {
6241 return posix_error();
6242 }
6243 if (n == 0) {
6244 /* Avoid malloc(0) */
6245 alt_grouplist = grouplist;
6246 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006247 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006248 if (alt_grouplist == NULL) {
6249 errno = EINVAL;
6250 return posix_error();
6251 }
6252 n = getgroups(n, alt_grouplist);
6253 if (n == -1) {
6254 PyMem_Free(alt_grouplist);
6255 return posix_error();
6256 }
6257 }
6258 } else {
6259 return posix_error();
6260 }
6261 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006262#endif
6263
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006264 result = PyList_New(n);
6265 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006266 int i;
6267 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006268 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006270 Py_DECREF(result);
6271 result = NULL;
6272 break;
Fred Drakec9680921999-12-13 16:37:25 +00006273 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006275 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006276 }
6277
6278 if (alt_grouplist != grouplist) {
6279 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006281
Fred Drakec9680921999-12-13 16:37:25 +00006282 return result;
6283}
Larry Hastings2f936352014-08-05 14:04:04 +10006284#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006285
Antoine Pitroub7572f02009-12-02 20:46:48 +00006286#ifdef HAVE_INITGROUPS
6287PyDoc_STRVAR(posix_initgroups__doc__,
6288"initgroups(username, gid) -> None\n\n\
6289Call the system initgroups() to initialize the group access list with all of\n\
6290the groups of which the specified username is a member, plus the specified\n\
6291group id.");
6292
Larry Hastings2f936352014-08-05 14:04:04 +10006293/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006294static PyObject *
6295posix_initgroups(PyObject *self, PyObject *args)
6296{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006297 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006298 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006299 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006300#ifdef __APPLE__
6301 int gid;
6302#else
6303 gid_t gid;
6304#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006305
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006306#ifdef __APPLE__
6307 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6308 PyUnicode_FSConverter, &oname,
6309 &gid))
6310#else
6311 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6312 PyUnicode_FSConverter, &oname,
6313 _Py_Gid_Converter, &gid))
6314#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006315 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006316 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006317
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006318 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006319 Py_DECREF(oname);
6320 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006322
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 Py_INCREF(Py_None);
6324 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006325}
Larry Hastings2f936352014-08-05 14:04:04 +10006326#endif /* HAVE_INITGROUPS */
6327
Antoine Pitroub7572f02009-12-02 20:46:48 +00006328
Martin v. Löwis606edc12002-06-13 21:09:11 +00006329#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006330/*[clinic input]
6331os.getpgid
6332
6333 pid: pid_t
6334
6335Call the system call getpgid(), and return the result.
6336[clinic start generated code]*/
6337
Larry Hastings2f936352014-08-05 14:04:04 +10006338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006339os_getpgid_impl(PyObject *module, pid_t pid)
6340/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006341{
6342 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 if (pgid < 0)
6344 return posix_error();
6345 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006346}
6347#endif /* HAVE_GETPGID */
6348
6349
Guido van Rossumb6775db1994-08-01 11:34:53 +00006350#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006351/*[clinic input]
6352os.getpgrp
6353
6354Return the current process group id.
6355[clinic start generated code]*/
6356
Larry Hastings2f936352014-08-05 14:04:04 +10006357static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006358os_getpgrp_impl(PyObject *module)
6359/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006360{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006362 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006363#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006364 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006365#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006366}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006367#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006369
Guido van Rossumb6775db1994-08-01 11:34:53 +00006370#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006371/*[clinic input]
6372os.setpgrp
6373
6374Make the current process the leader of its process group.
6375[clinic start generated code]*/
6376
Larry Hastings2f936352014-08-05 14:04:04 +10006377static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006378os_setpgrp_impl(PyObject *module)
6379/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006380{
Guido van Rossum64933891994-10-20 21:56:42 +00006381#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006382 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006383#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006384 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006385#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006386 return posix_error();
6387 Py_INCREF(Py_None);
6388 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006389}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006390#endif /* HAVE_SETPGRP */
6391
Guido van Rossumad0ee831995-03-01 10:34:45 +00006392#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006393
6394#ifdef MS_WINDOWS
6395#include <tlhelp32.h>
6396
6397static PyObject*
6398win32_getppid()
6399{
6400 HANDLE snapshot;
6401 pid_t mypid;
6402 PyObject* result = NULL;
6403 BOOL have_record;
6404 PROCESSENTRY32 pe;
6405
6406 mypid = getpid(); /* This function never fails */
6407
6408 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6409 if (snapshot == INVALID_HANDLE_VALUE)
6410 return PyErr_SetFromWindowsErr(GetLastError());
6411
6412 pe.dwSize = sizeof(pe);
6413 have_record = Process32First(snapshot, &pe);
6414 while (have_record) {
6415 if (mypid == (pid_t)pe.th32ProcessID) {
6416 /* We could cache the ulong value in a static variable. */
6417 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6418 break;
6419 }
6420
6421 have_record = Process32Next(snapshot, &pe);
6422 }
6423
6424 /* If our loop exits and our pid was not found (result will be NULL)
6425 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6426 * error anyway, so let's raise it. */
6427 if (!result)
6428 result = PyErr_SetFromWindowsErr(GetLastError());
6429
6430 CloseHandle(snapshot);
6431
6432 return result;
6433}
6434#endif /*MS_WINDOWS*/
6435
Larry Hastings2f936352014-08-05 14:04:04 +10006436
6437/*[clinic input]
6438os.getppid
6439
6440Return the parent's process id.
6441
6442If the parent process has already exited, Windows machines will still
6443return its id; others systems will return the id of the 'init' process (1).
6444[clinic start generated code]*/
6445
Larry Hastings2f936352014-08-05 14:04:04 +10006446static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006447os_getppid_impl(PyObject *module)
6448/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006449{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006450#ifdef MS_WINDOWS
6451 return win32_getppid();
6452#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006454#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006455}
6456#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006457
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006458
Fred Drake12c6e2d1999-12-14 21:25:03 +00006459#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006460/*[clinic input]
6461os.getlogin
6462
6463Return the actual login name.
6464[clinic start generated code]*/
6465
Larry Hastings2f936352014-08-05 14:04:04 +10006466static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006467os_getlogin_impl(PyObject *module)
6468/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006469{
Victor Stinner8c62be82010-05-06 00:08:46 +00006470 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006471#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006472 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006473 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006474
6475 if (GetUserNameW(user_name, &num_chars)) {
6476 /* num_chars is the number of unicode chars plus null terminator */
6477 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006478 }
6479 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006480 result = PyErr_SetFromWindowsErr(GetLastError());
6481#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006482 char *name;
6483 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006484
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 errno = 0;
6486 name = getlogin();
6487 if (name == NULL) {
6488 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006489 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006490 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006491 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006492 }
6493 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006494 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006495 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006496#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006497 return result;
6498}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006499#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006500
Larry Hastings2f936352014-08-05 14:04:04 +10006501
Guido van Rossumad0ee831995-03-01 10:34:45 +00006502#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006503/*[clinic input]
6504os.getuid
6505
6506Return the current process's user id.
6507[clinic start generated code]*/
6508
Larry Hastings2f936352014-08-05 14:04:04 +10006509static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006510os_getuid_impl(PyObject *module)
6511/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006512{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006513 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006514}
Larry Hastings2f936352014-08-05 14:04:04 +10006515#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006516
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006517
Brian Curtineb24d742010-04-12 17:16:38 +00006518#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006519#define HAVE_KILL
6520#endif /* MS_WINDOWS */
6521
6522#ifdef HAVE_KILL
6523/*[clinic input]
6524os.kill
6525
6526 pid: pid_t
6527 signal: Py_ssize_t
6528 /
6529
6530Kill a process with a signal.
6531[clinic start generated code]*/
6532
Larry Hastings2f936352014-08-05 14:04:04 +10006533static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006534os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6535/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006536#ifndef MS_WINDOWS
6537{
6538 if (kill(pid, (int)signal) == -1)
6539 return posix_error();
6540 Py_RETURN_NONE;
6541}
6542#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006543{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006544 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006545 DWORD sig = (DWORD)signal;
6546 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006548
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 /* Console processes which share a common console can be sent CTRL+C or
6550 CTRL+BREAK events, provided they handle said events. */
6551 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006552 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006553 err = GetLastError();
6554 PyErr_SetFromWindowsErr(err);
6555 }
6556 else
6557 Py_RETURN_NONE;
6558 }
Brian Curtineb24d742010-04-12 17:16:38 +00006559
Victor Stinner8c62be82010-05-06 00:08:46 +00006560 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6561 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006562 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006563 if (handle == NULL) {
6564 err = GetLastError();
6565 return PyErr_SetFromWindowsErr(err);
6566 }
Brian Curtineb24d742010-04-12 17:16:38 +00006567
Victor Stinner8c62be82010-05-06 00:08:46 +00006568 if (TerminateProcess(handle, sig) == 0) {
6569 err = GetLastError();
6570 result = PyErr_SetFromWindowsErr(err);
6571 } else {
6572 Py_INCREF(Py_None);
6573 result = Py_None;
6574 }
Brian Curtineb24d742010-04-12 17:16:38 +00006575
Victor Stinner8c62be82010-05-06 00:08:46 +00006576 CloseHandle(handle);
6577 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006578}
Larry Hastings2f936352014-08-05 14:04:04 +10006579#endif /* !MS_WINDOWS */
6580#endif /* HAVE_KILL */
6581
6582
6583#ifdef HAVE_KILLPG
6584/*[clinic input]
6585os.killpg
6586
6587 pgid: pid_t
6588 signal: int
6589 /
6590
6591Kill a process group with a signal.
6592[clinic start generated code]*/
6593
Larry Hastings2f936352014-08-05 14:04:04 +10006594static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006595os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6596/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006597{
6598 /* XXX some man pages make the `pgid` parameter an int, others
6599 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6600 take the same type. Moreover, pid_t is always at least as wide as
6601 int (else compilation of this module fails), which is safe. */
6602 if (killpg(pgid, signal) == -1)
6603 return posix_error();
6604 Py_RETURN_NONE;
6605}
6606#endif /* HAVE_KILLPG */
6607
Brian Curtineb24d742010-04-12 17:16:38 +00006608
Guido van Rossumc0125471996-06-28 18:55:32 +00006609#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006610#ifdef HAVE_SYS_LOCK_H
6611#include <sys/lock.h>
6612#endif
6613
Larry Hastings2f936352014-08-05 14:04:04 +10006614/*[clinic input]
6615os.plock
6616 op: int
6617 /
6618
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006619Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006623os_plock_impl(PyObject *module, int op)
6624/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006625{
Victor Stinner8c62be82010-05-06 00:08:46 +00006626 if (plock(op) == -1)
6627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006628 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006629}
Larry Hastings2f936352014-08-05 14:04:04 +10006630#endif /* HAVE_PLOCK */
6631
Guido van Rossumc0125471996-06-28 18:55:32 +00006632
Guido van Rossumb6775db1994-08-01 11:34:53 +00006633#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.setuid
6636
6637 uid: uid_t
6638 /
6639
6640Set the current process's user id.
6641[clinic start generated code]*/
6642
Larry Hastings2f936352014-08-05 14:04:04 +10006643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006644os_setuid_impl(PyObject *module, uid_t uid)
6645/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006646{
Victor Stinner8c62be82010-05-06 00:08:46 +00006647 if (setuid(uid) < 0)
6648 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006649 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006650}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006651#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006653
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006654#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006655/*[clinic input]
6656os.seteuid
6657
6658 euid: uid_t
6659 /
6660
6661Set the current process's effective user id.
6662[clinic start generated code]*/
6663
Larry Hastings2f936352014-08-05 14:04:04 +10006664static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006665os_seteuid_impl(PyObject *module, uid_t euid)
6666/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006667{
6668 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006670 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006671}
6672#endif /* HAVE_SETEUID */
6673
Larry Hastings2f936352014-08-05 14:04:04 +10006674
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006675#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006676/*[clinic input]
6677os.setegid
6678
6679 egid: gid_t
6680 /
6681
6682Set the current process's effective group id.
6683[clinic start generated code]*/
6684
Larry Hastings2f936352014-08-05 14:04:04 +10006685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006686os_setegid_impl(PyObject *module, gid_t egid)
6687/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006688{
6689 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006690 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006691 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006692}
6693#endif /* HAVE_SETEGID */
6694
Larry Hastings2f936352014-08-05 14:04:04 +10006695
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006696#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006697/*[clinic input]
6698os.setreuid
6699
6700 ruid: uid_t
6701 euid: uid_t
6702 /
6703
6704Set the current process's real and effective user ids.
6705[clinic start generated code]*/
6706
Larry Hastings2f936352014-08-05 14:04:04 +10006707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006708os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6709/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006710{
Victor Stinner8c62be82010-05-06 00:08:46 +00006711 if (setreuid(ruid, euid) < 0) {
6712 return posix_error();
6713 } else {
6714 Py_INCREF(Py_None);
6715 return Py_None;
6716 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006717}
6718#endif /* HAVE_SETREUID */
6719
Larry Hastings2f936352014-08-05 14:04:04 +10006720
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006721#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006722/*[clinic input]
6723os.setregid
6724
6725 rgid: gid_t
6726 egid: gid_t
6727 /
6728
6729Set the current process's real and effective group ids.
6730[clinic start generated code]*/
6731
Larry Hastings2f936352014-08-05 14:04:04 +10006732static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006733os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6734/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006735{
6736 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006738 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006739}
6740#endif /* HAVE_SETREGID */
6741
Larry Hastings2f936352014-08-05 14:04:04 +10006742
Guido van Rossumb6775db1994-08-01 11:34:53 +00006743#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006744/*[clinic input]
6745os.setgid
6746 gid: gid_t
6747 /
6748
6749Set the current process's group id.
6750[clinic start generated code]*/
6751
Larry Hastings2f936352014-08-05 14:04:04 +10006752static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006753os_setgid_impl(PyObject *module, gid_t gid)
6754/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006755{
Victor Stinner8c62be82010-05-06 00:08:46 +00006756 if (setgid(gid) < 0)
6757 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006758 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006759}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006760#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006761
Larry Hastings2f936352014-08-05 14:04:04 +10006762
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006763#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006764/*[clinic input]
6765os.setgroups
6766
6767 groups: object
6768 /
6769
6770Set the groups of the current process to list.
6771[clinic start generated code]*/
6772
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006773static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006774os_setgroups(PyObject *module, PyObject *groups)
6775/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006776{
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 int i, len;
6778 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006779
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 if (!PySequence_Check(groups)) {
6781 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6782 return NULL;
6783 }
6784 len = PySequence_Size(groups);
6785 if (len > MAX_GROUPS) {
6786 PyErr_SetString(PyExc_ValueError, "too many groups");
6787 return NULL;
6788 }
6789 for(i = 0; i < len; i++) {
6790 PyObject *elem;
6791 elem = PySequence_GetItem(groups, i);
6792 if (!elem)
6793 return NULL;
6794 if (!PyLong_Check(elem)) {
6795 PyErr_SetString(PyExc_TypeError,
6796 "groups must be integers");
6797 Py_DECREF(elem);
6798 return NULL;
6799 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006800 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 Py_DECREF(elem);
6802 return NULL;
6803 }
6804 }
6805 Py_DECREF(elem);
6806 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006807
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 if (setgroups(len, grouplist) < 0)
6809 return posix_error();
6810 Py_INCREF(Py_None);
6811 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006812}
6813#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006814
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6816static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006817wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818{
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 PyObject *result;
6820 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006821 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 if (pid == -1)
6824 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 if (struct_rusage == NULL) {
6827 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6828 if (m == NULL)
6829 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006830 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 Py_DECREF(m);
6832 if (struct_rusage == NULL)
6833 return NULL;
6834 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6837 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6838 if (!result)
6839 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840
6841#ifndef doubletime
6842#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6843#endif
6844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006846 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006848 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6851 SET_INT(result, 2, ru->ru_maxrss);
6852 SET_INT(result, 3, ru->ru_ixrss);
6853 SET_INT(result, 4, ru->ru_idrss);
6854 SET_INT(result, 5, ru->ru_isrss);
6855 SET_INT(result, 6, ru->ru_minflt);
6856 SET_INT(result, 7, ru->ru_majflt);
6857 SET_INT(result, 8, ru->ru_nswap);
6858 SET_INT(result, 9, ru->ru_inblock);
6859 SET_INT(result, 10, ru->ru_oublock);
6860 SET_INT(result, 11, ru->ru_msgsnd);
6861 SET_INT(result, 12, ru->ru_msgrcv);
6862 SET_INT(result, 13, ru->ru_nsignals);
6863 SET_INT(result, 14, ru->ru_nvcsw);
6864 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865#undef SET_INT
6866
Victor Stinner8c62be82010-05-06 00:08:46 +00006867 if (PyErr_Occurred()) {
6868 Py_DECREF(result);
6869 return NULL;
6870 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006871
Victor Stinner8c62be82010-05-06 00:08:46 +00006872 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006873}
6874#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6875
Larry Hastings2f936352014-08-05 14:04:04 +10006876
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006877#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006878/*[clinic input]
6879os.wait3
6880
6881 options: int
6882Wait for completion of a child process.
6883
6884Returns a tuple of information about the child process:
6885 (pid, status, rusage)
6886[clinic start generated code]*/
6887
Larry Hastings2f936352014-08-05 14:04:04 +10006888static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006889os_wait3_impl(PyObject *module, int options)
6890/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006891{
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006893 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006894 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006895 WAIT_TYPE status;
6896 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006897
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006898 do {
6899 Py_BEGIN_ALLOW_THREADS
6900 pid = wait3(&status, options, &ru);
6901 Py_END_ALLOW_THREADS
6902 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6903 if (pid < 0)
6904 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006905
Victor Stinner4195b5c2012-02-08 23:03:19 +01006906 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907}
6908#endif /* HAVE_WAIT3 */
6909
Larry Hastings2f936352014-08-05 14:04:04 +10006910
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006912/*[clinic input]
6913
6914os.wait4
6915
6916 pid: pid_t
6917 options: int
6918
6919Wait for completion of a specific child process.
6920
6921Returns a tuple of information about the child process:
6922 (pid, status, rusage)
6923[clinic start generated code]*/
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006926os_wait4_impl(PyObject *module, pid_t pid, int options)
6927/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006928{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006929 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006930 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006931 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006932 WAIT_TYPE status;
6933 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 do {
6936 Py_BEGIN_ALLOW_THREADS
6937 res = wait4(pid, &status, options, &ru);
6938 Py_END_ALLOW_THREADS
6939 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6940 if (res < 0)
6941 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006942
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006943 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006944}
6945#endif /* HAVE_WAIT4 */
6946
Larry Hastings2f936352014-08-05 14:04:04 +10006947
Ross Lagerwall7807c352011-03-17 20:20:30 +02006948#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006949/*[clinic input]
6950os.waitid
6951
6952 idtype: idtype_t
6953 Must be one of be P_PID, P_PGID or P_ALL.
6954 id: id_t
6955 The id to wait on.
6956 options: int
6957 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6958 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6959 /
6960
6961Returns the result of waiting for a process or processes.
6962
6963Returns either waitid_result or None if WNOHANG is specified and there are
6964no children in a waitable state.
6965[clinic start generated code]*/
6966
Larry Hastings2f936352014-08-05 14:04:04 +10006967static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006968os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6969/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006970{
6971 PyObject *result;
6972 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006973 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006974 siginfo_t si;
6975 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006976
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006977 do {
6978 Py_BEGIN_ALLOW_THREADS
6979 res = waitid(idtype, id, &si, options);
6980 Py_END_ALLOW_THREADS
6981 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6982 if (res < 0)
6983 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006984
6985 if (si.si_pid == 0)
6986 Py_RETURN_NONE;
6987
6988 result = PyStructSequence_New(&WaitidResultType);
6989 if (!result)
6990 return NULL;
6991
6992 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006993 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006994 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6995 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6996 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6997 if (PyErr_Occurred()) {
6998 Py_DECREF(result);
6999 return NULL;
7000 }
7001
7002 return result;
7003}
Larry Hastings2f936352014-08-05 14:04:04 +10007004#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007005
Larry Hastings2f936352014-08-05 14:04:04 +10007006
7007#if defined(HAVE_WAITPID)
7008/*[clinic input]
7009os.waitpid
7010 pid: pid_t
7011 options: int
7012 /
7013
7014Wait for completion of a given child process.
7015
7016Returns a tuple of information regarding the child process:
7017 (pid, status)
7018
7019The options argument is ignored on Windows.
7020[clinic start generated code]*/
7021
Larry Hastings2f936352014-08-05 14:04:04 +10007022static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007023os_waitpid_impl(PyObject *module, pid_t pid, int options)
7024/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007025{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007026 pid_t res;
7027 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007028 WAIT_TYPE status;
7029 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007030
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007031 do {
7032 Py_BEGIN_ALLOW_THREADS
7033 res = waitpid(pid, &status, options);
7034 Py_END_ALLOW_THREADS
7035 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7036 if (res < 0)
7037 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007038
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007039 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007040}
Tim Petersab034fa2002-02-01 11:27:43 +00007041#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007042/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007043/*[clinic input]
7044os.waitpid
7045 pid: Py_intptr_t
7046 options: int
7047 /
7048
7049Wait for completion of a given process.
7050
7051Returns a tuple of information regarding the process:
7052 (pid, status << 8)
7053
7054The options argument is ignored on Windows.
7055[clinic start generated code]*/
7056
Larry Hastings2f936352014-08-05 14:04:04 +10007057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007058os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7059/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007060{
7061 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007062 Py_intptr_t res;
7063 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007064
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007065 do {
7066 Py_BEGIN_ALLOW_THREADS
7067 res = _cwait(&status, pid, options);
7068 Py_END_ALLOW_THREADS
7069 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007070 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007071 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007072
Victor Stinner8c62be82010-05-06 00:08:46 +00007073 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007074 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007075}
Larry Hastings2f936352014-08-05 14:04:04 +10007076#endif
7077
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007078
Guido van Rossumad0ee831995-03-01 10:34:45 +00007079#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007080/*[clinic input]
7081os.wait
7082
7083Wait for completion of a child process.
7084
7085Returns a tuple of information about the child process:
7086 (pid, status)
7087[clinic start generated code]*/
7088
Larry Hastings2f936352014-08-05 14:04:04 +10007089static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007090os_wait_impl(PyObject *module)
7091/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007092{
Victor Stinner8c62be82010-05-06 00:08:46 +00007093 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007094 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007095 WAIT_TYPE status;
7096 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007097
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007098 do {
7099 Py_BEGIN_ALLOW_THREADS
7100 pid = wait(&status);
7101 Py_END_ALLOW_THREADS
7102 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7103 if (pid < 0)
7104 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007105
Victor Stinner8c62be82010-05-06 00:08:46 +00007106 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007107}
Larry Hastings2f936352014-08-05 14:04:04 +10007108#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007109
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007110
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7112PyDoc_STRVAR(readlink__doc__,
7113"readlink(path, *, dir_fd=None) -> path\n\n\
7114Return a string representing the path to which the symbolic link points.\n\
7115\n\
7116If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7117 and path should be relative; path will then be relative to that directory.\n\
7118dir_fd may not be implemented on your platform.\n\
7119 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007120#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007121
Guido van Rossumb6775db1994-08-01 11:34:53 +00007122#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007123
Larry Hastings2f936352014-08-05 14:04:04 +10007124/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007125static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007127{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007128 path_t path;
7129 int dir_fd = DEFAULT_DIR_FD;
7130 char buffer[MAXPATHLEN];
7131 ssize_t length;
7132 PyObject *return_value = NULL;
7133 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007134
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007136 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007137 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7138 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007139 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007140 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007141
Victor Stinner8c62be82010-05-06 00:08:46 +00007142 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007143#ifdef HAVE_READLINKAT
7144 if (dir_fd != DEFAULT_DIR_FD)
7145 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007146 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007147#endif
7148 length = readlink(path.narrow, buffer, sizeof(buffer));
7149 Py_END_ALLOW_THREADS
7150
7151 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007152 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007153 goto exit;
7154 }
7155
7156 if (PyUnicode_Check(path.object))
7157 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7158 else
7159 return_value = PyBytes_FromStringAndSize(buffer, length);
7160exit:
7161 path_cleanup(&path);
7162 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007163}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007164
Guido van Rossumb6775db1994-08-01 11:34:53 +00007165#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007166
Larry Hastings2f936352014-08-05 14:04:04 +10007167#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7168
7169static PyObject *
7170win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7171{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007172 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007173 DWORD n_bytes_returned;
7174 DWORD io_result;
7175 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007176 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007177 HANDLE reparse_point_handle;
7178
Martin Panter70214ad2016-08-04 02:38:59 +00007179 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7180 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007181 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007182
7183 static char *keywords[] = {"path", "dir_fd", NULL};
7184
7185 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7186 &po,
7187 dir_fd_unavailable, &dir_fd
7188 ))
7189 return NULL;
7190
7191 path = PyUnicode_AsUnicode(po);
7192 if (path == NULL)
7193 return NULL;
7194
7195 /* First get a handle to the reparse point */
7196 Py_BEGIN_ALLOW_THREADS
7197 reparse_point_handle = CreateFileW(
7198 path,
7199 0,
7200 0,
7201 0,
7202 OPEN_EXISTING,
7203 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7204 0);
7205 Py_END_ALLOW_THREADS
7206
7207 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7208 return win32_error_object("readlink", po);
7209
7210 Py_BEGIN_ALLOW_THREADS
7211 /* New call DeviceIoControl to read the reparse point */
7212 io_result = DeviceIoControl(
7213 reparse_point_handle,
7214 FSCTL_GET_REPARSE_POINT,
7215 0, 0, /* in buffer */
7216 target_buffer, sizeof(target_buffer),
7217 &n_bytes_returned,
7218 0 /* we're not using OVERLAPPED_IO */
7219 );
7220 CloseHandle(reparse_point_handle);
7221 Py_END_ALLOW_THREADS
7222
7223 if (io_result==0)
7224 return win32_error_object("readlink", po);
7225
7226 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7227 {
7228 PyErr_SetString(PyExc_ValueError,
7229 "not a symbolic link");
7230 return NULL;
7231 }
7232 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7233 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7234
7235 result = PyUnicode_FromWideChar(print_name,
7236 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7237 return result;
7238}
7239
7240#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7241
7242
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007243
Larry Hastings9cf065c2012-06-22 16:30:09 -07007244#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007245
7246#if defined(MS_WINDOWS)
7247
7248/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007249static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
7250static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPCSTR, LPCSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007251
Larry Hastings9cf065c2012-06-22 16:30:09 -07007252static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007253check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007254{
7255 HINSTANCE hKernel32;
7256 /* only recheck */
7257 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7258 return 1;
7259 hKernel32 = GetModuleHandleW(L"KERNEL32");
7260 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7261 "CreateSymbolicLinkW");
7262 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7263 "CreateSymbolicLinkA");
7264 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7265}
7266
Victor Stinner31b3b922013-06-05 01:49:17 +02007267/* Remove the last portion of the path */
7268static void
7269_dirnameW(WCHAR *path)
7270{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007271 WCHAR *ptr;
7272
7273 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007274 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007275 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 }
7278 *ptr = 0;
7279}
7280
Victor Stinner31b3b922013-06-05 01:49:17 +02007281/* Remove the last portion of the path */
7282static void
7283_dirnameA(char *path)
7284{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007285 char *ptr;
7286
7287 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007288 for(ptr = path + strlen(path); ptr != path; ptr--) {
7289 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007290 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291 }
7292 *ptr = 0;
7293}
7294
Victor Stinner31b3b922013-06-05 01:49:17 +02007295/* Is this path absolute? */
7296static int
7297_is_absW(const WCHAR *path)
7298{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007299 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7300
7301}
7302
Victor Stinner31b3b922013-06-05 01:49:17 +02007303/* Is this path absolute? */
7304static int
7305_is_absA(const char *path)
7306{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007307 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7308
7309}
7310
Victor Stinner31b3b922013-06-05 01:49:17 +02007311/* join root and rest with a backslash */
7312static void
7313_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7314{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007315 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316
Victor Stinner31b3b922013-06-05 01:49:17 +02007317 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007318 wcscpy(dest_path, rest);
7319 return;
7320 }
7321
7322 root_len = wcslen(root);
7323
7324 wcscpy(dest_path, root);
7325 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007326 dest_path[root_len] = L'\\';
7327 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007328 }
7329 wcscpy(dest_path+root_len, rest);
7330}
7331
Victor Stinner31b3b922013-06-05 01:49:17 +02007332/* join root and rest with a backslash */
7333static void
7334_joinA(char *dest_path, const char *root, const char *rest)
7335{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007336 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337
Victor Stinner31b3b922013-06-05 01:49:17 +02007338 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007339 strcpy(dest_path, rest);
7340 return;
7341 }
7342
7343 root_len = strlen(root);
7344
7345 strcpy(dest_path, root);
7346 if(root_len) {
7347 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007348 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007349 }
7350 strcpy(dest_path+root_len, rest);
7351}
7352
Victor Stinner31b3b922013-06-05 01:49:17 +02007353/* Return True if the path at src relative to dest is a directory */
7354static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007355_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007356{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007357 WIN32_FILE_ATTRIBUTE_DATA src_info;
7358 WCHAR dest_parent[MAX_PATH];
7359 WCHAR src_resolved[MAX_PATH] = L"";
7360
7361 /* dest_parent = os.path.dirname(dest) */
7362 wcscpy(dest_parent, dest);
7363 _dirnameW(dest_parent);
7364 /* src_resolved = os.path.join(dest_parent, src) */
7365 _joinW(src_resolved, dest_parent, src);
7366 return (
7367 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7368 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7369 );
7370}
7371
Victor Stinner31b3b922013-06-05 01:49:17 +02007372/* Return True if the path at src relative to dest is a directory */
7373static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007374_check_dirA(LPCSTR src, LPCSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007375{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007376 WIN32_FILE_ATTRIBUTE_DATA src_info;
7377 char dest_parent[MAX_PATH];
7378 char src_resolved[MAX_PATH] = "";
7379
7380 /* dest_parent = os.path.dirname(dest) */
7381 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007382 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007383 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007384 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007385 return (
7386 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7387 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7388 );
7389}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007391
Larry Hastings2f936352014-08-05 14:04:04 +10007392
7393/*[clinic input]
7394os.symlink
7395 src: path_t
7396 dst: path_t
7397 target_is_directory: bool = False
7398 *
7399 dir_fd: dir_fd(requires='symlinkat')=None
7400
7401# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7402
7403Create a symbolic link pointing to src named dst.
7404
7405target_is_directory is required on Windows if the target is to be
7406 interpreted as a directory. (On Windows, symlink requires
7407 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7408 target_is_directory is ignored on non-Windows platforms.
7409
7410If dir_fd is not None, it should be a file descriptor open to a directory,
7411 and path should be relative; path will then be relative to that directory.
7412dir_fd may not be implemented on your platform.
7413 If it is unavailable, using it will raise a NotImplementedError.
7414
7415[clinic start generated code]*/
7416
Larry Hastings2f936352014-08-05 14:04:04 +10007417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007418os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007419 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007420/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007421{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422#ifdef MS_WINDOWS
7423 DWORD result;
7424#else
7425 int result;
7426#endif
7427
Larry Hastings9cf065c2012-06-22 16:30:09 -07007428#ifdef MS_WINDOWS
7429 if (!check_CreateSymbolicLink()) {
7430 PyErr_SetString(PyExc_NotImplementedError,
7431 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007432 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007433 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434 if (!win32_can_symlink) {
7435 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007436 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007437 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438#endif
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007441 PyErr_SetString(PyExc_ValueError,
7442 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007444 }
7445
7446#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007447
Larry Hastings9cf065c2012-06-22 16:30:09 -07007448 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007449 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007450 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007451 target_is_directory |= _check_dirW(src->wide, dst->wide);
7452 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007453 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007454 }
7455 else {
7456 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007457 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7458 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007459 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007460 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007461 Py_END_ALLOW_THREADS
7462
Larry Hastings2f936352014-08-05 14:04:04 +10007463 if (!result)
7464 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007465
7466#else
7467
7468 Py_BEGIN_ALLOW_THREADS
7469#if HAVE_SYMLINKAT
7470 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007471 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007472 else
7473#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007474 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007475 Py_END_ALLOW_THREADS
7476
Larry Hastings2f936352014-08-05 14:04:04 +10007477 if (result)
7478 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007479#endif
7480
Larry Hastings2f936352014-08-05 14:04:04 +10007481 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007482}
7483#endif /* HAVE_SYMLINK */
7484
Larry Hastings9cf065c2012-06-22 16:30:09 -07007485
Brian Curtind40e6f72010-07-08 21:39:08 +00007486
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007487
Larry Hastings605a62d2012-06-24 04:33:36 -07007488static PyStructSequence_Field times_result_fields[] = {
7489 {"user", "user time"},
7490 {"system", "system time"},
7491 {"children_user", "user time of children"},
7492 {"children_system", "system time of children"},
7493 {"elapsed", "elapsed time since an arbitrary point in the past"},
7494 {NULL}
7495};
7496
7497PyDoc_STRVAR(times_result__doc__,
7498"times_result: Result from os.times().\n\n\
7499This object may be accessed either as a tuple of\n\
7500 (user, system, children_user, children_system, elapsed),\n\
7501or via the attributes user, system, children_user, children_system,\n\
7502and elapsed.\n\
7503\n\
7504See os.times for more information.");
7505
7506static PyStructSequence_Desc times_result_desc = {
7507 "times_result", /* name */
7508 times_result__doc__, /* doc */
7509 times_result_fields,
7510 5
7511};
7512
7513static PyTypeObject TimesResultType;
7514
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007515#ifdef MS_WINDOWS
7516#define HAVE_TIMES /* mandatory, for the method table */
7517#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007518
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007519#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007520
7521static PyObject *
7522build_times_result(double user, double system,
7523 double children_user, double children_system,
7524 double elapsed)
7525{
7526 PyObject *value = PyStructSequence_New(&TimesResultType);
7527 if (value == NULL)
7528 return NULL;
7529
7530#define SET(i, field) \
7531 { \
7532 PyObject *o = PyFloat_FromDouble(field); \
7533 if (!o) { \
7534 Py_DECREF(value); \
7535 return NULL; \
7536 } \
7537 PyStructSequence_SET_ITEM(value, i, o); \
7538 } \
7539
7540 SET(0, user);
7541 SET(1, system);
7542 SET(2, children_user);
7543 SET(3, children_system);
7544 SET(4, elapsed);
7545
7546#undef SET
7547
7548 return value;
7549}
7550
Larry Hastings605a62d2012-06-24 04:33:36 -07007551
Larry Hastings2f936352014-08-05 14:04:04 +10007552#ifndef MS_WINDOWS
7553#define NEED_TICKS_PER_SECOND
7554static long ticks_per_second = -1;
7555#endif /* MS_WINDOWS */
7556
7557/*[clinic input]
7558os.times
7559
7560Return a collection containing process timing information.
7561
7562The object returned behaves like a named tuple with these fields:
7563 (utime, stime, cutime, cstime, elapsed_time)
7564All fields are floating point numbers.
7565[clinic start generated code]*/
7566
Larry Hastings2f936352014-08-05 14:04:04 +10007567static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007568os_times_impl(PyObject *module)
7569/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007570#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007571{
Victor Stinner8c62be82010-05-06 00:08:46 +00007572 FILETIME create, exit, kernel, user;
7573 HANDLE hProc;
7574 hProc = GetCurrentProcess();
7575 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7576 /* The fields of a FILETIME structure are the hi and lo part
7577 of a 64-bit value expressed in 100 nanosecond units.
7578 1e7 is one second in such units; 1e-7 the inverse.
7579 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7580 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007581 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007582 (double)(user.dwHighDateTime*429.4967296 +
7583 user.dwLowDateTime*1e-7),
7584 (double)(kernel.dwHighDateTime*429.4967296 +
7585 kernel.dwLowDateTime*1e-7),
7586 (double)0,
7587 (double)0,
7588 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007589}
Larry Hastings2f936352014-08-05 14:04:04 +10007590#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007591{
Larry Hastings2f936352014-08-05 14:04:04 +10007592
7593
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007594 struct tms t;
7595 clock_t c;
7596 errno = 0;
7597 c = times(&t);
7598 if (c == (clock_t) -1)
7599 return posix_error();
7600 return build_times_result(
7601 (double)t.tms_utime / ticks_per_second,
7602 (double)t.tms_stime / ticks_per_second,
7603 (double)t.tms_cutime / ticks_per_second,
7604 (double)t.tms_cstime / ticks_per_second,
7605 (double)c / ticks_per_second);
7606}
Larry Hastings2f936352014-08-05 14:04:04 +10007607#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007608#endif /* HAVE_TIMES */
7609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007611#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.getsid
7614
7615 pid: pid_t
7616 /
7617
7618Call the system call getsid(pid) and return the result.
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007622os_getsid_impl(PyObject *module, pid_t pid)
7623/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007624{
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 sid = getsid(pid);
7627 if (sid < 0)
7628 return posix_error();
7629 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007630}
7631#endif /* HAVE_GETSID */
7632
7633
Guido van Rossumb6775db1994-08-01 11:34:53 +00007634#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007635/*[clinic input]
7636os.setsid
7637
7638Call the system call setsid().
7639[clinic start generated code]*/
7640
Larry Hastings2f936352014-08-05 14:04:04 +10007641static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007642os_setsid_impl(PyObject *module)
7643/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007644{
Victor Stinner8c62be82010-05-06 00:08:46 +00007645 if (setsid() < 0)
7646 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007647 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007648}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007649#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007650
Larry Hastings2f936352014-08-05 14:04:04 +10007651
Guido van Rossumb6775db1994-08-01 11:34:53 +00007652#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007653/*[clinic input]
7654os.setpgid
7655
7656 pid: pid_t
7657 pgrp: pid_t
7658 /
7659
7660Call the system call setpgid(pid, pgrp).
7661[clinic start generated code]*/
7662
Larry Hastings2f936352014-08-05 14:04:04 +10007663static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007664os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7665/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007666{
Victor Stinner8c62be82010-05-06 00:08:46 +00007667 if (setpgid(pid, pgrp) < 0)
7668 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007669 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007670}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007671#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007672
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007673
Guido van Rossumb6775db1994-08-01 11:34:53 +00007674#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007675/*[clinic input]
7676os.tcgetpgrp
7677
7678 fd: int
7679 /
7680
7681Return the process group associated with the terminal specified by fd.
7682[clinic start generated code]*/
7683
Larry Hastings2f936352014-08-05 14:04:04 +10007684static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007685os_tcgetpgrp_impl(PyObject *module, int fd)
7686/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007687{
7688 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007689 if (pgid < 0)
7690 return posix_error();
7691 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007692}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007693#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007694
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007695
Guido van Rossumb6775db1994-08-01 11:34:53 +00007696#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007697/*[clinic input]
7698os.tcsetpgrp
7699
7700 fd: int
7701 pgid: pid_t
7702 /
7703
7704Set the process group associated with the terminal specified by fd.
7705[clinic start generated code]*/
7706
Larry Hastings2f936352014-08-05 14:04:04 +10007707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007708os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7709/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007710{
Victor Stinner8c62be82010-05-06 00:08:46 +00007711 if (tcsetpgrp(fd, pgid) < 0)
7712 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007713 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007714}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007715#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007716
Guido van Rossum687dd131993-05-17 08:34:16 +00007717/* Functions acting on file descriptors */
7718
Victor Stinnerdaf45552013-08-28 00:53:59 +02007719#ifdef O_CLOEXEC
7720extern int _Py_open_cloexec_works;
7721#endif
7722
Larry Hastings2f936352014-08-05 14:04:04 +10007723
7724/*[clinic input]
7725os.open -> int
7726 path: path_t
7727 flags: int
7728 mode: int = 0o777
7729 *
7730 dir_fd: dir_fd(requires='openat') = None
7731
7732# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7733
7734Open a file for low level IO. Returns a file descriptor (integer).
7735
7736If dir_fd is not None, it should be a file descriptor open to a directory,
7737 and path should be relative; path will then be relative to that directory.
7738dir_fd may not be implemented on your platform.
7739 If it is unavailable, using it will raise a NotImplementedError.
7740[clinic start generated code]*/
7741
Larry Hastings2f936352014-08-05 14:04:04 +10007742static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007743os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7744/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007745{
7746 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007747 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007748
Victor Stinnerdaf45552013-08-28 00:53:59 +02007749#ifdef O_CLOEXEC
7750 int *atomic_flag_works = &_Py_open_cloexec_works;
7751#elif !defined(MS_WINDOWS)
7752 int *atomic_flag_works = NULL;
7753#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007754
Victor Stinnerdaf45552013-08-28 00:53:59 +02007755#ifdef MS_WINDOWS
7756 flags |= O_NOINHERIT;
7757#elif defined(O_CLOEXEC)
7758 flags |= O_CLOEXEC;
7759#endif
7760
Steve Dower8fc89802015-04-12 00:26:27 -04007761 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007762 do {
7763 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007764#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007765 if (path->wide)
7766 fd = _wopen(path->wide, flags, mode);
7767 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007768#endif
7769#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007770 if (dir_fd != DEFAULT_DIR_FD)
7771 fd = openat(dir_fd, path->narrow, flags, mode);
7772 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007773#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007774 fd = open(path->narrow, flags, mode);
7775 Py_END_ALLOW_THREADS
7776 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007777 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007778
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007779 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007780 if (!async_err)
7781 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007782 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007783 }
7784
Victor Stinnerdaf45552013-08-28 00:53:59 +02007785#ifndef MS_WINDOWS
7786 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7787 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007788 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007789 }
7790#endif
7791
Larry Hastings2f936352014-08-05 14:04:04 +10007792 return fd;
7793}
7794
7795
7796/*[clinic input]
7797os.close
7798
7799 fd: int
7800
7801Close a file descriptor.
7802[clinic start generated code]*/
7803
Barry Warsaw53699e91996-12-10 23:23:01 +00007804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007805os_close_impl(PyObject *module, int fd)
7806/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007807{
Larry Hastings2f936352014-08-05 14:04:04 +10007808 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007809 if (!_PyVerify_fd(fd))
7810 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007811 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7812 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7813 * for more details.
7814 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007816 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007818 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007819 Py_END_ALLOW_THREADS
7820 if (res < 0)
7821 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007822 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007823}
7824
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007825
Larry Hastings2f936352014-08-05 14:04:04 +10007826/*[clinic input]
7827os.closerange
7828
7829 fd_low: int
7830 fd_high: int
7831 /
7832
7833Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7834[clinic start generated code]*/
7835
Larry Hastings2f936352014-08-05 14:04:04 +10007836static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007837os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7838/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007839{
7840 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007841 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007842 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007843 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 if (_PyVerify_fd(i))
7845 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007846 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 Py_END_ALLOW_THREADS
7848 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007849}
7850
7851
Larry Hastings2f936352014-08-05 14:04:04 +10007852/*[clinic input]
7853os.dup -> int
7854
7855 fd: int
7856 /
7857
7858Return a duplicate of a file descriptor.
7859[clinic start generated code]*/
7860
Larry Hastings2f936352014-08-05 14:04:04 +10007861static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007862os_dup_impl(PyObject *module, int fd)
7863/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007864{
7865 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007866}
7867
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007868
Larry Hastings2f936352014-08-05 14:04:04 +10007869/*[clinic input]
7870os.dup2
7871 fd: int
7872 fd2: int
7873 inheritable: bool=True
7874
7875Duplicate file descriptor.
7876[clinic start generated code]*/
7877
Larry Hastings2f936352014-08-05 14:04:04 +10007878static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007879os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7880/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007881{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007882 int res;
7883#if defined(HAVE_DUP3) && \
7884 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7885 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7886 int dup3_works = -1;
7887#endif
7888
Victor Stinner8c62be82010-05-06 00:08:46 +00007889 if (!_PyVerify_fd_dup2(fd, fd2))
7890 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007891
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007892 /* dup2() can fail with EINTR if the target FD is already open, because it
7893 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7894 * upon close(), and therefore below.
7895 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007896#ifdef MS_WINDOWS
7897 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007898 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007899 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007900 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007901 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007902 if (res < 0)
7903 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007904
7905 /* Character files like console cannot be make non-inheritable */
7906 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7907 close(fd2);
7908 return NULL;
7909 }
7910
7911#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7912 Py_BEGIN_ALLOW_THREADS
7913 if (!inheritable)
7914 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7915 else
7916 res = dup2(fd, fd2);
7917 Py_END_ALLOW_THREADS
7918 if (res < 0)
7919 return posix_error();
7920
7921#else
7922
7923#ifdef HAVE_DUP3
7924 if (!inheritable && dup3_works != 0) {
7925 Py_BEGIN_ALLOW_THREADS
7926 res = dup3(fd, fd2, O_CLOEXEC);
7927 Py_END_ALLOW_THREADS
7928 if (res < 0) {
7929 if (dup3_works == -1)
7930 dup3_works = (errno != ENOSYS);
7931 if (dup3_works)
7932 return posix_error();
7933 }
7934 }
7935
7936 if (inheritable || dup3_works == 0)
7937 {
7938#endif
7939 Py_BEGIN_ALLOW_THREADS
7940 res = dup2(fd, fd2);
7941 Py_END_ALLOW_THREADS
7942 if (res < 0)
7943 return posix_error();
7944
7945 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7946 close(fd2);
7947 return NULL;
7948 }
7949#ifdef HAVE_DUP3
7950 }
7951#endif
7952
7953#endif
7954
Larry Hastings2f936352014-08-05 14:04:04 +10007955 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007956}
7957
Larry Hastings2f936352014-08-05 14:04:04 +10007958
Ross Lagerwall7807c352011-03-17 20:20:30 +02007959#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007960/*[clinic input]
7961os.lockf
7962
7963 fd: int
7964 An open file descriptor.
7965 command: int
7966 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7967 length: Py_off_t
7968 The number of bytes to lock, starting at the current position.
7969 /
7970
7971Apply, test or remove a POSIX lock on an open file descriptor.
7972
7973[clinic start generated code]*/
7974
Larry Hastings2f936352014-08-05 14:04:04 +10007975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007976os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7977/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007978{
7979 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007980
7981 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007982 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007983 Py_END_ALLOW_THREADS
7984
7985 if (res < 0)
7986 return posix_error();
7987
7988 Py_RETURN_NONE;
7989}
Larry Hastings2f936352014-08-05 14:04:04 +10007990#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007991
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007992
Larry Hastings2f936352014-08-05 14:04:04 +10007993/*[clinic input]
7994os.lseek -> Py_off_t
7995
7996 fd: int
7997 position: Py_off_t
7998 how: int
7999 /
8000
8001Set the position of a file descriptor. Return the new position.
8002
8003Return the new cursor position in number of bytes
8004relative to the beginning of the file.
8005[clinic start generated code]*/
8006
Larry Hastings2f936352014-08-05 14:04:04 +10008007static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008008os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
8009/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008010{
8011 Py_off_t result;
8012
8013 if (!_PyVerify_fd(fd)) {
8014 posix_error();
8015 return -1;
8016 }
Guido van Rossum687dd131993-05-17 08:34:16 +00008017#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008018 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8019 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008020 case 0: how = SEEK_SET; break;
8021 case 1: how = SEEK_CUR; break;
8022 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008023 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008024#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008025
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008027 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008028
Larry Hastings2f936352014-08-05 14:04:04 +10008029 if (!_PyVerify_fd(fd)) {
8030 posix_error();
8031 return -1;
8032 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008034 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008035#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008036 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008037#else
Larry Hastings2f936352014-08-05 14:04:04 +10008038 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008039#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008040 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008041 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008042 if (result < 0)
8043 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008044
Larry Hastings2f936352014-08-05 14:04:04 +10008045 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008046}
8047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008048
Larry Hastings2f936352014-08-05 14:04:04 +10008049/*[clinic input]
8050os.read
8051 fd: int
8052 length: Py_ssize_t
8053 /
8054
8055Read from a file descriptor. Returns a bytes object.
8056[clinic start generated code]*/
8057
Larry Hastings2f936352014-08-05 14:04:04 +10008058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008059os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8060/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008061{
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 Py_ssize_t n;
8063 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008064
8065 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008066 errno = EINVAL;
8067 return posix_error();
8068 }
Larry Hastings2f936352014-08-05 14:04:04 +10008069
8070#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008071 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008072 if (length > INT_MAX)
8073 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008074#endif
8075
8076 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008077 if (buffer == NULL)
8078 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008079
Victor Stinner66aab0c2015-03-19 22:53:20 +01008080 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8081 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008082 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008083 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008084 }
Larry Hastings2f936352014-08-05 14:04:04 +10008085
8086 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008087 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008088
Victor Stinner8c62be82010-05-06 00:08:46 +00008089 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008090}
8091
Ross Lagerwall7807c352011-03-17 20:20:30 +02008092#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8093 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008094static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8096{
8097 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008098 Py_ssize_t blen, total = 0;
8099
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100 *iov = PyMem_New(struct iovec, cnt);
8101 if (*iov == NULL) {
8102 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008103 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106 *buf = PyMem_New(Py_buffer, cnt);
8107 if (*buf == NULL) {
8108 PyMem_Del(*iov);
8109 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008110 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008111 }
8112
8113 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008114 PyObject *item = PySequence_GetItem(seq, i);
8115 if (item == NULL)
8116 goto fail;
8117 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8118 Py_DECREF(item);
8119 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008120 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008121 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008122 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008123 blen = (*buf)[i].len;
8124 (*iov)[i].iov_len = blen;
8125 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008126 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008127 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008128
8129fail:
8130 PyMem_Del(*iov);
8131 for (j = 0; j < i; j++) {
8132 PyBuffer_Release(&(*buf)[j]);
8133 }
8134 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008135 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008136}
8137
8138static void
8139iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8140{
8141 int i;
8142 PyMem_Del(iov);
8143 for (i = 0; i < cnt; i++) {
8144 PyBuffer_Release(&buf[i]);
8145 }
8146 PyMem_Del(buf);
8147}
8148#endif
8149
Larry Hastings2f936352014-08-05 14:04:04 +10008150
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008152/*[clinic input]
8153os.readv -> Py_ssize_t
8154
8155 fd: int
8156 buffers: object
8157 /
8158
8159Read from a file descriptor fd into an iterable of buffers.
8160
8161The buffers should be mutable buffers accepting bytes.
8162readv will transfer data into each buffer until it is full
8163and then move on to the next buffer in the sequence to hold
8164the rest of the data.
8165
8166readv returns the total number of bytes read,
8167which may be less than the total capacity of all the buffers.
8168[clinic start generated code]*/
8169
Larry Hastings2f936352014-08-05 14:04:04 +10008170static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008171os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8172/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008173{
8174 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008176 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008177 struct iovec *iov;
8178 Py_buffer *buf;
8179
Larry Hastings2f936352014-08-05 14:04:04 +10008180 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008181 PyErr_SetString(PyExc_TypeError,
8182 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008183 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008184 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008185
Larry Hastings2f936352014-08-05 14:04:04 +10008186 cnt = PySequence_Size(buffers);
8187
8188 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8189 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008191 do {
8192 Py_BEGIN_ALLOW_THREADS
8193 n = readv(fd, iov, cnt);
8194 Py_END_ALLOW_THREADS
8195 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008196
8197 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008198 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008199 if (!async_err)
8200 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008201 return -1;
8202 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008203
Larry Hastings2f936352014-08-05 14:04:04 +10008204 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008205}
Larry Hastings2f936352014-08-05 14:04:04 +10008206#endif /* HAVE_READV */
8207
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208
8209#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008210/*[clinic input]
8211# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8212os.pread
8213
8214 fd: int
8215 length: int
8216 offset: Py_off_t
8217 /
8218
8219Read a number of bytes from a file descriptor starting at a particular offset.
8220
8221Read length bytes from file descriptor fd, starting at offset bytes from
8222the beginning of the file. The file offset remains unchanged.
8223[clinic start generated code]*/
8224
Larry Hastings2f936352014-08-05 14:04:04 +10008225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008226os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8227/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008228{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008229 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008230 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008231 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008232
Larry Hastings2f936352014-08-05 14:04:04 +10008233 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008234 errno = EINVAL;
8235 return posix_error();
8236 }
Larry Hastings2f936352014-08-05 14:04:04 +10008237 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008238 if (buffer == NULL)
8239 return NULL;
8240 if (!_PyVerify_fd(fd)) {
8241 Py_DECREF(buffer);
8242 return posix_error();
8243 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008244
8245 do {
8246 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008247 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008248 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008249 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008250 Py_END_ALLOW_THREADS
8251 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8252
Ross Lagerwall7807c352011-03-17 20:20:30 +02008253 if (n < 0) {
8254 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008255 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008256 }
Larry Hastings2f936352014-08-05 14:04:04 +10008257 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008258 _PyBytes_Resize(&buffer, n);
8259 return buffer;
8260}
Larry Hastings2f936352014-08-05 14:04:04 +10008261#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008262
Larry Hastings2f936352014-08-05 14:04:04 +10008263
8264/*[clinic input]
8265os.write -> Py_ssize_t
8266
8267 fd: int
8268 data: Py_buffer
8269 /
8270
8271Write a bytes object to a file descriptor.
8272[clinic start generated code]*/
8273
Larry Hastings2f936352014-08-05 14:04:04 +10008274static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008275os_write_impl(PyObject *module, int fd, Py_buffer *data)
8276/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008277{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008278 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008279}
8280
8281#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008282PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008283"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008284sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008285 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008286Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008287
Larry Hastings2f936352014-08-05 14:04:04 +10008288/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008289static PyObject *
8290posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8291{
8292 int in, out;
8293 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008294 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008295 off_t offset;
8296
8297#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8298#ifndef __APPLE__
8299 Py_ssize_t len;
8300#endif
8301 PyObject *headers = NULL, *trailers = NULL;
8302 Py_buffer *hbuf, *tbuf;
8303 off_t sbytes;
8304 struct sf_hdtr sf;
8305 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008306 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008307 static char *keywords[] = {"out", "in",
8308 "offset", "count",
8309 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008310
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008311 sf.headers = NULL;
8312 sf.trailers = NULL;
8313
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314#ifdef __APPLE__
8315 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008316 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317#else
8318 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008319 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320#endif
8321 &headers, &trailers, &flags))
8322 return NULL;
8323 if (headers != NULL) {
8324 if (!PySequence_Check(headers)) {
8325 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008326 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327 return NULL;
8328 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008329 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008330 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008331 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008332 (i = iov_setup(&(sf.headers), &hbuf,
8333 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008334 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008335#ifdef __APPLE__
8336 sbytes += i;
8337#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338 }
8339 }
8340 if (trailers != NULL) {
8341 if (!PySequence_Check(trailers)) {
8342 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008343 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008344 return NULL;
8345 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008346 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008347 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008348 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008349 (i = iov_setup(&(sf.trailers), &tbuf,
8350 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008351 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008352#ifdef __APPLE__
8353 sbytes += i;
8354#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008355 }
8356 }
8357
Steve Dower8fc89802015-04-12 00:26:27 -04008358 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008359 do {
8360 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008361#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008362 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008363#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008364 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008365#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008366 Py_END_ALLOW_THREADS
8367 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008368 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008369
8370 if (sf.headers != NULL)
8371 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8372 if (sf.trailers != NULL)
8373 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8374
8375 if (ret < 0) {
8376 if ((errno == EAGAIN) || (errno == EBUSY)) {
8377 if (sbytes != 0) {
8378 // some data has been sent
8379 goto done;
8380 }
8381 else {
8382 // no data has been sent; upper application is supposed
8383 // to retry on EAGAIN or EBUSY
8384 return posix_error();
8385 }
8386 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008387 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008388 }
8389 goto done;
8390
8391done:
8392 #if !defined(HAVE_LARGEFILE_SUPPORT)
8393 return Py_BuildValue("l", sbytes);
8394 #else
8395 return Py_BuildValue("L", sbytes);
8396 #endif
8397
8398#else
8399 Py_ssize_t count;
8400 PyObject *offobj;
8401 static char *keywords[] = {"out", "in",
8402 "offset", "count", NULL};
8403 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8404 keywords, &out, &in, &offobj, &count))
8405 return NULL;
8406#ifdef linux
8407 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008408 do {
8409 Py_BEGIN_ALLOW_THREADS
8410 ret = sendfile(out, in, NULL, count);
8411 Py_END_ALLOW_THREADS
8412 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008413 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008414 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008415 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008416 }
8417#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008418 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008419 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008420
8421 do {
8422 Py_BEGIN_ALLOW_THREADS
8423 ret = sendfile(out, in, &offset, count);
8424 Py_END_ALLOW_THREADS
8425 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008426 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008427 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008428 return Py_BuildValue("n", ret);
8429#endif
8430}
Larry Hastings2f936352014-08-05 14:04:04 +10008431#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008432
Larry Hastings2f936352014-08-05 14:04:04 +10008433
8434/*[clinic input]
8435os.fstat
8436
8437 fd : int
8438
8439Perform a stat system call on the given file descriptor.
8440
8441Like stat(), but for an open file descriptor.
8442Equivalent to os.stat(fd).
8443[clinic start generated code]*/
8444
Larry Hastings2f936352014-08-05 14:04:04 +10008445static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008446os_fstat_impl(PyObject *module, int fd)
8447/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008448{
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 STRUCT_STAT st;
8450 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008451 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008452
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008453 do {
8454 Py_BEGIN_ALLOW_THREADS
8455 res = FSTAT(fd, &st);
8456 Py_END_ALLOW_THREADS
8457 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008458 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008459#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008460 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008461#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008462 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008463#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 }
Tim Peters5aa91602002-01-30 05:46:57 +00008465
Victor Stinner4195b5c2012-02-08 23:03:19 +01008466 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008467}
8468
Larry Hastings2f936352014-08-05 14:04:04 +10008469
8470/*[clinic input]
8471os.isatty -> bool
8472 fd: int
8473 /
8474
8475Return True if the fd is connected to a terminal.
8476
8477Return True if the file descriptor is an open file descriptor
8478connected to the slave end of a terminal.
8479[clinic start generated code]*/
8480
Larry Hastings2f936352014-08-05 14:04:04 +10008481static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008482os_isatty_impl(PyObject *module, int fd)
8483/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008484{
Steve Dower8fc89802015-04-12 00:26:27 -04008485 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008486 if (!_PyVerify_fd(fd))
8487 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008488 _Py_BEGIN_SUPPRESS_IPH
8489 return_value = isatty(fd);
8490 _Py_END_SUPPRESS_IPH
8491 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008492}
8493
8494
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008495#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008496/*[clinic input]
8497os.pipe
8498
8499Create a pipe.
8500
8501Returns a tuple of two file descriptors:
8502 (read_fd, write_fd)
8503[clinic start generated code]*/
8504
Larry Hastings2f936352014-08-05 14:04:04 +10008505static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008506os_pipe_impl(PyObject *module)
8507/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008508{
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008510#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008511 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008512 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008513 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008514#else
8515 int res;
8516#endif
8517
8518#ifdef MS_WINDOWS
8519 attr.nLength = sizeof(attr);
8520 attr.lpSecurityDescriptor = NULL;
8521 attr.bInheritHandle = FALSE;
8522
8523 Py_BEGIN_ALLOW_THREADS
8524 ok = CreatePipe(&read, &write, &attr, 0);
8525 if (ok) {
8526 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8527 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8528 if (fds[0] == -1 || fds[1] == -1) {
8529 CloseHandle(read);
8530 CloseHandle(write);
8531 ok = 0;
8532 }
8533 }
8534 Py_END_ALLOW_THREADS
8535
Victor Stinner8c62be82010-05-06 00:08:46 +00008536 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008537 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008538#else
8539
8540#ifdef HAVE_PIPE2
8541 Py_BEGIN_ALLOW_THREADS
8542 res = pipe2(fds, O_CLOEXEC);
8543 Py_END_ALLOW_THREADS
8544
8545 if (res != 0 && errno == ENOSYS)
8546 {
8547#endif
8548 Py_BEGIN_ALLOW_THREADS
8549 res = pipe(fds);
8550 Py_END_ALLOW_THREADS
8551
8552 if (res == 0) {
8553 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8554 close(fds[0]);
8555 close(fds[1]);
8556 return NULL;
8557 }
8558 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8559 close(fds[0]);
8560 close(fds[1]);
8561 return NULL;
8562 }
8563 }
8564#ifdef HAVE_PIPE2
8565 }
8566#endif
8567
8568 if (res != 0)
8569 return PyErr_SetFromErrno(PyExc_OSError);
8570#endif /* !MS_WINDOWS */
8571 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008572}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008573#endif /* HAVE_PIPE */
8574
Larry Hastings2f936352014-08-05 14:04:04 +10008575
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008576#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008577/*[clinic input]
8578os.pipe2
8579
8580 flags: int
8581 /
8582
8583Create a pipe with flags set atomically.
8584
8585Returns a tuple of two file descriptors:
8586 (read_fd, write_fd)
8587
8588flags can be constructed by ORing together one or more of these values:
8589O_NONBLOCK, O_CLOEXEC.
8590[clinic start generated code]*/
8591
Larry Hastings2f936352014-08-05 14:04:04 +10008592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008593os_pipe2_impl(PyObject *module, int flags)
8594/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008595{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008596 int fds[2];
8597 int res;
8598
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008599 res = pipe2(fds, flags);
8600 if (res != 0)
8601 return posix_error();
8602 return Py_BuildValue("(ii)", fds[0], fds[1]);
8603}
8604#endif /* HAVE_PIPE2 */
8605
Larry Hastings2f936352014-08-05 14:04:04 +10008606
Ross Lagerwall7807c352011-03-17 20:20:30 +02008607#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008608/*[clinic input]
8609os.writev -> Py_ssize_t
8610 fd: int
8611 buffers: object
8612 /
8613
8614Iterate over buffers, and write the contents of each to a file descriptor.
8615
8616Returns the total number of bytes written.
8617buffers must be a sequence of bytes-like objects.
8618[clinic start generated code]*/
8619
Larry Hastings2f936352014-08-05 14:04:04 +10008620static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008621os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8622/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008623{
8624 int cnt;
8625 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008626 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008627 struct iovec *iov;
8628 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008629
8630 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008631 PyErr_SetString(PyExc_TypeError,
8632 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008633 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008634 }
Larry Hastings2f936352014-08-05 14:04:04 +10008635 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636
Larry Hastings2f936352014-08-05 14:04:04 +10008637 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8638 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008639 }
8640
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008641 do {
8642 Py_BEGIN_ALLOW_THREADS
8643 result = writev(fd, iov, cnt);
8644 Py_END_ALLOW_THREADS
8645 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008646
8647 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008649 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008650
Georg Brandl306336b2012-06-24 12:55:33 +02008651 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008652}
Larry Hastings2f936352014-08-05 14:04:04 +10008653#endif /* HAVE_WRITEV */
8654
8655
8656#ifdef HAVE_PWRITE
8657/*[clinic input]
8658os.pwrite -> Py_ssize_t
8659
8660 fd: int
8661 buffer: Py_buffer
8662 offset: Py_off_t
8663 /
8664
8665Write bytes to a file descriptor starting at a particular offset.
8666
8667Write buffer to fd, starting at offset bytes from the beginning of
8668the file. Returns the number of bytes writte. Does not change the
8669current file offset.
8670[clinic start generated code]*/
8671
Larry Hastings2f936352014-08-05 14:04:04 +10008672static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008673os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8674/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008675{
8676 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008677 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008678
8679 if (!_PyVerify_fd(fd)) {
8680 posix_error();
8681 return -1;
8682 }
8683
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 do {
8685 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008686 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008687 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008688 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008689 Py_END_ALLOW_THREADS
8690 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008691
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008693 posix_error();
8694 return size;
8695}
8696#endif /* HAVE_PWRITE */
8697
8698
8699#ifdef HAVE_MKFIFO
8700/*[clinic input]
8701os.mkfifo
8702
8703 path: path_t
8704 mode: int=0o666
8705 *
8706 dir_fd: dir_fd(requires='mkfifoat')=None
8707
8708Create a "fifo" (a POSIX named pipe).
8709
8710If dir_fd is not None, it should be a file descriptor open to a directory,
8711 and path should be relative; path will then be relative to that directory.
8712dir_fd may not be implemented on your platform.
8713 If it is unavailable, using it will raise a NotImplementedError.
8714[clinic start generated code]*/
8715
Larry Hastings2f936352014-08-05 14:04:04 +10008716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008717os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8718/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008719{
8720 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008721 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008722
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008723 do {
8724 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008725#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008726 if (dir_fd != DEFAULT_DIR_FD)
8727 result = mkfifoat(dir_fd, path->narrow, mode);
8728 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008729#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008730 result = mkfifo(path->narrow, mode);
8731 Py_END_ALLOW_THREADS
8732 } while (result != 0 && errno == EINTR &&
8733 !(async_err = PyErr_CheckSignals()));
8734 if (result != 0)
8735 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008736
8737 Py_RETURN_NONE;
8738}
8739#endif /* HAVE_MKFIFO */
8740
8741
8742#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8743/*[clinic input]
8744os.mknod
8745
8746 path: path_t
8747 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008748 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008749 *
8750 dir_fd: dir_fd(requires='mknodat')=None
8751
8752Create a node in the file system.
8753
8754Create a node in the file system (file, device special file or named pipe)
8755at path. mode specifies both the permissions to use and the
8756type of node to be created, being combined (bitwise OR) with one of
8757S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8758device defines the newly created device special file (probably using
8759os.makedev()). Otherwise device is ignored.
8760
8761If dir_fd is not None, it should be a file descriptor open to a directory,
8762 and path should be relative; path will then be relative to that directory.
8763dir_fd may not be implemented on your platform.
8764 If it is unavailable, using it will raise a NotImplementedError.
8765[clinic start generated code]*/
8766
Larry Hastings2f936352014-08-05 14:04:04 +10008767static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008768os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008769 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008770/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008771{
8772 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008773 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008774
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008775 do {
8776 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008777#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008778 if (dir_fd != DEFAULT_DIR_FD)
8779 result = mknodat(dir_fd, path->narrow, mode, device);
8780 else
Larry Hastings2f936352014-08-05 14:04:04 +10008781#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008782 result = mknod(path->narrow, mode, device);
8783 Py_END_ALLOW_THREADS
8784 } while (result != 0 && errno == EINTR &&
8785 !(async_err = PyErr_CheckSignals()));
8786 if (result != 0)
8787 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008788
8789 Py_RETURN_NONE;
8790}
8791#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8792
8793
8794#ifdef HAVE_DEVICE_MACROS
8795/*[clinic input]
8796os.major -> unsigned_int
8797
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008798 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008799 /
8800
8801Extracts a device major number from a raw device number.
8802[clinic start generated code]*/
8803
Larry Hastings2f936352014-08-05 14:04:04 +10008804static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008805os_major_impl(PyObject *module, dev_t device)
8806/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008807{
8808 return major(device);
8809}
8810
8811
8812/*[clinic input]
8813os.minor -> unsigned_int
8814
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008815 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008816 /
8817
8818Extracts a device minor number from a raw device number.
8819[clinic start generated code]*/
8820
Larry Hastings2f936352014-08-05 14:04:04 +10008821static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008822os_minor_impl(PyObject *module, dev_t device)
8823/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008824{
8825 return minor(device);
8826}
8827
8828
8829/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008830os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008831
8832 major: int
8833 minor: int
8834 /
8835
8836Composes a raw device number from the major and minor device numbers.
8837[clinic start generated code]*/
8838
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008839static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008840os_makedev_impl(PyObject *module, int major, int minor)
8841/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008842{
8843 return makedev(major, minor);
8844}
8845#endif /* HAVE_DEVICE_MACROS */
8846
8847
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008848#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008849/*[clinic input]
8850os.ftruncate
8851
8852 fd: int
8853 length: Py_off_t
8854 /
8855
8856Truncate a file, specified by file descriptor, to a specific length.
8857[clinic start generated code]*/
8858
Larry Hastings2f936352014-08-05 14:04:04 +10008859static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008860os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8861/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008862{
8863 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008864 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008865
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008866 if (!_PyVerify_fd(fd))
8867 return posix_error();
8868
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008869 do {
8870 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008871 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008872#ifdef MS_WINDOWS
8873 result = _chsize_s(fd, length);
8874#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008875 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008876#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008877 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008878 Py_END_ALLOW_THREADS
8879 } while (result != 0 && errno == EINTR &&
8880 !(async_err = PyErr_CheckSignals()));
8881 if (result != 0)
8882 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008883 Py_RETURN_NONE;
8884}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008885#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008886
8887
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008888#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008889/*[clinic input]
8890os.truncate
8891 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8892 length: Py_off_t
8893
8894Truncate a file, specified by path, to a specific length.
8895
8896On some platforms, path may also be specified as an open file descriptor.
8897 If this functionality is unavailable, using it raises an exception.
8898[clinic start generated code]*/
8899
Larry Hastings2f936352014-08-05 14:04:04 +10008900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008901os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8902/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008903{
8904 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008905#ifdef MS_WINDOWS
8906 int fd;
8907#endif
8908
8909 if (path->fd != -1)
8910 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008911
8912 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008913 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008914#ifdef MS_WINDOWS
8915 if (path->wide)
8916 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008917 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008918 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008919 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008920 result = -1;
8921 else {
8922 result = _chsize_s(fd, length);
8923 close(fd);
8924 if (result < 0)
8925 errno = result;
8926 }
8927#else
8928 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008929#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008930 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008931 Py_END_ALLOW_THREADS
8932 if (result < 0)
8933 return path_error(path);
8934
8935 Py_RETURN_NONE;
8936}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008937#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008938
Ross Lagerwall7807c352011-03-17 20:20:30 +02008939
Victor Stinnerd6b17692014-09-30 12:20:05 +02008940/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8941 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8942 defined, which is the case in Python on AIX. AIX bug report:
8943 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8944#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8945# define POSIX_FADVISE_AIX_BUG
8946#endif
8947
Victor Stinnerec39e262014-09-30 12:35:58 +02008948
Victor Stinnerd6b17692014-09-30 12:20:05 +02008949#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008950/*[clinic input]
8951os.posix_fallocate
8952
8953 fd: int
8954 offset: Py_off_t
8955 length: Py_off_t
8956 /
8957
8958Ensure a file has allocated at least a particular number of bytes on disk.
8959
8960Ensure that the file specified by fd encompasses a range of bytes
8961starting at offset bytes from the beginning and continuing for length bytes.
8962[clinic start generated code]*/
8963
Larry Hastings2f936352014-08-05 14:04:04 +10008964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008965os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008966 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008967/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008968{
8969 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008970 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008971
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008972 do {
8973 Py_BEGIN_ALLOW_THREADS
8974 result = posix_fallocate(fd, offset, length);
8975 Py_END_ALLOW_THREADS
8976 } while (result != 0 && errno == EINTR &&
8977 !(async_err = PyErr_CheckSignals()));
8978 if (result != 0)
8979 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008980 Py_RETURN_NONE;
8981}
Victor Stinnerec39e262014-09-30 12:35:58 +02008982#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008983
Ross Lagerwall7807c352011-03-17 20:20:30 +02008984
Victor Stinnerd6b17692014-09-30 12:20:05 +02008985#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008986/*[clinic input]
8987os.posix_fadvise
8988
8989 fd: int
8990 offset: Py_off_t
8991 length: Py_off_t
8992 advice: int
8993 /
8994
8995Announce an intention to access data in a specific pattern.
8996
8997Announce an intention to access data in a specific pattern, thus allowing
8998the kernel to make optimizations.
8999The advice applies to the region of the file specified by fd starting at
9000offset and continuing for length bytes.
9001advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
9002POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
9003POSIX_FADV_DONTNEED.
9004[clinic start generated code]*/
9005
Larry Hastings2f936352014-08-05 14:04:04 +10009006static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009007os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04009008 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009009/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009010{
9011 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009012 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009013
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009014 do {
9015 Py_BEGIN_ALLOW_THREADS
9016 result = posix_fadvise(fd, offset, length, advice);
9017 Py_END_ALLOW_THREADS
9018 } while (result != 0 && errno == EINTR &&
9019 !(async_err = PyErr_CheckSignals()));
9020 if (result != 0)
9021 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009022 Py_RETURN_NONE;
9023}
Victor Stinnerec39e262014-09-30 12:35:58 +02009024#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009025
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009026#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009027
Fred Drake762e2061999-08-26 17:23:54 +00009028/* Save putenv() parameters as values here, so we can collect them when they
9029 * get re-set with another call for the same key. */
9030static PyObject *posix_putenv_garbage;
9031
Larry Hastings2f936352014-08-05 14:04:04 +10009032static void
9033posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009034{
Larry Hastings2f936352014-08-05 14:04:04 +10009035 /* Install the first arg and newstr in posix_putenv_garbage;
9036 * this will cause previous value to be collected. This has to
9037 * happen after the real putenv() call because the old value
9038 * was still accessible until then. */
9039 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9040 /* really not much we can do; just leak */
9041 PyErr_Clear();
9042 else
9043 Py_DECREF(value);
9044}
9045
9046
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009047#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009048/*[clinic input]
9049os.putenv
9050
9051 name: unicode
9052 value: unicode
9053 /
9054
9055Change or add an environment variable.
9056[clinic start generated code]*/
9057
Larry Hastings2f936352014-08-05 14:04:04 +10009058static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009059os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9060/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009061{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009062 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10009063
9064 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9065 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009066 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009067 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009068 }
Larry Hastings2f936352014-08-05 14:04:04 +10009069 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009070 PyErr_Format(PyExc_ValueError,
9071 "the environment variable is longer than %u characters",
9072 _MAX_ENV);
9073 goto error;
9074 }
9075
Larry Hastings2f936352014-08-05 14:04:04 +10009076 env = PyUnicode_AsUnicode(unicode);
9077 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009078 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009079 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009080 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009081 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009082 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009083
Larry Hastings2f936352014-08-05 14:04:04 +10009084 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009085 Py_RETURN_NONE;
9086
9087error:
Larry Hastings2f936352014-08-05 14:04:04 +10009088 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009089 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009090}
Larry Hastings2f936352014-08-05 14:04:04 +10009091#else /* MS_WINDOWS */
9092/*[clinic input]
9093os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009094
Larry Hastings2f936352014-08-05 14:04:04 +10009095 name: FSConverter
9096 value: FSConverter
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=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009105{
9106 PyObject *bytes = NULL;
9107 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009108 const char *name_string = PyBytes_AsString(name);
9109 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009110
9111 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9112 if (bytes == NULL) {
9113 PyErr_NoMemory();
9114 return NULL;
9115 }
9116
9117 env = PyBytes_AS_STRING(bytes);
9118 if (putenv(env)) {
9119 Py_DECREF(bytes);
9120 return posix_error();
9121 }
9122
9123 posix_putenv_garbage_setitem(name, bytes);
9124 Py_RETURN_NONE;
9125}
9126#endif /* MS_WINDOWS */
9127#endif /* HAVE_PUTENV */
9128
9129
9130#ifdef HAVE_UNSETENV
9131/*[clinic input]
9132os.unsetenv
9133 name: FSConverter
9134 /
9135
9136Delete an environment variable.
9137[clinic start generated code]*/
9138
Larry Hastings2f936352014-08-05 14:04:04 +10009139static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009140os_unsetenv_impl(PyObject *module, PyObject *name)
9141/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009142{
Victor Stinner984890f2011-11-24 13:53:38 +01009143#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009144 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009145#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009146
Victor Stinner984890f2011-11-24 13:53:38 +01009147#ifdef HAVE_BROKEN_UNSETENV
9148 unsetenv(PyBytes_AS_STRING(name));
9149#else
Victor Stinner65170952011-11-22 22:16:17 +01009150 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009151 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009152 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009153#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009154
Victor Stinner8c62be82010-05-06 00:08:46 +00009155 /* Remove the key from posix_putenv_garbage;
9156 * this will cause it to be collected. This has to
9157 * happen after the real unsetenv() call because the
9158 * old value was still accessible until then.
9159 */
Victor Stinner65170952011-11-22 22:16:17 +01009160 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009161 /* really not much we can do; just leak */
9162 PyErr_Clear();
9163 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009164 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009165}
Larry Hastings2f936352014-08-05 14:04:04 +10009166#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009167
Larry Hastings2f936352014-08-05 14:04:04 +10009168
9169/*[clinic input]
9170os.strerror
9171
9172 code: int
9173 /
9174
9175Translate an error code to a message string.
9176[clinic start generated code]*/
9177
Larry Hastings2f936352014-08-05 14:04:04 +10009178static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009179os_strerror_impl(PyObject *module, int code)
9180/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009181{
9182 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009183 if (message == NULL) {
9184 PyErr_SetString(PyExc_ValueError,
9185 "strerror() argument out of range");
9186 return NULL;
9187 }
Victor Stinner1b579672011-12-17 05:47:23 +01009188 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009189}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009190
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009191
Guido van Rossumc9641791998-08-04 15:26:23 +00009192#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009193#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009194/*[clinic input]
9195os.WCOREDUMP -> bool
9196
9197 status: int
9198 /
9199
9200Return True if the process returning status was dumped to a core file.
9201[clinic start generated code]*/
9202
Larry Hastings2f936352014-08-05 14:04:04 +10009203static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009204os_WCOREDUMP_impl(PyObject *module, int status)
9205/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009206{
9207 WAIT_TYPE wait_status;
9208 WAIT_STATUS_INT(wait_status) = status;
9209 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009210}
9211#endif /* WCOREDUMP */
9212
Larry Hastings2f936352014-08-05 14:04:04 +10009213
Fred Drake106c1a02002-04-23 15:58:02 +00009214#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009215/*[clinic input]
9216os.WIFCONTINUED -> bool
9217
9218 status: int
9219
9220Return True if a particular process was continued from a job control stop.
9221
9222Return True if the process returning status was continued from a
9223job control stop.
9224[clinic start generated code]*/
9225
Larry Hastings2f936352014-08-05 14:04:04 +10009226static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009227os_WIFCONTINUED_impl(PyObject *module, int status)
9228/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009229{
9230 WAIT_TYPE wait_status;
9231 WAIT_STATUS_INT(wait_status) = status;
9232 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009233}
9234#endif /* WIFCONTINUED */
9235
Larry Hastings2f936352014-08-05 14:04:04 +10009236
Guido van Rossumc9641791998-08-04 15:26:23 +00009237#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009238/*[clinic input]
9239os.WIFSTOPPED -> bool
9240
9241 status: int
9242
9243Return True if the process returning status was stopped.
9244[clinic start generated code]*/
9245
Larry Hastings2f936352014-08-05 14:04:04 +10009246static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009247os_WIFSTOPPED_impl(PyObject *module, int status)
9248/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009249{
9250 WAIT_TYPE wait_status;
9251 WAIT_STATUS_INT(wait_status) = status;
9252 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009253}
9254#endif /* WIFSTOPPED */
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256
Guido van Rossumc9641791998-08-04 15:26:23 +00009257#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009258/*[clinic input]
9259os.WIFSIGNALED -> bool
9260
9261 status: int
9262
9263Return True if the process returning status was terminated by a signal.
9264[clinic start generated code]*/
9265
Larry Hastings2f936352014-08-05 14:04:04 +10009266static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009267os_WIFSIGNALED_impl(PyObject *module, int status)
9268/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009269{
9270 WAIT_TYPE wait_status;
9271 WAIT_STATUS_INT(wait_status) = status;
9272 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009273}
9274#endif /* WIFSIGNALED */
9275
Larry Hastings2f936352014-08-05 14:04:04 +10009276
Guido van Rossumc9641791998-08-04 15:26:23 +00009277#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009278/*[clinic input]
9279os.WIFEXITED -> bool
9280
9281 status: int
9282
9283Return True if the process returning status exited via the exit() system call.
9284[clinic start generated code]*/
9285
Larry Hastings2f936352014-08-05 14:04:04 +10009286static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009287os_WIFEXITED_impl(PyObject *module, int status)
9288/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009289{
9290 WAIT_TYPE wait_status;
9291 WAIT_STATUS_INT(wait_status) = status;
9292 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009293}
9294#endif /* WIFEXITED */
9295
Larry Hastings2f936352014-08-05 14:04:04 +10009296
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009297#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009298/*[clinic input]
9299os.WEXITSTATUS -> int
9300
9301 status: int
9302
9303Return the process return code from status.
9304[clinic start generated code]*/
9305
Larry Hastings2f936352014-08-05 14:04:04 +10009306static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009307os_WEXITSTATUS_impl(PyObject *module, int status)
9308/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009309{
9310 WAIT_TYPE wait_status;
9311 WAIT_STATUS_INT(wait_status) = status;
9312 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009313}
9314#endif /* WEXITSTATUS */
9315
Larry Hastings2f936352014-08-05 14:04:04 +10009316
Guido van Rossumc9641791998-08-04 15:26:23 +00009317#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009318/*[clinic input]
9319os.WTERMSIG -> int
9320
9321 status: int
9322
9323Return the signal that terminated the process that provided the status value.
9324[clinic start generated code]*/
9325
Larry Hastings2f936352014-08-05 14:04:04 +10009326static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009327os_WTERMSIG_impl(PyObject *module, int status)
9328/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009329{
9330 WAIT_TYPE wait_status;
9331 WAIT_STATUS_INT(wait_status) = status;
9332 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009333}
9334#endif /* WTERMSIG */
9335
Larry Hastings2f936352014-08-05 14:04:04 +10009336
Guido van Rossumc9641791998-08-04 15:26:23 +00009337#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009338/*[clinic input]
9339os.WSTOPSIG -> int
9340
9341 status: int
9342
9343Return the signal that stopped the process that provided the status value.
9344[clinic start generated code]*/
9345
Larry Hastings2f936352014-08-05 14:04:04 +10009346static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009347os_WSTOPSIG_impl(PyObject *module, int status)
9348/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009349{
9350 WAIT_TYPE wait_status;
9351 WAIT_STATUS_INT(wait_status) = status;
9352 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009353}
9354#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009355#endif /* HAVE_SYS_WAIT_H */
9356
9357
Thomas Wouters477c8d52006-05-27 19:21:47 +00009358#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009359#ifdef _SCO_DS
9360/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9361 needed definitions in sys/statvfs.h */
9362#define _SVID3
9363#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009364#include <sys/statvfs.h>
9365
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009366static PyObject*
9367_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9369 if (v == NULL)
9370 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009371
9372#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009373 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9374 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9375 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9376 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9377 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9378 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9379 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9380 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9381 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9382 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009383#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9385 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9386 PyStructSequence_SET_ITEM(v, 2,
9387 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9388 PyStructSequence_SET_ITEM(v, 3,
9389 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9390 PyStructSequence_SET_ITEM(v, 4,
9391 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9392 PyStructSequence_SET_ITEM(v, 5,
9393 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9394 PyStructSequence_SET_ITEM(v, 6,
9395 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9396 PyStructSequence_SET_ITEM(v, 7,
9397 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9398 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9399 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009400#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009401 if (PyErr_Occurred()) {
9402 Py_DECREF(v);
9403 return NULL;
9404 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009405
Victor Stinner8c62be82010-05-06 00:08:46 +00009406 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009407}
9408
Larry Hastings2f936352014-08-05 14:04:04 +10009409
9410/*[clinic input]
9411os.fstatvfs
9412 fd: int
9413 /
9414
9415Perform an fstatvfs system call on the given fd.
9416
9417Equivalent to statvfs(fd).
9418[clinic start generated code]*/
9419
Larry Hastings2f936352014-08-05 14:04:04 +10009420static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009421os_fstatvfs_impl(PyObject *module, int fd)
9422/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009423{
9424 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009425 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009426 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009427
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009428 do {
9429 Py_BEGIN_ALLOW_THREADS
9430 result = fstatvfs(fd, &st);
9431 Py_END_ALLOW_THREADS
9432 } while (result != 0 && errno == EINTR &&
9433 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009434 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009435 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009436
Victor Stinner8c62be82010-05-06 00:08:46 +00009437 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009438}
Larry Hastings2f936352014-08-05 14:04:04 +10009439#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009440
9441
Thomas Wouters477c8d52006-05-27 19:21:47 +00009442#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009443#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009444/*[clinic input]
9445os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009446
Larry Hastings2f936352014-08-05 14:04:04 +10009447 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9448
9449Perform a statvfs system call on the given path.
9450
9451path may always be specified as a string.
9452On some platforms, path may also be specified as an open file descriptor.
9453 If this functionality is unavailable, using it raises an exception.
9454[clinic start generated code]*/
9455
Larry Hastings2f936352014-08-05 14:04:04 +10009456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009457os_statvfs_impl(PyObject *module, path_t *path)
9458/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009459{
9460 int result;
9461 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009462
9463 Py_BEGIN_ALLOW_THREADS
9464#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009465 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009466#ifdef __APPLE__
9467 /* handle weak-linking on Mac OS X 10.3 */
9468 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009469 fd_specified("statvfs", path->fd);
9470 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009471 }
9472#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009473 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009474 }
9475 else
9476#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009477 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009478 Py_END_ALLOW_THREADS
9479
9480 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009481 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009482 }
9483
Larry Hastings2f936352014-08-05 14:04:04 +10009484 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009485}
Larry Hastings2f936352014-08-05 14:04:04 +10009486#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9487
Guido van Rossum94f6f721999-01-06 18:42:14 +00009488
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009489#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009490/*[clinic input]
9491os._getdiskusage
9492
9493 path: Py_UNICODE
9494
9495Return disk usage statistics about the given path as a (total, free) tuple.
9496[clinic start generated code]*/
9497
Larry Hastings2f936352014-08-05 14:04:04 +10009498static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009499os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9500/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009501{
9502 BOOL retval;
9503 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009504
9505 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009506 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009507 Py_END_ALLOW_THREADS
9508 if (retval == 0)
9509 return PyErr_SetFromWindowsErr(0);
9510
9511 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9512}
Larry Hastings2f936352014-08-05 14:04:04 +10009513#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009514
9515
Fred Drakec9680921999-12-13 16:37:25 +00009516/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9517 * It maps strings representing configuration variable names to
9518 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009519 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009520 * rarely-used constants. There are three separate tables that use
9521 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009522 *
9523 * This code is always included, even if none of the interfaces that
9524 * need it are included. The #if hackery needed to avoid it would be
9525 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009526 */
9527struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009528 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009529 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009530};
9531
Fred Drake12c6e2d1999-12-14 21:25:03 +00009532static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009533conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009534 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009535{
Christian Heimes217cfd12007-12-02 14:31:20 +00009536 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009537 int value = _PyLong_AsInt(arg);
9538 if (value == -1 && PyErr_Occurred())
9539 return 0;
9540 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009541 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009542 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009543 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009544 /* look up the value in the table using a binary search */
9545 size_t lo = 0;
9546 size_t mid;
9547 size_t hi = tablesize;
9548 int cmp;
9549 const char *confname;
9550 if (!PyUnicode_Check(arg)) {
9551 PyErr_SetString(PyExc_TypeError,
9552 "configuration names must be strings or integers");
9553 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009555 confname = _PyUnicode_AsString(arg);
9556 if (confname == NULL)
9557 return 0;
9558 while (lo < hi) {
9559 mid = (lo + hi) / 2;
9560 cmp = strcmp(confname, table[mid].name);
9561 if (cmp < 0)
9562 hi = mid;
9563 else if (cmp > 0)
9564 lo = mid + 1;
9565 else {
9566 *valuep = table[mid].value;
9567 return 1;
9568 }
9569 }
9570 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9571 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009573}
9574
9575
9576#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9577static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009578#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009580#endif
9581#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009583#endif
Fred Drakec9680921999-12-13 16:37:25 +00009584#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
9602#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009603 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009604#endif
9605#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009606 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009607#endif
9608#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009609 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009610#endif
9611#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009612 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009613#endif
9614#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009615 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009616#endif
9617#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009618 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009619#endif
9620#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009621 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009622#endif
9623#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009624 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009625#endif
9626#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009627 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009628#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009629#ifdef _PC_ACL_ENABLED
9630 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9631#endif
9632#ifdef _PC_MIN_HOLE_SIZE
9633 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9634#endif
9635#ifdef _PC_ALLOC_SIZE_MIN
9636 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9637#endif
9638#ifdef _PC_REC_INCR_XFER_SIZE
9639 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9640#endif
9641#ifdef _PC_REC_MAX_XFER_SIZE
9642 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9643#endif
9644#ifdef _PC_REC_MIN_XFER_SIZE
9645 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9646#endif
9647#ifdef _PC_REC_XFER_ALIGN
9648 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9649#endif
9650#ifdef _PC_SYMLINK_MAX
9651 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9652#endif
9653#ifdef _PC_XATTR_ENABLED
9654 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9655#endif
9656#ifdef _PC_XATTR_EXISTS
9657 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9658#endif
9659#ifdef _PC_TIMESTAMP_RESOLUTION
9660 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9661#endif
Fred Drakec9680921999-12-13 16:37:25 +00009662};
9663
Fred Drakec9680921999-12-13 16:37:25 +00009664static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009665conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009666{
9667 return conv_confname(arg, valuep, posix_constants_pathconf,
9668 sizeof(posix_constants_pathconf)
9669 / sizeof(struct constdef));
9670}
9671#endif
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673
Fred Drakec9680921999-12-13 16:37:25 +00009674#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009675/*[clinic input]
9676os.fpathconf -> long
9677
9678 fd: int
9679 name: path_confname
9680 /
9681
9682Return the configuration limit name for the file descriptor fd.
9683
9684If there is no limit, return -1.
9685[clinic start generated code]*/
9686
Larry Hastings2f936352014-08-05 14:04:04 +10009687static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009688os_fpathconf_impl(PyObject *module, int fd, int name)
9689/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009690{
9691 long limit;
9692
9693 errno = 0;
9694 limit = fpathconf(fd, name);
9695 if (limit == -1 && errno != 0)
9696 posix_error();
9697
9698 return limit;
9699}
9700#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009701
9702
9703#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009704/*[clinic input]
9705os.pathconf -> long
9706 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9707 name: path_confname
9708
9709Return the configuration limit name for the file or directory path.
9710
9711If there is no limit, return -1.
9712On some platforms, path may also be specified as an open file descriptor.
9713 If this functionality is unavailable, using it raises an exception.
9714[clinic start generated code]*/
9715
Larry Hastings2f936352014-08-05 14:04:04 +10009716static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009717os_pathconf_impl(PyObject *module, path_t *path, int name)
9718/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009719{
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009721
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009723#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009724 if (path->fd != -1)
9725 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009726 else
9727#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009728 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 if (limit == -1 && errno != 0) {
9730 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009731 /* could be a path or name problem */
9732 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009733 else
Larry Hastings2f936352014-08-05 14:04:04 +10009734 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 }
Larry Hastings2f936352014-08-05 14:04:04 +10009736
9737 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009738}
Larry Hastings2f936352014-08-05 14:04:04 +10009739#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009740
9741#ifdef HAVE_CONFSTR
9742static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009743#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009745#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009746#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009748#endif
9749#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009751#endif
Fred Draked86ed291999-12-15 15:34:33 +00009752#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009754#endif
9755#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
9761#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
Fred Draked86ed291999-12-15 15:34:33 +00009788#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009790#endif
Fred Drakec9680921999-12-13 16:37:25 +00009791#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
Fred Draked86ed291999-12-15 15:34:33 +00009794#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009796#endif
9797#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009799#endif
9800#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009802#endif
9803#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009805#endif
Fred Drakec9680921999-12-13 16:37:25 +00009806#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
9827#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009829#endif
9830#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009832#endif
9833#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009835#endif
9836#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009838#endif
9839#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009841#endif
9842#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009844#endif
9845#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009847#endif
9848#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009850#endif
9851#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009853#endif
Fred Draked86ed291999-12-15 15:34:33 +00009854#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009856#endif
9857#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009859#endif
9860#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009862#endif
9863#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009865#endif
9866#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009867 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009868#endif
9869#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009870 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009871#endif
9872#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009873 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009874#endif
9875#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009876 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009877#endif
9878#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009879 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009880#endif
9881#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009882 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009883#endif
9884#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009885 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009886#endif
9887#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009888 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009889#endif
9890#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009891 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009892#endif
Fred Drakec9680921999-12-13 16:37:25 +00009893};
9894
9895static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009896conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009897{
9898 return conv_confname(arg, valuep, posix_constants_confstr,
9899 sizeof(posix_constants_confstr)
9900 / sizeof(struct constdef));
9901}
9902
Larry Hastings2f936352014-08-05 14:04:04 +10009903
9904/*[clinic input]
9905os.confstr
9906
9907 name: confstr_confname
9908 /
9909
9910Return a string-valued system configuration variable.
9911[clinic start generated code]*/
9912
Larry Hastings2f936352014-08-05 14:04:04 +10009913static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009914os_confstr_impl(PyObject *module, int name)
9915/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009916{
9917 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009918 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009919 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009920
Victor Stinnercb043522010-09-10 23:49:04 +00009921 errno = 0;
9922 len = confstr(name, buffer, sizeof(buffer));
9923 if (len == 0) {
9924 if (errno) {
9925 posix_error();
9926 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009927 }
9928 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009929 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009930 }
9931 }
Victor Stinnercb043522010-09-10 23:49:04 +00009932
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009933 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009934 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009935 char *buf = PyMem_Malloc(len);
9936 if (buf == NULL)
9937 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009938 len2 = confstr(name, buf, len);
9939 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009940 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009941 PyMem_Free(buf);
9942 }
9943 else
9944 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009945 return result;
9946}
Larry Hastings2f936352014-08-05 14:04:04 +10009947#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009948
9949
9950#ifdef HAVE_SYSCONF
9951static struct constdef posix_constants_sysconf[] = {
9952#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
Fred Draked86ed291999-12-15 15:34:33 +00009982#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009984#endif
9985#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009987#endif
Fred Drakec9680921999-12-13 16:37:25 +00009988#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
Fred Drakec9680921999-12-13 16:37:25 +00009991#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
Fred Draked86ed291999-12-15 15:34:33 +000010006#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +000010008#endif
Fred Drakec9680921999-12-13 16:37:25 +000010009#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
Fred Draked86ed291999-12-15 15:34:33 +000010024#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010026#endif
Fred Drakec9680921999-12-13 16:37:25 +000010027#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
10069#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010071#endif
10072#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
Fred Draked86ed291999-12-15 15:34:33 +000010096#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010098#endif
Fred Drakec9680921999-12-13 16:37:25 +000010099#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
Fred Draked86ed291999-12-15 15:34:33 +000010108#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010110#endif
Fred Drakec9680921999-12-13 16:37:25 +000010111#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
Fred Draked86ed291999-12-15 15:34:33 +000010114#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010116#endif
10117#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010119#endif
Fred Drakec9680921999-12-13 16:37:25 +000010120#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
Fred Draked86ed291999-12-15 15:34:33 +000010132#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010134#endif
Fred Drakec9680921999-12-13 16:37:25 +000010135#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
Fred Draked86ed291999-12-15 15:34:33 +000010156#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010158#endif
Fred Drakec9680921999-12-13 16:37:25 +000010159#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
Fred Draked86ed291999-12-15 15:34:33 +000010165#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010167#endif
Fred Drakec9680921999-12-13 16:37:25 +000010168#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
Fred Draked86ed291999-12-15 15:34:33 +000010195#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010197#endif
10198#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010200#endif
Fred Drakec9680921999-12-13 16:37:25 +000010201#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
Fred Draked86ed291999-12-15 15:34:33 +000010306#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010308#endif
Fred Drakec9680921999-12-13 16:37:25 +000010309#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
10411#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010413#endif
10414#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010416#endif
10417#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010418 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010419#endif
10420#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010421 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010422#endif
10423#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010425#endif
10426#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010427 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010428#endif
10429#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010430 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010431#endif
10432#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010433 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010434#endif
10435#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010436 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010437#endif
10438#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010440#endif
10441#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010443#endif
10444};
10445
10446static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010447conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010448{
10449 return conv_confname(arg, valuep, posix_constants_sysconf,
10450 sizeof(posix_constants_sysconf)
10451 / sizeof(struct constdef));
10452}
10453
Larry Hastings2f936352014-08-05 14:04:04 +100010454
10455/*[clinic input]
10456os.sysconf -> long
10457 name: sysconf_confname
10458 /
10459
10460Return an integer-valued system configuration variable.
10461[clinic start generated code]*/
10462
Larry Hastings2f936352014-08-05 14:04:04 +100010463static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010464os_sysconf_impl(PyObject *module, int name)
10465/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010466{
10467 long value;
10468
10469 errno = 0;
10470 value = sysconf(name);
10471 if (value == -1 && errno != 0)
10472 posix_error();
10473 return value;
10474}
10475#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010476
10477
Fred Drakebec628d1999-12-15 18:31:10 +000010478/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010479 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010480 * the exported dictionaries that are used to publish information about the
10481 * names available on the host platform.
10482 *
10483 * Sorting the table at runtime ensures that the table is properly ordered
10484 * when used, even for platforms we're not able to test on. It also makes
10485 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010486 */
Fred Drakebec628d1999-12-15 18:31:10 +000010487
10488static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010489cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010490{
10491 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010492 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010493 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010494 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010495
10496 return strcmp(c1->name, c2->name);
10497}
10498
10499static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010500setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010501 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010502{
Fred Drakebec628d1999-12-15 18:31:10 +000010503 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010504 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010505
10506 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10507 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010508 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010509 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010510
Barry Warsaw3155db32000-04-13 15:20:40 +000010511 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010512 PyObject *o = PyLong_FromLong(table[i].value);
10513 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10514 Py_XDECREF(o);
10515 Py_DECREF(d);
10516 return -1;
10517 }
10518 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010519 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010520 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010521}
10522
Fred Drakebec628d1999-12-15 18:31:10 +000010523/* Return -1 on failure, 0 on success. */
10524static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010525setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010526{
10527#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010528 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010529 sizeof(posix_constants_pathconf)
10530 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010531 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010532 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010533#endif
10534#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010535 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010536 sizeof(posix_constants_confstr)
10537 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010538 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010539 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010540#endif
10541#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010542 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010543 sizeof(posix_constants_sysconf)
10544 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010545 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010546 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010547#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010548 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010549}
Fred Draked86ed291999-12-15 15:34:33 +000010550
10551
Larry Hastings2f936352014-08-05 14:04:04 +100010552/*[clinic input]
10553os.abort
10554
10555Abort the interpreter immediately.
10556
10557This function 'dumps core' or otherwise fails in the hardest way possible
10558on the hosting operating system. This function never returns.
10559[clinic start generated code]*/
10560
Larry Hastings2f936352014-08-05 14:04:04 +100010561static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010562os_abort_impl(PyObject *module)
10563/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010564{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010565 abort();
10566 /*NOTREACHED*/
10567 Py_FatalError("abort() called from Python code didn't abort!");
10568 return NULL;
10569}
Fred Drakebec628d1999-12-15 18:31:10 +000010570
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010571#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010572/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010573PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010574"startfile(filepath [, operation])\n\
10575\n\
10576Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010577\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010578When \"operation\" is not specified or \"open\", this acts like\n\
10579double-clicking the file in Explorer, or giving the file name as an\n\
10580argument to the DOS \"start\" command: the file is opened with whatever\n\
10581application (if any) its extension is associated.\n\
10582When another \"operation\" is given, it specifies what should be done with\n\
10583the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010584\n\
10585startfile returns as soon as the associated application is launched.\n\
10586There is no option to wait for the application to close, and no way\n\
10587to retrieve the application's exit status.\n\
10588\n\
10589The filepath is relative to the current directory. If you want to use\n\
10590an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010591the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010592
Steve Dower7d0e0c92015-01-24 08:18:24 -080010593/* Grab ShellExecute dynamically from shell32 */
10594static int has_ShellExecute = -1;
10595static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10596 LPCSTR, INT);
10597static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10598 LPCWSTR, INT);
10599static int
10600check_ShellExecute()
10601{
10602 HINSTANCE hShell32;
10603
10604 /* only recheck */
10605 if (-1 == has_ShellExecute) {
10606 Py_BEGIN_ALLOW_THREADS
10607 hShell32 = LoadLibraryW(L"SHELL32");
10608 Py_END_ALLOW_THREADS
10609 if (hShell32) {
10610 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10611 "ShellExecuteA");
10612 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10613 "ShellExecuteW");
10614 has_ShellExecute = Py_ShellExecuteA &&
10615 Py_ShellExecuteW;
10616 } else {
10617 has_ShellExecute = 0;
10618 }
10619 }
10620 return has_ShellExecute;
10621}
10622
10623
Tim Petersf58a7aa2000-09-22 10:05:54 +000010624static PyObject *
10625win32_startfile(PyObject *self, PyObject *args)
10626{
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 PyObject *ofilepath;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010628 const char *filepath;
10629 const char *operation = NULL;
10630 const wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010632
Victor Stinnereb5657a2011-09-30 01:44:27 +020010633 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010634
10635 if(!check_ShellExecute()) {
10636 /* If the OS doesn't have ShellExecute, return a
10637 NotImplementedError. */
10638 return PyErr_Format(PyExc_NotImplementedError,
10639 "startfile not available on this platform");
10640 }
10641
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 if (!PyArg_ParseTuple(args, "U|s:startfile",
10643 &unipath, &operation)) {
10644 PyErr_Clear();
10645 goto normal;
10646 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010647
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010649 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010651 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 PyErr_Clear();
10653 operation = NULL;
10654 goto normal;
10655 }
10656 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010657
Victor Stinnereb5657a2011-09-30 01:44:27 +020010658 wpath = PyUnicode_AsUnicode(unipath);
10659 if (wpath == NULL)
10660 goto normal;
10661 if (uoperation) {
10662 woperation = PyUnicode_AsUnicode(uoperation);
10663 if (woperation == NULL)
10664 goto normal;
10665 }
10666 else
10667 woperation = NULL;
10668
Victor Stinner8c62be82010-05-06 00:08:46 +000010669 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010670 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10671 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 Py_END_ALLOW_THREADS
10673
Victor Stinnereb5657a2011-09-30 01:44:27 +020010674 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010675 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010676 win32_error_object("startfile", unipath);
10677 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010678 }
10679 Py_INCREF(Py_None);
10680 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010681
10682normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010683 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10684 PyUnicode_FSConverter, &ofilepath,
10685 &operation))
10686 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010687 if (win32_warn_bytes_api()) {
10688 Py_DECREF(ofilepath);
10689 return NULL;
10690 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010691 filepath = PyBytes_AsString(ofilepath);
10692 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010693 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10694 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010695 Py_END_ALLOW_THREADS
10696 if (rc <= (HINSTANCE)32) {
10697 PyObject *errval = win32_error("startfile", filepath);
10698 Py_DECREF(ofilepath);
10699 return errval;
10700 }
10701 Py_DECREF(ofilepath);
10702 Py_INCREF(Py_None);
10703 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010704}
Larry Hastings2f936352014-08-05 14:04:04 +100010705#endif /* MS_WINDOWS */
10706
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010707
Martin v. Löwis438b5342002-12-27 10:16:42 +000010708#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010709/*[clinic input]
10710os.getloadavg
10711
10712Return average recent system load information.
10713
10714Return the number of processes in the system run queue averaged over
10715the last 1, 5, and 15 minutes as a tuple of three floats.
10716Raises OSError if the load average was unobtainable.
10717[clinic start generated code]*/
10718
Larry Hastings2f936352014-08-05 14:04:04 +100010719static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010720os_getloadavg_impl(PyObject *module)
10721/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010722{
10723 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010724 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010725 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10726 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010727 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010728 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010729}
Larry Hastings2f936352014-08-05 14:04:04 +100010730#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010731
Larry Hastings2f936352014-08-05 14:04:04 +100010732
10733/*[clinic input]
10734os.device_encoding
10735 fd: int
10736
10737Return a string describing the encoding of a terminal's file descriptor.
10738
10739The file descriptor must be attached to a terminal.
10740If the device is not a terminal, return None.
10741[clinic start generated code]*/
10742
Larry Hastings2f936352014-08-05 14:04:04 +100010743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010744os_device_encoding_impl(PyObject *module, int fd)
10745/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010746{
Brett Cannonefb00c02012-02-29 18:31:31 -050010747 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010748}
10749
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010750
Larry Hastings2f936352014-08-05 14:04:04 +100010751#ifdef HAVE_SETRESUID
10752/*[clinic input]
10753os.setresuid
10754
10755 ruid: uid_t
10756 euid: uid_t
10757 suid: uid_t
10758 /
10759
10760Set the current process's real, effective, and saved user ids.
10761[clinic start generated code]*/
10762
Larry Hastings2f936352014-08-05 14:04:04 +100010763static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010764os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10765/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010766{
Victor Stinner8c62be82010-05-06 00:08:46 +000010767 if (setresuid(ruid, euid, suid) < 0)
10768 return posix_error();
10769 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010770}
Larry Hastings2f936352014-08-05 14:04:04 +100010771#endif /* HAVE_SETRESUID */
10772
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010773
10774#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010775/*[clinic input]
10776os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010777
Larry Hastings2f936352014-08-05 14:04:04 +100010778 rgid: gid_t
10779 egid: gid_t
10780 sgid: gid_t
10781 /
10782
10783Set the current process's real, effective, and saved group ids.
10784[clinic start generated code]*/
10785
Larry Hastings2f936352014-08-05 14:04:04 +100010786static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010787os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10788/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010789{
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 if (setresgid(rgid, egid, sgid) < 0)
10791 return posix_error();
10792 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010793}
Larry Hastings2f936352014-08-05 14:04:04 +100010794#endif /* HAVE_SETRESGID */
10795
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010796
10797#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010798/*[clinic input]
10799os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010800
Larry Hastings2f936352014-08-05 14:04:04 +100010801Return a tuple of the current process's real, effective, and saved user ids.
10802[clinic start generated code]*/
10803
Larry Hastings2f936352014-08-05 14:04:04 +100010804static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010805os_getresuid_impl(PyObject *module)
10806/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010807{
Victor Stinner8c62be82010-05-06 00:08:46 +000010808 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010809 if (getresuid(&ruid, &euid, &suid) < 0)
10810 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010811 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10812 _PyLong_FromUid(euid),
10813 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010814}
Larry Hastings2f936352014-08-05 14:04:04 +100010815#endif /* HAVE_GETRESUID */
10816
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010817
10818#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010819/*[clinic input]
10820os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010821
Larry Hastings2f936352014-08-05 14:04:04 +100010822Return a tuple of the current process's real, effective, and saved group ids.
10823[clinic start generated code]*/
10824
Larry Hastings2f936352014-08-05 14:04:04 +100010825static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010826os_getresgid_impl(PyObject *module)
10827/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010828{
10829 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010830 if (getresgid(&rgid, &egid, &sgid) < 0)
10831 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010832 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10833 _PyLong_FromGid(egid),
10834 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010835}
Larry Hastings2f936352014-08-05 14:04:04 +100010836#endif /* HAVE_GETRESGID */
10837
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010838
Benjamin Peterson9428d532011-09-14 11:45:52 -040010839#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010840/*[clinic input]
10841os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010842
Larry Hastings2f936352014-08-05 14:04:04 +100010843 path: path_t(allow_fd=True)
10844 attribute: path_t
10845 *
10846 follow_symlinks: bool = True
10847
10848Return the value of extended attribute attribute on path.
10849
10850path may be either a string or an open file descriptor.
10851If follow_symlinks is False, and the last element of the path is a symbolic
10852 link, getxattr will examine the symbolic link itself instead of the file
10853 the link points to.
10854
10855[clinic start generated code]*/
10856
Larry Hastings2f936352014-08-05 14:04:04 +100010857static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010858os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010859 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010860/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010861{
10862 Py_ssize_t i;
10863 PyObject *buffer = NULL;
10864
10865 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10866 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010867
Larry Hastings9cf065c2012-06-22 16:30:09 -070010868 for (i = 0; ; i++) {
10869 void *ptr;
10870 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010871 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010872 Py_ssize_t buffer_size = buffer_sizes[i];
10873 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010874 path_error(path);
10875 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010876 }
10877 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10878 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010879 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010880 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010881
Larry Hastings9cf065c2012-06-22 16:30:09 -070010882 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010883 if (path->fd >= 0)
10884 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010885 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010886 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010887 else
Larry Hastings2f936352014-08-05 14:04:04 +100010888 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010889 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010890
Larry Hastings9cf065c2012-06-22 16:30:09 -070010891 if (result < 0) {
10892 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010893 if (errno == ERANGE)
10894 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010895 path_error(path);
10896 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010897 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010898
Larry Hastings9cf065c2012-06-22 16:30:09 -070010899 if (result != buffer_size) {
10900 /* Can only shrink. */
10901 _PyBytes_Resize(&buffer, result);
10902 }
10903 break;
10904 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010905
Larry Hastings9cf065c2012-06-22 16:30:09 -070010906 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010907}
10908
Larry Hastings2f936352014-08-05 14:04:04 +100010909
10910/*[clinic input]
10911os.setxattr
10912
10913 path: path_t(allow_fd=True)
10914 attribute: path_t
10915 value: Py_buffer
10916 flags: int = 0
10917 *
10918 follow_symlinks: bool = True
10919
10920Set extended attribute attribute on path to value.
10921
10922path may be either a string or an open file descriptor.
10923If follow_symlinks is False, and the last element of the path is a symbolic
10924 link, setxattr will modify the symbolic link itself instead of the file
10925 the link points to.
10926
10927[clinic start generated code]*/
10928
Benjamin Peterson799bd802011-08-31 22:15:17 -040010929static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010930os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010931 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010932/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010933{
Larry Hastings2f936352014-08-05 14:04:04 +100010934 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010935
Larry Hastings2f936352014-08-05 14:04:04 +100010936 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010937 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010938
Benjamin Peterson799bd802011-08-31 22:15:17 -040010939 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010940 if (path->fd > -1)
10941 result = fsetxattr(path->fd, attribute->narrow,
10942 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010943 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010944 result = setxattr(path->narrow, attribute->narrow,
10945 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010946 else
Larry Hastings2f936352014-08-05 14:04:04 +100010947 result = lsetxattr(path->narrow, attribute->narrow,
10948 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010949 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010950
Larry Hastings9cf065c2012-06-22 16:30:09 -070010951 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010952 path_error(path);
10953 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010954 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010955
Larry Hastings2f936352014-08-05 14:04:04 +100010956 Py_RETURN_NONE;
10957}
10958
10959
10960/*[clinic input]
10961os.removexattr
10962
10963 path: path_t(allow_fd=True)
10964 attribute: path_t
10965 *
10966 follow_symlinks: bool = True
10967
10968Remove extended attribute attribute on path.
10969
10970path may be either a string or an open file descriptor.
10971If follow_symlinks is False, and the last element of the path is a symbolic
10972 link, removexattr will modify the symbolic link itself instead of the file
10973 the link points to.
10974
10975[clinic start generated code]*/
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010978os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010979 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010980/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010981{
10982 ssize_t result;
10983
10984 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10985 return NULL;
10986
10987 Py_BEGIN_ALLOW_THREADS;
10988 if (path->fd > -1)
10989 result = fremovexattr(path->fd, attribute->narrow);
10990 else if (follow_symlinks)
10991 result = removexattr(path->narrow, attribute->narrow);
10992 else
10993 result = lremovexattr(path->narrow, attribute->narrow);
10994 Py_END_ALLOW_THREADS;
10995
10996 if (result) {
10997 return path_error(path);
10998 }
10999
11000 Py_RETURN_NONE;
11001}
11002
11003
11004/*[clinic input]
11005os.listxattr
11006
11007 path: path_t(allow_fd=True, nullable=True) = None
11008 *
11009 follow_symlinks: bool = True
11010
11011Return a list of extended attributes on path.
11012
11013path may be either None, a string, or an open file descriptor.
11014if path is None, listxattr will examine the current directory.
11015If follow_symlinks is False, and the last element of the path is a symbolic
11016 link, listxattr will examine the symbolic link itself instead of the file
11017 the link points to.
11018[clinic start generated code]*/
11019
Larry Hastings2f936352014-08-05 14:04:04 +100011020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011021os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11022/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011023{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 Py_ssize_t i;
11025 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011026 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011027 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011028
Larry Hastings2f936352014-08-05 14:04:04 +100011029 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011030 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011031
Larry Hastings2f936352014-08-05 14:04:04 +100011032 name = path->narrow ? path->narrow : ".";
11033
Larry Hastings9cf065c2012-06-22 16:30:09 -070011034 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011035 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011036 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011037 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011038 Py_ssize_t buffer_size = buffer_sizes[i];
11039 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011040 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011041 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011042 break;
11043 }
11044 buffer = PyMem_MALLOC(buffer_size);
11045 if (!buffer) {
11046 PyErr_NoMemory();
11047 break;
11048 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011049
Larry Hastings9cf065c2012-06-22 16:30:09 -070011050 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011051 if (path->fd > -1)
11052 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011053 else if (follow_symlinks)
11054 length = listxattr(name, buffer, buffer_size);
11055 else
11056 length = llistxattr(name, buffer, buffer_size);
11057 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011058
Larry Hastings9cf065c2012-06-22 16:30:09 -070011059 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011060 if (errno == ERANGE) {
11061 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011062 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011063 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011064 }
Larry Hastings2f936352014-08-05 14:04:04 +100011065 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011066 break;
11067 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011068
Larry Hastings9cf065c2012-06-22 16:30:09 -070011069 result = PyList_New(0);
11070 if (!result) {
11071 goto exit;
11072 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011073
Larry Hastings9cf065c2012-06-22 16:30:09 -070011074 end = buffer + length;
11075 for (trace = start = buffer; trace != end; trace++) {
11076 if (!*trace) {
11077 int error;
11078 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11079 trace - start);
11080 if (!attribute) {
11081 Py_DECREF(result);
11082 result = NULL;
11083 goto exit;
11084 }
11085 error = PyList_Append(result, attribute);
11086 Py_DECREF(attribute);
11087 if (error) {
11088 Py_DECREF(result);
11089 result = NULL;
11090 goto exit;
11091 }
11092 start = trace + 1;
11093 }
11094 }
11095 break;
11096 }
11097exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011098 if (buffer)
11099 PyMem_FREE(buffer);
11100 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011101}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011102#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011103
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011104
Larry Hastings2f936352014-08-05 14:04:04 +100011105/*[clinic input]
11106os.urandom
11107
11108 size: Py_ssize_t
11109 /
11110
11111Return a bytes object containing random bytes suitable for cryptographic use.
11112[clinic start generated code]*/
11113
Larry Hastings2f936352014-08-05 14:04:04 +100011114static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011115os_urandom_impl(PyObject *module, Py_ssize_t size)
11116/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011117{
11118 PyObject *bytes;
11119 int result;
11120
Georg Brandl2fb477c2012-02-21 00:33:36 +010011121 if (size < 0)
11122 return PyErr_Format(PyExc_ValueError,
11123 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011124 bytes = PyBytes_FromStringAndSize(NULL, size);
11125 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011126 return NULL;
11127
Larry Hastings2f936352014-08-05 14:04:04 +100011128 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11129 PyBytes_GET_SIZE(bytes));
11130 if (result == -1) {
11131 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011132 return NULL;
11133 }
Larry Hastings2f936352014-08-05 14:04:04 +100011134 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011135}
11136
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011137/* Terminal size querying */
11138
11139static PyTypeObject TerminalSizeType;
11140
11141PyDoc_STRVAR(TerminalSize_docstring,
11142 "A tuple of (columns, lines) for holding terminal window size");
11143
11144static PyStructSequence_Field TerminalSize_fields[] = {
11145 {"columns", "width of the terminal window in characters"},
11146 {"lines", "height of the terminal window in characters"},
11147 {NULL, NULL}
11148};
11149
11150static PyStructSequence_Desc TerminalSize_desc = {
11151 "os.terminal_size",
11152 TerminalSize_docstring,
11153 TerminalSize_fields,
11154 2,
11155};
11156
11157#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011158/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011159PyDoc_STRVAR(termsize__doc__,
11160 "Return the size of the terminal window as (columns, lines).\n" \
11161 "\n" \
11162 "The optional argument fd (default standard output) specifies\n" \
11163 "which file descriptor should be queried.\n" \
11164 "\n" \
11165 "If the file descriptor is not connected to a terminal, an OSError\n" \
11166 "is thrown.\n" \
11167 "\n" \
11168 "This function will only be defined if an implementation is\n" \
11169 "available for this system.\n" \
11170 "\n" \
11171 "shutil.get_terminal_size is the high-level function which should \n" \
11172 "normally be used, os.get_terminal_size is the low-level implementation.");
11173
11174static PyObject*
11175get_terminal_size(PyObject *self, PyObject *args)
11176{
11177 int columns, lines;
11178 PyObject *termsize;
11179
11180 int fd = fileno(stdout);
11181 /* Under some conditions stdout may not be connected and
11182 * fileno(stdout) may point to an invalid file descriptor. For example
11183 * GUI apps don't have valid standard streams by default.
11184 *
11185 * If this happens, and the optional fd argument is not present,
11186 * the ioctl below will fail returning EBADF. This is what we want.
11187 */
11188
11189 if (!PyArg_ParseTuple(args, "|i", &fd))
11190 return NULL;
11191
11192#ifdef TERMSIZE_USE_IOCTL
11193 {
11194 struct winsize w;
11195 if (ioctl(fd, TIOCGWINSZ, &w))
11196 return PyErr_SetFromErrno(PyExc_OSError);
11197 columns = w.ws_col;
11198 lines = w.ws_row;
11199 }
11200#endif /* TERMSIZE_USE_IOCTL */
11201
11202#ifdef TERMSIZE_USE_CONIO
11203 {
11204 DWORD nhandle;
11205 HANDLE handle;
11206 CONSOLE_SCREEN_BUFFER_INFO csbi;
11207 switch (fd) {
11208 case 0: nhandle = STD_INPUT_HANDLE;
11209 break;
11210 case 1: nhandle = STD_OUTPUT_HANDLE;
11211 break;
11212 case 2: nhandle = STD_ERROR_HANDLE;
11213 break;
11214 default:
11215 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11216 }
11217 handle = GetStdHandle(nhandle);
11218 if (handle == NULL)
11219 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11220 if (handle == INVALID_HANDLE_VALUE)
11221 return PyErr_SetFromWindowsErr(0);
11222
11223 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11224 return PyErr_SetFromWindowsErr(0);
11225
11226 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11227 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11228 }
11229#endif /* TERMSIZE_USE_CONIO */
11230
11231 termsize = PyStructSequence_New(&TerminalSizeType);
11232 if (termsize == NULL)
11233 return NULL;
11234 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11235 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11236 if (PyErr_Occurred()) {
11237 Py_DECREF(termsize);
11238 return NULL;
11239 }
11240 return termsize;
11241}
11242#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11243
Larry Hastings2f936352014-08-05 14:04:04 +100011244
11245/*[clinic input]
11246os.cpu_count
11247
Charles-François Natali80d62e62015-08-13 20:37:08 +010011248Return the number of CPUs in the system; return None if indeterminable.
11249
11250This number is not equivalent to the number of CPUs the current process can
11251use. The number of usable CPUs can be obtained with
11252``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011253[clinic start generated code]*/
11254
Larry Hastings2f936352014-08-05 14:04:04 +100011255static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011256os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011257/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011258{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011259 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011260#ifdef MS_WINDOWS
11261 SYSTEM_INFO sysinfo;
11262 GetSystemInfo(&sysinfo);
11263 ncpu = sysinfo.dwNumberOfProcessors;
11264#elif defined(__hpux)
11265 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11266#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11267 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011268#elif defined(__DragonFly__) || \
11269 defined(__OpenBSD__) || \
11270 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011271 defined(__NetBSD__) || \
11272 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011273 int mib[2];
11274 size_t len = sizeof(ncpu);
11275 mib[0] = CTL_HW;
11276 mib[1] = HW_NCPU;
11277 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11278 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011279#endif
11280 if (ncpu >= 1)
11281 return PyLong_FromLong(ncpu);
11282 else
11283 Py_RETURN_NONE;
11284}
11285
Victor Stinnerdaf45552013-08-28 00:53:59 +020011286
Larry Hastings2f936352014-08-05 14:04:04 +100011287/*[clinic input]
11288os.get_inheritable -> bool
11289
11290 fd: int
11291 /
11292
11293Get the close-on-exe flag of the specified file descriptor.
11294[clinic start generated code]*/
11295
Larry Hastings2f936352014-08-05 14:04:04 +100011296static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011297os_get_inheritable_impl(PyObject *module, int fd)
11298/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011299{
Steve Dower8fc89802015-04-12 00:26:27 -040011300 int return_value;
11301 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011302 posix_error();
11303 return -1;
11304 }
11305
Steve Dower8fc89802015-04-12 00:26:27 -040011306 _Py_BEGIN_SUPPRESS_IPH
11307 return_value = _Py_get_inheritable(fd);
11308 _Py_END_SUPPRESS_IPH
11309 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011310}
11311
11312
11313/*[clinic input]
11314os.set_inheritable
11315 fd: int
11316 inheritable: int
11317 /
11318
11319Set the inheritable flag of the specified file descriptor.
11320[clinic start generated code]*/
11321
Larry Hastings2f936352014-08-05 14:04:04 +100011322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011323os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11324/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011325{
Steve Dower8fc89802015-04-12 00:26:27 -040011326 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011327 if (!_PyVerify_fd(fd))
11328 return posix_error();
11329
Steve Dower8fc89802015-04-12 00:26:27 -040011330 _Py_BEGIN_SUPPRESS_IPH
11331 result = _Py_set_inheritable(fd, inheritable, NULL);
11332 _Py_END_SUPPRESS_IPH
11333 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011334 return NULL;
11335 Py_RETURN_NONE;
11336}
11337
11338
11339#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011340/*[clinic input]
11341os.get_handle_inheritable -> bool
11342 handle: Py_intptr_t
11343 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011344
Larry Hastings2f936352014-08-05 14:04:04 +100011345Get the close-on-exe flag of the specified file descriptor.
11346[clinic start generated code]*/
11347
Larry Hastings2f936352014-08-05 14:04:04 +100011348static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011349os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11350/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011351{
11352 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011353
11354 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11355 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011356 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011357 }
11358
Larry Hastings2f936352014-08-05 14:04:04 +100011359 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011360}
11361
Victor Stinnerdaf45552013-08-28 00:53:59 +020011362
Larry Hastings2f936352014-08-05 14:04:04 +100011363/*[clinic input]
11364os.set_handle_inheritable
11365 handle: Py_intptr_t
11366 inheritable: bool
11367 /
11368
11369Set the inheritable flag of the specified handle.
11370[clinic start generated code]*/
11371
Larry Hastings2f936352014-08-05 14:04:04 +100011372static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011373os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011374 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011375/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011376{
11377 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011378 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11379 PyErr_SetFromWindowsErr(0);
11380 return NULL;
11381 }
11382 Py_RETURN_NONE;
11383}
Larry Hastings2f936352014-08-05 14:04:04 +100011384#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011385
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011386#ifndef MS_WINDOWS
11387PyDoc_STRVAR(get_blocking__doc__,
11388 "get_blocking(fd) -> bool\n" \
11389 "\n" \
11390 "Get the blocking mode of the file descriptor:\n" \
11391 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11392
11393static PyObject*
11394posix_get_blocking(PyObject *self, PyObject *args)
11395{
11396 int fd;
11397 int blocking;
11398
11399 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11400 return NULL;
11401
11402 if (!_PyVerify_fd(fd))
11403 return posix_error();
11404
Steve Dower8fc89802015-04-12 00:26:27 -040011405 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011406 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011407 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011408 if (blocking < 0)
11409 return NULL;
11410 return PyBool_FromLong(blocking);
11411}
11412
11413PyDoc_STRVAR(set_blocking__doc__,
11414 "set_blocking(fd, blocking)\n" \
11415 "\n" \
11416 "Set the blocking mode of the specified file descriptor.\n" \
11417 "Set the O_NONBLOCK flag if blocking is False,\n" \
11418 "clear the O_NONBLOCK flag otherwise.");
11419
11420static PyObject*
11421posix_set_blocking(PyObject *self, PyObject *args)
11422{
Steve Dower8fc89802015-04-12 00:26:27 -040011423 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011424
11425 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11426 return NULL;
11427
11428 if (!_PyVerify_fd(fd))
11429 return posix_error();
11430
Steve Dower8fc89802015-04-12 00:26:27 -040011431 _Py_BEGIN_SUPPRESS_IPH
11432 result = _Py_set_blocking(fd, blocking);
11433 _Py_END_SUPPRESS_IPH
11434 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011435 return NULL;
11436 Py_RETURN_NONE;
11437}
11438#endif /* !MS_WINDOWS */
11439
11440
Victor Stinner6036e442015-03-08 01:58:04 +010011441PyDoc_STRVAR(posix_scandir__doc__,
11442"scandir(path='.') -> iterator of DirEntry objects for given path");
11443
11444static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11445
11446typedef struct {
11447 PyObject_HEAD
11448 PyObject *name;
11449 PyObject *path;
11450 PyObject *stat;
11451 PyObject *lstat;
11452#ifdef MS_WINDOWS
11453 struct _Py_stat_struct win32_lstat;
11454 __int64 win32_file_index;
11455 int got_file_index;
11456#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011457#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011458 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011459#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011460 ino_t d_ino;
11461#endif
11462} DirEntry;
11463
11464static void
11465DirEntry_dealloc(DirEntry *entry)
11466{
11467 Py_XDECREF(entry->name);
11468 Py_XDECREF(entry->path);
11469 Py_XDECREF(entry->stat);
11470 Py_XDECREF(entry->lstat);
11471 Py_TYPE(entry)->tp_free((PyObject *)entry);
11472}
11473
11474/* Forward reference */
11475static int
11476DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11477
11478/* Set exception and return -1 on error, 0 for False, 1 for True */
11479static int
11480DirEntry_is_symlink(DirEntry *self)
11481{
11482#ifdef MS_WINDOWS
11483 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011484#elif defined(HAVE_DIRENT_D_TYPE)
11485 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011486 if (self->d_type != DT_UNKNOWN)
11487 return self->d_type == DT_LNK;
11488 else
11489 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011490#else
11491 /* POSIX without d_type */
11492 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011493#endif
11494}
11495
11496static PyObject *
11497DirEntry_py_is_symlink(DirEntry *self)
11498{
11499 int result;
11500
11501 result = DirEntry_is_symlink(self);
11502 if (result == -1)
11503 return NULL;
11504 return PyBool_FromLong(result);
11505}
11506
11507static PyObject *
11508DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11509{
11510 int result;
11511 struct _Py_stat_struct st;
11512
11513#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011514 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011515
11516 path = PyUnicode_AsUnicode(self->path);
11517 if (!path)
11518 return NULL;
11519
11520 if (follow_symlinks)
11521 result = win32_stat_w(path, &st);
11522 else
11523 result = win32_lstat_w(path, &st);
11524
11525 if (result != 0) {
11526 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11527 0, self->path);
11528 }
11529#else /* POSIX */
11530 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011531 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011532
11533 if (!PyUnicode_FSConverter(self->path, &bytes))
11534 return NULL;
11535 path = PyBytes_AS_STRING(bytes);
11536
11537 if (follow_symlinks)
11538 result = STAT(path, &st);
11539 else
11540 result = LSTAT(path, &st);
11541 Py_DECREF(bytes);
11542
11543 if (result != 0)
11544 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11545#endif
11546
11547 return _pystat_fromstructstat(&st);
11548}
11549
11550static PyObject *
11551DirEntry_get_lstat(DirEntry *self)
11552{
11553 if (!self->lstat) {
11554#ifdef MS_WINDOWS
11555 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11556#else /* POSIX */
11557 self->lstat = DirEntry_fetch_stat(self, 0);
11558#endif
11559 }
11560 Py_XINCREF(self->lstat);
11561 return self->lstat;
11562}
11563
11564static PyObject *
11565DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11566{
11567 if (!follow_symlinks)
11568 return DirEntry_get_lstat(self);
11569
11570 if (!self->stat) {
11571 int result = DirEntry_is_symlink(self);
11572 if (result == -1)
11573 return NULL;
11574 else if (result)
11575 self->stat = DirEntry_fetch_stat(self, 1);
11576 else
11577 self->stat = DirEntry_get_lstat(self);
11578 }
11579
11580 Py_XINCREF(self->stat);
11581 return self->stat;
11582}
11583
11584static PyObject *
11585DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11586{
11587 int follow_symlinks = 1;
11588
11589 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11590 follow_symlinks_keywords, &follow_symlinks))
11591 return NULL;
11592
11593 return DirEntry_get_stat(self, follow_symlinks);
11594}
11595
11596/* Set exception and return -1 on error, 0 for False, 1 for True */
11597static int
11598DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11599{
11600 PyObject *stat = NULL;
11601 PyObject *st_mode = NULL;
11602 long mode;
11603 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011604#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011605 int is_symlink;
11606 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011607#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011608#ifdef MS_WINDOWS
11609 unsigned long dir_bits;
11610#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011611 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011612
11613#ifdef MS_WINDOWS
11614 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11615 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011616#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011617 is_symlink = self->d_type == DT_LNK;
11618 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11619#endif
11620
Victor Stinner35a97c02015-03-08 02:59:09 +010011621#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011622 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011623#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011624 stat = DirEntry_get_stat(self, follow_symlinks);
11625 if (!stat) {
11626 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11627 /* If file doesn't exist (anymore), then return False
11628 (i.e., say it's not a file/directory) */
11629 PyErr_Clear();
11630 return 0;
11631 }
11632 goto error;
11633 }
11634 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11635 if (!st_mode)
11636 goto error;
11637
11638 mode = PyLong_AsLong(st_mode);
11639 if (mode == -1 && PyErr_Occurred())
11640 goto error;
11641 Py_CLEAR(st_mode);
11642 Py_CLEAR(stat);
11643 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011644#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011645 }
11646 else if (is_symlink) {
11647 assert(mode_bits != S_IFLNK);
11648 result = 0;
11649 }
11650 else {
11651 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11652#ifdef MS_WINDOWS
11653 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11654 if (mode_bits == S_IFDIR)
11655 result = dir_bits != 0;
11656 else
11657 result = dir_bits == 0;
11658#else /* POSIX */
11659 if (mode_bits == S_IFDIR)
11660 result = self->d_type == DT_DIR;
11661 else
11662 result = self->d_type == DT_REG;
11663#endif
11664 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011665#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011666
11667 return result;
11668
11669error:
11670 Py_XDECREF(st_mode);
11671 Py_XDECREF(stat);
11672 return -1;
11673}
11674
11675static PyObject *
11676DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11677{
11678 int result;
11679
11680 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11681 if (result == -1)
11682 return NULL;
11683 return PyBool_FromLong(result);
11684}
11685
11686static PyObject *
11687DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11688{
11689 int follow_symlinks = 1;
11690
11691 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11692 follow_symlinks_keywords, &follow_symlinks))
11693 return NULL;
11694
11695 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11696}
11697
11698static PyObject *
11699DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11700{
11701 int follow_symlinks = 1;
11702
11703 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11704 follow_symlinks_keywords, &follow_symlinks))
11705 return NULL;
11706
11707 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11708}
11709
11710static PyObject *
11711DirEntry_inode(DirEntry *self)
11712{
11713#ifdef MS_WINDOWS
11714 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011715 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011716 struct _Py_stat_struct stat;
11717
11718 path = PyUnicode_AsUnicode(self->path);
11719 if (!path)
11720 return NULL;
11721
11722 if (win32_lstat_w(path, &stat) != 0) {
11723 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11724 0, self->path);
11725 }
11726
11727 self->win32_file_index = stat.st_ino;
11728 self->got_file_index = 1;
11729 }
11730 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11731#else /* POSIX */
11732#ifdef HAVE_LARGEFILE_SUPPORT
11733 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11734#else
11735 return PyLong_FromLong((long)self->d_ino);
11736#endif
11737#endif
11738}
11739
11740static PyObject *
11741DirEntry_repr(DirEntry *self)
11742{
11743 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11744}
11745
Brett Cannon96881cd2016-06-10 14:37:21 -070011746static PyObject *
11747DirEntry_fspath(DirEntry *self)
11748{
11749 Py_INCREF(self->path);
11750 return self->path;
11751}
11752
Victor Stinner6036e442015-03-08 01:58:04 +010011753static PyMemberDef DirEntry_members[] = {
11754 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11755 "the entry's base filename, relative to scandir() \"path\" argument"},
11756 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11757 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11758 {NULL}
11759};
11760
11761static PyMethodDef DirEntry_methods[] = {
11762 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11763 "return True if the entry is a directory; cached per entry"
11764 },
11765 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11766 "return True if the entry is a file; cached per entry"
11767 },
11768 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11769 "return True if the entry is a symbolic link; cached per entry"
11770 },
11771 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11772 "return stat_result object for the entry; cached per entry"
11773 },
11774 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11775 "return inode of the entry; cached per entry",
11776 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011777 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11778 "returns the path for the entry",
11779 },
Victor Stinner6036e442015-03-08 01:58:04 +010011780 {NULL}
11781};
11782
Benjamin Peterson5646de42015-04-12 17:56:34 -040011783static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011784 PyVarObject_HEAD_INIT(NULL, 0)
11785 MODNAME ".DirEntry", /* tp_name */
11786 sizeof(DirEntry), /* tp_basicsize */
11787 0, /* tp_itemsize */
11788 /* methods */
11789 (destructor)DirEntry_dealloc, /* tp_dealloc */
11790 0, /* tp_print */
11791 0, /* tp_getattr */
11792 0, /* tp_setattr */
11793 0, /* tp_compare */
11794 (reprfunc)DirEntry_repr, /* tp_repr */
11795 0, /* tp_as_number */
11796 0, /* tp_as_sequence */
11797 0, /* tp_as_mapping */
11798 0, /* tp_hash */
11799 0, /* tp_call */
11800 0, /* tp_str */
11801 0, /* tp_getattro */
11802 0, /* tp_setattro */
11803 0, /* tp_as_buffer */
11804 Py_TPFLAGS_DEFAULT, /* tp_flags */
11805 0, /* tp_doc */
11806 0, /* tp_traverse */
11807 0, /* tp_clear */
11808 0, /* tp_richcompare */
11809 0, /* tp_weaklistoffset */
11810 0, /* tp_iter */
11811 0, /* tp_iternext */
11812 DirEntry_methods, /* tp_methods */
11813 DirEntry_members, /* tp_members */
11814};
11815
11816#ifdef MS_WINDOWS
11817
11818static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011819join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011820{
11821 Py_ssize_t path_len;
11822 Py_ssize_t size;
11823 wchar_t *result;
11824 wchar_t ch;
11825
11826 if (!path_wide) { /* Default arg: "." */
11827 path_wide = L".";
11828 path_len = 1;
11829 }
11830 else {
11831 path_len = wcslen(path_wide);
11832 }
11833
11834 /* The +1's are for the path separator and the NUL */
11835 size = path_len + 1 + wcslen(filename) + 1;
11836 result = PyMem_New(wchar_t, size);
11837 if (!result) {
11838 PyErr_NoMemory();
11839 return NULL;
11840 }
11841 wcscpy(result, path_wide);
11842 if (path_len > 0) {
11843 ch = result[path_len - 1];
11844 if (ch != SEP && ch != ALTSEP && ch != L':')
11845 result[path_len++] = SEP;
11846 wcscpy(result + path_len, filename);
11847 }
11848 return result;
11849}
11850
11851static PyObject *
11852DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11853{
11854 DirEntry *entry;
11855 BY_HANDLE_FILE_INFORMATION file_info;
11856 ULONG reparse_tag;
11857 wchar_t *joined_path;
11858
11859 entry = PyObject_New(DirEntry, &DirEntryType);
11860 if (!entry)
11861 return NULL;
11862 entry->name = NULL;
11863 entry->path = NULL;
11864 entry->stat = NULL;
11865 entry->lstat = NULL;
11866 entry->got_file_index = 0;
11867
11868 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11869 if (!entry->name)
11870 goto error;
11871
11872 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11873 if (!joined_path)
11874 goto error;
11875
11876 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11877 PyMem_Free(joined_path);
11878 if (!entry->path)
11879 goto error;
11880
11881 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11882 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11883
11884 return (PyObject *)entry;
11885
11886error:
11887 Py_DECREF(entry);
11888 return NULL;
11889}
11890
11891#else /* POSIX */
11892
11893static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011894join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011895{
11896 Py_ssize_t path_len;
11897 Py_ssize_t size;
11898 char *result;
11899
11900 if (!path_narrow) { /* Default arg: "." */
11901 path_narrow = ".";
11902 path_len = 1;
11903 }
11904 else {
11905 path_len = strlen(path_narrow);
11906 }
11907
11908 if (filename_len == -1)
11909 filename_len = strlen(filename);
11910
11911 /* The +1's are for the path separator and the NUL */
11912 size = path_len + 1 + filename_len + 1;
11913 result = PyMem_New(char, size);
11914 if (!result) {
11915 PyErr_NoMemory();
11916 return NULL;
11917 }
11918 strcpy(result, path_narrow);
11919 if (path_len > 0 && result[path_len - 1] != '/')
11920 result[path_len++] = '/';
11921 strcpy(result + path_len, filename);
11922 return result;
11923}
11924
11925static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011926DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011927 ino_t d_ino
11928#ifdef HAVE_DIRENT_D_TYPE
11929 , unsigned char d_type
11930#endif
11931 )
Victor Stinner6036e442015-03-08 01:58:04 +010011932{
11933 DirEntry *entry;
11934 char *joined_path;
11935
11936 entry = PyObject_New(DirEntry, &DirEntryType);
11937 if (!entry)
11938 return NULL;
11939 entry->name = NULL;
11940 entry->path = NULL;
11941 entry->stat = NULL;
11942 entry->lstat = NULL;
11943
11944 joined_path = join_path_filename(path->narrow, name, name_len);
11945 if (!joined_path)
11946 goto error;
11947
11948 if (!path->narrow || !PyBytes_Check(path->object)) {
11949 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11950 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11951 }
11952 else {
11953 entry->name = PyBytes_FromStringAndSize(name, name_len);
11954 entry->path = PyBytes_FromString(joined_path);
11955 }
11956 PyMem_Free(joined_path);
11957 if (!entry->name || !entry->path)
11958 goto error;
11959
Victor Stinner35a97c02015-03-08 02:59:09 +010011960#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011961 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011962#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011963 entry->d_ino = d_ino;
11964
11965 return (PyObject *)entry;
11966
11967error:
11968 Py_XDECREF(entry);
11969 return NULL;
11970}
11971
11972#endif
11973
11974
11975typedef struct {
11976 PyObject_HEAD
11977 path_t path;
11978#ifdef MS_WINDOWS
11979 HANDLE handle;
11980 WIN32_FIND_DATAW file_data;
11981 int first_time;
11982#else /* POSIX */
11983 DIR *dirp;
11984#endif
11985} ScandirIterator;
11986
11987#ifdef MS_WINDOWS
11988
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011989static int
11990ScandirIterator_is_closed(ScandirIterator *iterator)
11991{
11992 return iterator->handle == INVALID_HANDLE_VALUE;
11993}
11994
Victor Stinner6036e442015-03-08 01:58:04 +010011995static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011996ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011997{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011998 HANDLE handle = iterator->handle;
11999
12000 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012001 return;
12002
Victor Stinner6036e442015-03-08 01:58:04 +010012003 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012004 Py_BEGIN_ALLOW_THREADS
12005 FindClose(handle);
12006 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012007}
12008
12009static PyObject *
12010ScandirIterator_iternext(ScandirIterator *iterator)
12011{
12012 WIN32_FIND_DATAW *file_data = &iterator->file_data;
12013 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012014 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012015
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012016 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012017 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010012018 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012019
12020 while (1) {
12021 if (!iterator->first_time) {
12022 Py_BEGIN_ALLOW_THREADS
12023 success = FindNextFileW(iterator->handle, file_data);
12024 Py_END_ALLOW_THREADS
12025 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012026 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012027 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012028 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012029 break;
12030 }
12031 }
12032 iterator->first_time = 0;
12033
12034 /* Skip over . and .. */
12035 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012036 wcscmp(file_data->cFileName, L"..") != 0) {
12037 entry = DirEntry_from_find_data(&iterator->path, file_data);
12038 if (!entry)
12039 break;
12040 return entry;
12041 }
Victor Stinner6036e442015-03-08 01:58:04 +010012042
12043 /* Loop till we get a non-dot directory or finish iterating */
12044 }
12045
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012046 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012047 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012048 return NULL;
12049}
12050
12051#else /* POSIX */
12052
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012053static int
12054ScandirIterator_is_closed(ScandirIterator *iterator)
12055{
12056 return !iterator->dirp;
12057}
12058
Victor Stinner6036e442015-03-08 01:58:04 +010012059static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012060ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012061{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012062 DIR *dirp = iterator->dirp;
12063
12064 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012065 return;
12066
Victor Stinner6036e442015-03-08 01:58:04 +010012067 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012068 Py_BEGIN_ALLOW_THREADS
12069 closedir(dirp);
12070 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012071 return;
12072}
12073
12074static PyObject *
12075ScandirIterator_iternext(ScandirIterator *iterator)
12076{
12077 struct dirent *direntp;
12078 Py_ssize_t name_len;
12079 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012080 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012081
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012082 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012083 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012084 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012085
12086 while (1) {
12087 errno = 0;
12088 Py_BEGIN_ALLOW_THREADS
12089 direntp = readdir(iterator->dirp);
12090 Py_END_ALLOW_THREADS
12091
12092 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012093 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012094 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012095 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012096 break;
12097 }
12098
12099 /* Skip over . and .. */
12100 name_len = NAMLEN(direntp);
12101 is_dot = direntp->d_name[0] == '.' &&
12102 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12103 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012104 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012105 name_len, direntp->d_ino
12106#ifdef HAVE_DIRENT_D_TYPE
12107 , direntp->d_type
12108#endif
12109 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012110 if (!entry)
12111 break;
12112 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012113 }
12114
12115 /* Loop till we get a non-dot directory or finish iterating */
12116 }
12117
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012118 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012119 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012120 return NULL;
12121}
12122
12123#endif
12124
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012125static PyObject *
12126ScandirIterator_close(ScandirIterator *self, PyObject *args)
12127{
12128 ScandirIterator_closedir(self);
12129 Py_RETURN_NONE;
12130}
12131
12132static PyObject *
12133ScandirIterator_enter(PyObject *self, PyObject *args)
12134{
12135 Py_INCREF(self);
12136 return self;
12137}
12138
12139static PyObject *
12140ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12141{
12142 ScandirIterator_closedir(self);
12143 Py_RETURN_NONE;
12144}
12145
Victor Stinner6036e442015-03-08 01:58:04 +010012146static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012147ScandirIterator_finalize(ScandirIterator *iterator)
12148{
12149 PyObject *error_type, *error_value, *error_traceback;
12150
12151 /* Save the current exception, if any. */
12152 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12153
12154 if (!ScandirIterator_is_closed(iterator)) {
12155 ScandirIterator_closedir(iterator);
12156
12157 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12158 "unclosed scandir iterator %R", iterator)) {
12159 /* Spurious errors can appear at shutdown */
12160 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12161 PyErr_WriteUnraisable((PyObject *) iterator);
12162 }
12163 }
12164 }
12165
12166 Py_CLEAR(iterator->path.object);
12167 path_cleanup(&iterator->path);
12168
12169 /* Restore the saved exception. */
12170 PyErr_Restore(error_type, error_value, error_traceback);
12171}
12172
12173static void
Victor Stinner6036e442015-03-08 01:58:04 +010012174ScandirIterator_dealloc(ScandirIterator *iterator)
12175{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012176 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12177 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012178
Victor Stinner6036e442015-03-08 01:58:04 +010012179 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12180}
12181
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012182static PyMethodDef ScandirIterator_methods[] = {
12183 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12184 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12185 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12186 {NULL}
12187};
12188
Benjamin Peterson5646de42015-04-12 17:56:34 -040012189static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012190 PyVarObject_HEAD_INIT(NULL, 0)
12191 MODNAME ".ScandirIterator", /* tp_name */
12192 sizeof(ScandirIterator), /* tp_basicsize */
12193 0, /* tp_itemsize */
12194 /* methods */
12195 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12196 0, /* tp_print */
12197 0, /* tp_getattr */
12198 0, /* tp_setattr */
12199 0, /* tp_compare */
12200 0, /* tp_repr */
12201 0, /* tp_as_number */
12202 0, /* tp_as_sequence */
12203 0, /* tp_as_mapping */
12204 0, /* tp_hash */
12205 0, /* tp_call */
12206 0, /* tp_str */
12207 0, /* tp_getattro */
12208 0, /* tp_setattro */
12209 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012210 Py_TPFLAGS_DEFAULT
12211 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012212 0, /* tp_doc */
12213 0, /* tp_traverse */
12214 0, /* tp_clear */
12215 0, /* tp_richcompare */
12216 0, /* tp_weaklistoffset */
12217 PyObject_SelfIter, /* tp_iter */
12218 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012219 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012220 0, /* tp_members */
12221 0, /* tp_getset */
12222 0, /* tp_base */
12223 0, /* tp_dict */
12224 0, /* tp_descr_get */
12225 0, /* tp_descr_set */
12226 0, /* tp_dictoffset */
12227 0, /* tp_init */
12228 0, /* tp_alloc */
12229 0, /* tp_new */
12230 0, /* tp_free */
12231 0, /* tp_is_gc */
12232 0, /* tp_bases */
12233 0, /* tp_mro */
12234 0, /* tp_cache */
12235 0, /* tp_subclasses */
12236 0, /* tp_weaklist */
12237 0, /* tp_del */
12238 0, /* tp_version_tag */
12239 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012240};
12241
12242static PyObject *
12243posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12244{
12245 ScandirIterator *iterator;
12246 static char *keywords[] = {"path", NULL};
12247#ifdef MS_WINDOWS
12248 wchar_t *path_strW;
12249#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012250 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010012251#endif
12252
12253 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12254 if (!iterator)
12255 return NULL;
12256 memset(&iterator->path, 0, sizeof(path_t));
12257 iterator->path.function_name = "scandir";
12258 iterator->path.nullable = 1;
12259
12260#ifdef MS_WINDOWS
12261 iterator->handle = INVALID_HANDLE_VALUE;
12262#else
12263 iterator->dirp = NULL;
12264#endif
12265
12266 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12267 path_converter, &iterator->path))
12268 goto error;
12269
12270 /* path_converter doesn't keep path.object around, so do it
12271 manually for the lifetime of the iterator here (the refcount
12272 is decremented in ScandirIterator_dealloc)
12273 */
12274 Py_XINCREF(iterator->path.object);
12275
12276#ifdef MS_WINDOWS
12277 if (iterator->path.narrow) {
12278 PyErr_SetString(PyExc_TypeError,
12279 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12280 goto error;
12281 }
12282 iterator->first_time = 1;
12283
12284 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12285 if (!path_strW)
12286 goto error;
12287
12288 Py_BEGIN_ALLOW_THREADS
12289 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12290 Py_END_ALLOW_THREADS
12291
12292 PyMem_Free(path_strW);
12293
12294 if (iterator->handle == INVALID_HANDLE_VALUE) {
12295 path_error(&iterator->path);
12296 goto error;
12297 }
12298#else /* POSIX */
12299 if (iterator->path.narrow)
12300 path = iterator->path.narrow;
12301 else
12302 path = ".";
12303
12304 errno = 0;
12305 Py_BEGIN_ALLOW_THREADS
12306 iterator->dirp = opendir(path);
12307 Py_END_ALLOW_THREADS
12308
12309 if (!iterator->dirp) {
12310 path_error(&iterator->path);
12311 goto error;
12312 }
12313#endif
12314
12315 return (PyObject *)iterator;
12316
12317error:
12318 Py_DECREF(iterator);
12319 return NULL;
12320}
12321
Ethan Furman410ef8e2016-06-04 12:06:26 -070012322/*
12323 Return the file system path representation of the object.
12324
12325 If the object is str or bytes, then allow it to pass through with
12326 an incremented refcount. If the object defines __fspath__(), then
12327 return the result of that method. All other types raise a TypeError.
12328*/
12329PyObject *
12330PyOS_FSPath(PyObject *path)
12331{
12332 _Py_IDENTIFIER(__fspath__);
12333 PyObject *func = NULL;
12334 PyObject *path_repr = NULL;
12335
12336 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12337 Py_INCREF(path);
12338 return path;
12339 }
12340
12341 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12342 if (NULL == func) {
12343 return PyErr_Format(PyExc_TypeError,
12344 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012345 "not %.200s",
12346 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012347 }
12348
12349 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12350 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012351 if (NULL == path_repr) {
12352 return NULL;
12353 }
12354
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012355 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12356 PyErr_Format(PyExc_TypeError,
12357 "expected %.200s.__fspath__() to return str or bytes, "
12358 "not %.200s", Py_TYPE(path)->tp_name,
12359 Py_TYPE(path_repr)->tp_name);
12360 Py_DECREF(path_repr);
12361 return NULL;
12362 }
12363
Ethan Furman410ef8e2016-06-04 12:06:26 -070012364 return path_repr;
12365}
12366
12367/*[clinic input]
12368os.fspath
12369
12370 path: object
12371
12372Return the file system path representation of the object.
12373
Brett Cannonb4f43e92016-06-09 14:32:08 -070012374If the object is str or bytes, then allow it to pass through as-is. If the
12375object defines __fspath__(), then return the result of that method. All other
12376types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012377[clinic start generated code]*/
12378
12379static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012380os_fspath_impl(PyObject *module, PyObject *path)
12381/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012382{
12383 return PyOS_FSPath(path);
12384}
Victor Stinner6036e442015-03-08 01:58:04 +010012385
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012386#include "clinic/posixmodule.c.h"
12387
Larry Hastings7726ac92014-01-31 22:03:12 -080012388/*[clinic input]
12389dump buffer
12390[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012391/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012392
Larry Hastings31826802013-10-19 00:09:25 -070012393
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012394static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012395
12396 OS_STAT_METHODDEF
12397 OS_ACCESS_METHODDEF
12398 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012399 OS_CHDIR_METHODDEF
12400 OS_CHFLAGS_METHODDEF
12401 OS_CHMOD_METHODDEF
12402 OS_FCHMOD_METHODDEF
12403 OS_LCHMOD_METHODDEF
12404 OS_CHOWN_METHODDEF
12405 OS_FCHOWN_METHODDEF
12406 OS_LCHOWN_METHODDEF
12407 OS_LCHFLAGS_METHODDEF
12408 OS_CHROOT_METHODDEF
12409 OS_CTERMID_METHODDEF
12410 OS_GETCWD_METHODDEF
12411 OS_GETCWDB_METHODDEF
12412 OS_LINK_METHODDEF
12413 OS_LISTDIR_METHODDEF
12414 OS_LSTAT_METHODDEF
12415 OS_MKDIR_METHODDEF
12416 OS_NICE_METHODDEF
12417 OS_GETPRIORITY_METHODDEF
12418 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012419#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012420 {"readlink", (PyCFunction)posix_readlink,
12421 METH_VARARGS | METH_KEYWORDS,
12422 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012423#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012424#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012425 {"readlink", (PyCFunction)win_readlink,
12426 METH_VARARGS | METH_KEYWORDS,
12427 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012428#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012429 OS_RENAME_METHODDEF
12430 OS_REPLACE_METHODDEF
12431 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012432 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012433 OS_SYMLINK_METHODDEF
12434 OS_SYSTEM_METHODDEF
12435 OS_UMASK_METHODDEF
12436 OS_UNAME_METHODDEF
12437 OS_UNLINK_METHODDEF
12438 OS_REMOVE_METHODDEF
12439 OS_UTIME_METHODDEF
12440 OS_TIMES_METHODDEF
12441 OS__EXIT_METHODDEF
12442 OS_EXECV_METHODDEF
12443 OS_EXECVE_METHODDEF
12444 OS_SPAWNV_METHODDEF
12445 OS_SPAWNVE_METHODDEF
12446 OS_FORK1_METHODDEF
12447 OS_FORK_METHODDEF
12448 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12449 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12450 OS_SCHED_GETPARAM_METHODDEF
12451 OS_SCHED_GETSCHEDULER_METHODDEF
12452 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12453 OS_SCHED_SETPARAM_METHODDEF
12454 OS_SCHED_SETSCHEDULER_METHODDEF
12455 OS_SCHED_YIELD_METHODDEF
12456 OS_SCHED_SETAFFINITY_METHODDEF
12457 OS_SCHED_GETAFFINITY_METHODDEF
12458 OS_OPENPTY_METHODDEF
12459 OS_FORKPTY_METHODDEF
12460 OS_GETEGID_METHODDEF
12461 OS_GETEUID_METHODDEF
12462 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012463#ifdef HAVE_GETGROUPLIST
12464 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12465#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012466 OS_GETGROUPS_METHODDEF
12467 OS_GETPID_METHODDEF
12468 OS_GETPGRP_METHODDEF
12469 OS_GETPPID_METHODDEF
12470 OS_GETUID_METHODDEF
12471 OS_GETLOGIN_METHODDEF
12472 OS_KILL_METHODDEF
12473 OS_KILLPG_METHODDEF
12474 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012475#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012476 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012477#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012478 OS_SETUID_METHODDEF
12479 OS_SETEUID_METHODDEF
12480 OS_SETREUID_METHODDEF
12481 OS_SETGID_METHODDEF
12482 OS_SETEGID_METHODDEF
12483 OS_SETREGID_METHODDEF
12484 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012485#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012486 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012487#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012488 OS_GETPGID_METHODDEF
12489 OS_SETPGRP_METHODDEF
12490 OS_WAIT_METHODDEF
12491 OS_WAIT3_METHODDEF
12492 OS_WAIT4_METHODDEF
12493 OS_WAITID_METHODDEF
12494 OS_WAITPID_METHODDEF
12495 OS_GETSID_METHODDEF
12496 OS_SETSID_METHODDEF
12497 OS_SETPGID_METHODDEF
12498 OS_TCGETPGRP_METHODDEF
12499 OS_TCSETPGRP_METHODDEF
12500 OS_OPEN_METHODDEF
12501 OS_CLOSE_METHODDEF
12502 OS_CLOSERANGE_METHODDEF
12503 OS_DEVICE_ENCODING_METHODDEF
12504 OS_DUP_METHODDEF
12505 OS_DUP2_METHODDEF
12506 OS_LOCKF_METHODDEF
12507 OS_LSEEK_METHODDEF
12508 OS_READ_METHODDEF
12509 OS_READV_METHODDEF
12510 OS_PREAD_METHODDEF
12511 OS_WRITE_METHODDEF
12512 OS_WRITEV_METHODDEF
12513 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012514#ifdef HAVE_SENDFILE
12515 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12516 posix_sendfile__doc__},
12517#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012518 OS_FSTAT_METHODDEF
12519 OS_ISATTY_METHODDEF
12520 OS_PIPE_METHODDEF
12521 OS_PIPE2_METHODDEF
12522 OS_MKFIFO_METHODDEF
12523 OS_MKNOD_METHODDEF
12524 OS_MAJOR_METHODDEF
12525 OS_MINOR_METHODDEF
12526 OS_MAKEDEV_METHODDEF
12527 OS_FTRUNCATE_METHODDEF
12528 OS_TRUNCATE_METHODDEF
12529 OS_POSIX_FALLOCATE_METHODDEF
12530 OS_POSIX_FADVISE_METHODDEF
12531 OS_PUTENV_METHODDEF
12532 OS_UNSETENV_METHODDEF
12533 OS_STRERROR_METHODDEF
12534 OS_FCHDIR_METHODDEF
12535 OS_FSYNC_METHODDEF
12536 OS_SYNC_METHODDEF
12537 OS_FDATASYNC_METHODDEF
12538 OS_WCOREDUMP_METHODDEF
12539 OS_WIFCONTINUED_METHODDEF
12540 OS_WIFSTOPPED_METHODDEF
12541 OS_WIFSIGNALED_METHODDEF
12542 OS_WIFEXITED_METHODDEF
12543 OS_WEXITSTATUS_METHODDEF
12544 OS_WTERMSIG_METHODDEF
12545 OS_WSTOPSIG_METHODDEF
12546 OS_FSTATVFS_METHODDEF
12547 OS_STATVFS_METHODDEF
12548 OS_CONFSTR_METHODDEF
12549 OS_SYSCONF_METHODDEF
12550 OS_FPATHCONF_METHODDEF
12551 OS_PATHCONF_METHODDEF
12552 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012553 OS__GETFULLPATHNAME_METHODDEF
12554 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012555 OS__GETDISKUSAGE_METHODDEF
12556 OS__GETFINALPATHNAME_METHODDEF
12557 OS__GETVOLUMEPATHNAME_METHODDEF
12558 OS_GETLOADAVG_METHODDEF
12559 OS_URANDOM_METHODDEF
12560 OS_SETRESUID_METHODDEF
12561 OS_SETRESGID_METHODDEF
12562 OS_GETRESUID_METHODDEF
12563 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012564
Larry Hastings2f936352014-08-05 14:04:04 +100012565 OS_GETXATTR_METHODDEF
12566 OS_SETXATTR_METHODDEF
12567 OS_REMOVEXATTR_METHODDEF
12568 OS_LISTXATTR_METHODDEF
12569
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012570#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12571 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12572#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012573 OS_CPU_COUNT_METHODDEF
12574 OS_GET_INHERITABLE_METHODDEF
12575 OS_SET_INHERITABLE_METHODDEF
12576 OS_GET_HANDLE_INHERITABLE_METHODDEF
12577 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012578#ifndef MS_WINDOWS
12579 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12580 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12581#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012582 {"scandir", (PyCFunction)posix_scandir,
12583 METH_VARARGS | METH_KEYWORDS,
12584 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012585 OS_FSPATH_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012586 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012587};
12588
12589
Brian Curtin52173d42010-12-02 18:29:18 +000012590#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012591static int
Brian Curtin52173d42010-12-02 18:29:18 +000012592enable_symlink()
12593{
12594 HANDLE tok;
12595 TOKEN_PRIVILEGES tok_priv;
12596 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012597
12598 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012599 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012600
12601 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012602 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012603
12604 tok_priv.PrivilegeCount = 1;
12605 tok_priv.Privileges[0].Luid = luid;
12606 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12607
12608 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12609 sizeof(TOKEN_PRIVILEGES),
12610 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012611 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012612
Brian Curtin3b4499c2010-12-28 14:31:47 +000012613 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12614 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012615}
12616#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12617
Barry Warsaw4a342091996-12-19 23:50:02 +000012618static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012620{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012621#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012623#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012624#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012626#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012627#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012629#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012630#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012632#endif
Fred Drakec9680921999-12-13 16:37:25 +000012633#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012635#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012636#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012637 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012638#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012639#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012641#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012642#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012644#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012645#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012647#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012648#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012650#endif
12651#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012653#endif
12654#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012656#endif
12657#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012659#endif
12660#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012662#endif
12663#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012665#endif
12666#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012668#endif
12669#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012671#endif
12672#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012674#endif
12675#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012677#endif
12678#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012679 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012680#endif
12681#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012682 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012683#endif
12684#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012685 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012686#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012687#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012689#endif
12690#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012692#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012693#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012695#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012696#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012698#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012699#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012700#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012702#endif
12703#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012705#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012706#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012707#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012709#endif
12710#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012712#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012713#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012715#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012716#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012718#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012719#ifdef O_TMPFILE
12720 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12721#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012722#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012724#endif
12725#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012727#endif
12728#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012730#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012731#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012733#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012734#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012736#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012737
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012738
Jesus Cea94363612012-06-22 18:32:07 +020012739#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012741#endif
12742#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012744#endif
12745
Tim Peters5aa91602002-01-30 05:46:57 +000012746/* MS Windows */
12747#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012748 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012750#endif
12751#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012752 /* Optimize for short life (keep in memory). */
12753 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012755#endif
12756#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012757 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012759#endif
12760#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012761 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012763#endif
12764#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012765 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012767#endif
12768
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012769/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012770#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012771 /* Send a SIGIO signal whenever input or output
12772 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012774#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012775#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012776 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012778#endif
12779#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012780 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012781 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012782#endif
12783#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012784 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012786#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012787#ifdef O_NOLINKS
12788 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012790#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012791#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012792 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012793 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012794#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012795
Victor Stinner8c62be82010-05-06 00:08:46 +000012796 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012797#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012798 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012799#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012800#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012801 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012802#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012803#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012805#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012806#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012807 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012808#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012809#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012810 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012811#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012812#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012813 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012814#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012815#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012816 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012817#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012818#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012819 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012820#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012821#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012822 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012823#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012824#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012825 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012826#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012827#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012828 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012829#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012830#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012831 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012832#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012833#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012834 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012835#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012836#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012837 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012838#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012839#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012840 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012841#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012842#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012843 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012844#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012845#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012846 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012847#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012848
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012849 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012850#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012852#endif /* ST_RDONLY */
12853#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012855#endif /* ST_NOSUID */
12856
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012857 /* GNU extensions */
12858#ifdef ST_NODEV
12859 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12860#endif /* ST_NODEV */
12861#ifdef ST_NOEXEC
12862 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12863#endif /* ST_NOEXEC */
12864#ifdef ST_SYNCHRONOUS
12865 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12866#endif /* ST_SYNCHRONOUS */
12867#ifdef ST_MANDLOCK
12868 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12869#endif /* ST_MANDLOCK */
12870#ifdef ST_WRITE
12871 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12872#endif /* ST_WRITE */
12873#ifdef ST_APPEND
12874 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12875#endif /* ST_APPEND */
12876#ifdef ST_NOATIME
12877 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12878#endif /* ST_NOATIME */
12879#ifdef ST_NODIRATIME
12880 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12881#endif /* ST_NODIRATIME */
12882#ifdef ST_RELATIME
12883 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12884#endif /* ST_RELATIME */
12885
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012886 /* FreeBSD sendfile() constants */
12887#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012888 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012889#endif
12890#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012892#endif
12893#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012894 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012895#endif
12896
Ross Lagerwall7807c352011-03-17 20:20:30 +020012897 /* constants for posix_fadvise */
12898#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012899 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012900#endif
12901#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012902 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012903#endif
12904#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012905 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012906#endif
12907#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012908 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012909#endif
12910#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012911 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012912#endif
12913#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012915#endif
12916
12917 /* constants for waitid */
12918#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012919 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12920 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12921 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012922#endif
12923#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012925#endif
12926#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012928#endif
12929#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012930 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012931#endif
12932#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012934#endif
12935#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012936 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012937#endif
12938#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012939 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012940#endif
12941#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012942 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012943#endif
12944
12945 /* constants for lockf */
12946#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012947 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012948#endif
12949#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012950 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012951#endif
12952#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012953 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012954#endif
12955#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012956 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012957#endif
12958
Guido van Rossum246bc171999-02-01 23:54:31 +000012959#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12961 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12962 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12963 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12964 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012965#endif
12966
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012967#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012968#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012970#endif
12971#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012972 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012973#endif
12974#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012976#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012977#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012978 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012979#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012980#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012981 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012982#endif
12983#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012985#endif
12986#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012987 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012988#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012989#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012991#endif
12992#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012994#endif
12995#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012996 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012997#endif
12998#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012999 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020013000#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013001#endif
13002
Benjamin Peterson9428d532011-09-14 11:45:52 -040013003#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013004 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
13005 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
13006 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040013007#endif
13008
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013009#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013010 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013011#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013012#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013013 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013014#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013015#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013016 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013017#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013018#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013019 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013020#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013021#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013022 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013023#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013024#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013025 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013026#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013027#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013028 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013029#endif
13030
Victor Stinner8c62be82010-05-06 00:08:46 +000013031 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013032}
13033
13034
Martin v. Löwis1a214512008-06-11 05:26:20 +000013035static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013036 PyModuleDef_HEAD_INIT,
13037 MODNAME,
13038 posix__doc__,
13039 -1,
13040 posix_methods,
13041 NULL,
13042 NULL,
13043 NULL,
13044 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013045};
13046
13047
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013048static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013049
13050#ifdef HAVE_FACCESSAT
13051 "HAVE_FACCESSAT",
13052#endif
13053
13054#ifdef HAVE_FCHDIR
13055 "HAVE_FCHDIR",
13056#endif
13057
13058#ifdef HAVE_FCHMOD
13059 "HAVE_FCHMOD",
13060#endif
13061
13062#ifdef HAVE_FCHMODAT
13063 "HAVE_FCHMODAT",
13064#endif
13065
13066#ifdef HAVE_FCHOWN
13067 "HAVE_FCHOWN",
13068#endif
13069
Larry Hastings00964ed2013-08-12 13:49:30 -040013070#ifdef HAVE_FCHOWNAT
13071 "HAVE_FCHOWNAT",
13072#endif
13073
Larry Hastings9cf065c2012-06-22 16:30:09 -070013074#ifdef HAVE_FEXECVE
13075 "HAVE_FEXECVE",
13076#endif
13077
13078#ifdef HAVE_FDOPENDIR
13079 "HAVE_FDOPENDIR",
13080#endif
13081
Georg Brandl306336b2012-06-24 12:55:33 +020013082#ifdef HAVE_FPATHCONF
13083 "HAVE_FPATHCONF",
13084#endif
13085
Larry Hastings9cf065c2012-06-22 16:30:09 -070013086#ifdef HAVE_FSTATAT
13087 "HAVE_FSTATAT",
13088#endif
13089
13090#ifdef HAVE_FSTATVFS
13091 "HAVE_FSTATVFS",
13092#endif
13093
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013094#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013095 "HAVE_FTRUNCATE",
13096#endif
13097
Larry Hastings9cf065c2012-06-22 16:30:09 -070013098#ifdef HAVE_FUTIMENS
13099 "HAVE_FUTIMENS",
13100#endif
13101
13102#ifdef HAVE_FUTIMES
13103 "HAVE_FUTIMES",
13104#endif
13105
13106#ifdef HAVE_FUTIMESAT
13107 "HAVE_FUTIMESAT",
13108#endif
13109
13110#ifdef HAVE_LINKAT
13111 "HAVE_LINKAT",
13112#endif
13113
13114#ifdef HAVE_LCHFLAGS
13115 "HAVE_LCHFLAGS",
13116#endif
13117
13118#ifdef HAVE_LCHMOD
13119 "HAVE_LCHMOD",
13120#endif
13121
13122#ifdef HAVE_LCHOWN
13123 "HAVE_LCHOWN",
13124#endif
13125
13126#ifdef HAVE_LSTAT
13127 "HAVE_LSTAT",
13128#endif
13129
13130#ifdef HAVE_LUTIMES
13131 "HAVE_LUTIMES",
13132#endif
13133
13134#ifdef HAVE_MKDIRAT
13135 "HAVE_MKDIRAT",
13136#endif
13137
13138#ifdef HAVE_MKFIFOAT
13139 "HAVE_MKFIFOAT",
13140#endif
13141
13142#ifdef HAVE_MKNODAT
13143 "HAVE_MKNODAT",
13144#endif
13145
13146#ifdef HAVE_OPENAT
13147 "HAVE_OPENAT",
13148#endif
13149
13150#ifdef HAVE_READLINKAT
13151 "HAVE_READLINKAT",
13152#endif
13153
13154#ifdef HAVE_RENAMEAT
13155 "HAVE_RENAMEAT",
13156#endif
13157
13158#ifdef HAVE_SYMLINKAT
13159 "HAVE_SYMLINKAT",
13160#endif
13161
13162#ifdef HAVE_UNLINKAT
13163 "HAVE_UNLINKAT",
13164#endif
13165
13166#ifdef HAVE_UTIMENSAT
13167 "HAVE_UTIMENSAT",
13168#endif
13169
13170#ifdef MS_WINDOWS
13171 "MS_WINDOWS",
13172#endif
13173
13174 NULL
13175};
13176
13177
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013178PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013179INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013180{
Victor Stinner8c62be82010-05-06 00:08:46 +000013181 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013182 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013183 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013184
Brian Curtin52173d42010-12-02 18:29:18 +000013185#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013186 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013187#endif
13188
Victor Stinner8c62be82010-05-06 00:08:46 +000013189 m = PyModule_Create(&posixmodule);
13190 if (m == NULL)
13191 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013192
Victor Stinner8c62be82010-05-06 00:08:46 +000013193 /* Initialize environ dictionary */
13194 v = convertenviron();
13195 Py_XINCREF(v);
13196 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13197 return NULL;
13198 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013199
Victor Stinner8c62be82010-05-06 00:08:46 +000013200 if (all_ins(m))
13201 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013202
Victor Stinner8c62be82010-05-06 00:08:46 +000013203 if (setup_confname_tables(m))
13204 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013205
Victor Stinner8c62be82010-05-06 00:08:46 +000013206 Py_INCREF(PyExc_OSError);
13207 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013208
Guido van Rossumb3d39562000-01-31 18:41:26 +000013209#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013210 if (posix_putenv_garbage == NULL)
13211 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013212#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013213
Victor Stinner8c62be82010-05-06 00:08:46 +000013214 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013215#if defined(HAVE_WAITID) && !defined(__APPLE__)
13216 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013217 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13218 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013219#endif
13220
Christian Heimes25827622013-10-12 01:27:08 +020013221 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013222 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13223 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13224 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013225 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13226 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013227 structseq_new = StatResultType.tp_new;
13228 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013229
Christian Heimes25827622013-10-12 01:27:08 +020013230 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013231 if (PyStructSequence_InitType2(&StatVFSResultType,
13232 &statvfs_result_desc) < 0)
13233 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013234#ifdef NEED_TICKS_PER_SECOND
13235# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013236 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013237# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013238 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013239# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013240 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013241# endif
13242#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013243
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013244#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013245 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013246 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13247 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013248 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013249#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013250
13251 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013252 if (PyStructSequence_InitType2(&TerminalSizeType,
13253 &TerminalSize_desc) < 0)
13254 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013255
13256 /* initialize scandir types */
13257 if (PyType_Ready(&ScandirIteratorType) < 0)
13258 return NULL;
13259 if (PyType_Ready(&DirEntryType) < 0)
13260 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013261 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013262#if defined(HAVE_WAITID) && !defined(__APPLE__)
13263 Py_INCREF((PyObject*) &WaitidResultType);
13264 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13265#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013266 Py_INCREF((PyObject*) &StatResultType);
13267 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13268 Py_INCREF((PyObject*) &StatVFSResultType);
13269 PyModule_AddObject(m, "statvfs_result",
13270 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013271
13272#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013273 Py_INCREF(&SchedParamType);
13274 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013275#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013276
Larry Hastings605a62d2012-06-24 04:33:36 -070013277 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013278 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13279 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013280 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13281
13282 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013283 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13284 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013285 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13286
Thomas Wouters477c8d52006-05-27 19:21:47 +000013287#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013288 /*
13289 * Step 2 of weak-linking support on Mac OS X.
13290 *
13291 * The code below removes functions that are not available on the
13292 * currently active platform.
13293 *
13294 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013295 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013296 * OSX 10.4.
13297 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013298#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013299 if (fstatvfs == NULL) {
13300 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13301 return NULL;
13302 }
13303 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013304#endif /* HAVE_FSTATVFS */
13305
13306#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013307 if (statvfs == NULL) {
13308 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13309 return NULL;
13310 }
13311 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013312#endif /* HAVE_STATVFS */
13313
13314# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013315 if (lchown == NULL) {
13316 if (PyObject_DelAttrString(m, "lchown") == -1) {
13317 return NULL;
13318 }
13319 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013320#endif /* HAVE_LCHOWN */
13321
13322
13323#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013324
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013325 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013326 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13327
Larry Hastings6fe20b32012-04-19 15:07:49 -070013328 billion = PyLong_FromLong(1000000000);
13329 if (!billion)
13330 return NULL;
13331
Larry Hastings9cf065c2012-06-22 16:30:09 -070013332 /* suppress "function not used" warnings */
13333 {
13334 int ignored;
13335 fd_specified("", -1);
13336 follow_symlinks_specified("", 1);
13337 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13338 dir_fd_converter(Py_None, &ignored);
13339 dir_fd_unavailable(Py_None, &ignored);
13340 }
13341
13342 /*
13343 * provide list of locally available functions
13344 * so os.py can populate support_* lists
13345 */
13346 list = PyList_New(0);
13347 if (!list)
13348 return NULL;
13349 for (trace = have_functions; *trace; trace++) {
13350 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13351 if (!unicode)
13352 return NULL;
13353 if (PyList_Append(list, unicode))
13354 return NULL;
13355 Py_DECREF(unicode);
13356 }
13357 PyModule_AddObject(m, "_have_functions", list);
Ned Deilyeb3be662016-08-15 14:40:38 -040013358
13359 Py_INCREF((PyObject *) &DirEntryType);
Brett Cannona32c4d02016-06-24 14:14:44 -070013360 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013361
13362 initialized = 1;
13363
Victor Stinner8c62be82010-05-06 00:08:46 +000013364 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013365}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013366
13367#ifdef __cplusplus
13368}
13369#endif