blob: 4dc7c494657e0ce0f06f77cf22228e98490a6819 [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 Storchaka819399b2016-04-06 22:17:52 +0300894 else if (PyObject_CheckBuffer(o)) {
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300895#ifdef MS_WINDOWS
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300896 if (win32_warn_bytes_api()) {
897 return 0;
898 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300899#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300900 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901 if (!bytes) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300902 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903 }
904 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300905 else if (path->allow_fd && PyIndex_Check(o)) {
906 if (!_fd_converter(o, &path->fd)) {
907 return 0;
908 }
909 path->wide = NULL;
910 path->narrow = NULL;
911 path->length = 0;
912 path->object = o;
913 return 1;
914 }
915 else {
916 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
917 path->function_name ? path->function_name : "",
918 path->function_name ? ": " : "",
919 path->argument_name ? path->argument_name : "path",
920 path->allow_fd && path->nullable ? "string, bytes, integer or None" :
921 path->allow_fd ? "string, bytes or integer" :
922 path->nullable ? "string, bytes or None" :
923 "string or bytes",
924 Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925 return 0;
926 }
927
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928 length = PyBytes_GET_SIZE(bytes);
929#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100930 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
932 Py_DECREF(bytes);
933 return 0;
934 }
935#endif
936
937 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200938 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300939 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 Py_DECREF(bytes);
941 return 0;
942 }
943
944 path->wide = NULL;
945 path->narrow = narrow;
946 path->length = length;
947 path->object = o;
948 path->fd = -1;
949 path->cleanup = bytes;
950 return Py_CLEANUP_SUPPORTED;
951}
952
953static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200954argument_unavailable_error(const char *function_name, const char *argument_name)
955{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956 PyErr_Format(PyExc_NotImplementedError,
957 "%s%s%s unavailable on this platform",
958 (function_name != NULL) ? function_name : "",
959 (function_name != NULL) ? ": ": "",
960 argument_name);
961}
962
963static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200964dir_fd_unavailable(PyObject *o, void *p)
965{
966 int dir_fd;
967 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200969 if (dir_fd != DEFAULT_DIR_FD) {
970 argument_unavailable_error(NULL, "dir_fd");
971 return 0;
972 }
973 *(int *)p = dir_fd;
974 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700975}
976
977static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200978fd_specified(const char *function_name, int fd)
979{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700980 if (fd == -1)
981 return 0;
982
983 argument_unavailable_error(function_name, "fd");
984 return 1;
985}
986
987static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200988follow_symlinks_specified(const char *function_name, int follow_symlinks)
989{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700990 if (follow_symlinks)
991 return 0;
992
993 argument_unavailable_error(function_name, "follow_symlinks");
994 return 1;
995}
996
997static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200998path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
999{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001000 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
1001 PyErr_Format(PyExc_ValueError,
1002 "%s: can't specify dir_fd without matching path",
1003 function_name);
1004 return 1;
1005 }
1006 return 0;
1007}
1008
1009static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001010dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1011{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001012 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1013 PyErr_Format(PyExc_ValueError,
1014 "%s: can't specify both dir_fd and fd",
1015 function_name);
1016 return 1;
1017 }
1018 return 0;
1019}
1020
1021static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001022fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1023 int follow_symlinks)
1024{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025 if ((fd > 0) && (!follow_symlinks)) {
1026 PyErr_Format(PyExc_ValueError,
1027 "%s: cannot use fd and follow_symlinks together",
1028 function_name);
1029 return 1;
1030 }
1031 return 0;
1032}
1033
1034static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001035dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1036 int follow_symlinks)
1037{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1039 PyErr_Format(PyExc_ValueError,
1040 "%s: cannot use dir_fd and follow_symlinks together",
1041 function_name);
1042 return 1;
1043 }
1044 return 0;
1045}
1046
Larry Hastings2f936352014-08-05 14:04:04 +10001047#ifdef MS_WINDOWS
1048 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001049#else
Larry Hastings2f936352014-08-05 14:04:04 +10001050 typedef off_t Py_off_t;
1051#endif
1052
1053static int
1054Py_off_t_converter(PyObject *arg, void *addr)
1055{
1056#ifdef HAVE_LARGEFILE_SUPPORT
1057 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1058#else
1059 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001060#endif
1061 if (PyErr_Occurred())
1062 return 0;
1063 return 1;
1064}
Larry Hastings2f936352014-08-05 14:04:04 +10001065
1066static PyObject *
1067PyLong_FromPy_off_t(Py_off_t offset)
1068{
1069#ifdef HAVE_LARGEFILE_SUPPORT
1070 return PyLong_FromLongLong(offset);
1071#else
1072 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001073#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001074}
1075
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001076
Steve Dowerd81431f2015-03-06 14:47:02 -08001077#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1078/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1079 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001080 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001081#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001082#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001083#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001084#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001085#define _NO_CONSOLE_FILENO (intptr_t)-2
1086
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001087/* the special case of checking dup2. The target fd must be in a sensible range */
1088static int
1089_PyVerify_fd_dup2(int fd1, int fd2)
1090{
Victor Stinner8c62be82010-05-06 00:08:46 +00001091 if (!_PyVerify_fd(fd1))
1092 return 0;
1093 if (fd2 == _NO_CONSOLE_FILENO)
1094 return 0;
1095 if ((unsigned)fd2 < _NHANDLE_)
1096 return 1;
1097 else
1098 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001099}
1100#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001101#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001102#endif
1103
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001104#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001105
1106static int
Brian Curtind25aef52011-06-13 15:16:04 -05001107win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001108{
1109 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1110 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1111 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112
1113 if (0 == DeviceIoControl(
1114 reparse_point_handle,
1115 FSCTL_GET_REPARSE_POINT,
1116 NULL, 0, /* in buffer */
1117 target_buffer, sizeof(target_buffer),
1118 &n_bytes_returned,
1119 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001120 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001121
1122 if (reparse_tag)
1123 *reparse_tag = rdb->ReparseTag;
1124
Brian Curtind25aef52011-06-13 15:16:04 -05001125 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001126}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001127
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001128#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001129
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001131#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001132/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001133** environ directly, we must obtain it with _NSGetEnviron(). See also
1134** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001135*/
1136#include <crt_externs.h>
1137static char **environ;
1138#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001140#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001141
Barry Warsaw53699e91996-12-10 23:23:01 +00001142static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001143convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001144{
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001147 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001148#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001149 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001150#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151
Victor Stinner8c62be82010-05-06 00:08:46 +00001152 d = PyDict_New();
1153 if (d == NULL)
1154 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001155#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001156 if (environ == NULL)
1157 environ = *_NSGetEnviron();
1158#endif
1159#ifdef MS_WINDOWS
1160 /* _wenviron must be initialized in this way if the program is started
1161 through main() instead of wmain(). */
1162 _wgetenv(L"");
1163 if (_wenviron == NULL)
1164 return d;
1165 /* This part ignores errors */
1166 for (e = _wenviron; *e != NULL; e++) {
1167 PyObject *k;
1168 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001169 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001170 if (p == NULL)
1171 continue;
1172 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1173 if (k == NULL) {
1174 PyErr_Clear();
1175 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001176 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001177 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1178 if (v == NULL) {
1179 PyErr_Clear();
1180 Py_DECREF(k);
1181 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001182 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001183 if (PyDict_GetItem(d, k) == NULL) {
1184 if (PyDict_SetItem(d, k, v) != 0)
1185 PyErr_Clear();
1186 }
1187 Py_DECREF(k);
1188 Py_DECREF(v);
1189 }
1190#else
1191 if (environ == NULL)
1192 return d;
1193 /* This part ignores errors */
1194 for (e = environ; *e != NULL; e++) {
1195 PyObject *k;
1196 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001197 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001198 if (p == NULL)
1199 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001200 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 if (k == NULL) {
1202 PyErr_Clear();
1203 continue;
1204 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001205 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001206 if (v == NULL) {
1207 PyErr_Clear();
1208 Py_DECREF(k);
1209 continue;
1210 }
1211 if (PyDict_GetItem(d, k) == NULL) {
1212 if (PyDict_SetItem(d, k, v) != 0)
1213 PyErr_Clear();
1214 }
1215 Py_DECREF(k);
1216 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001217 }
1218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001219 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220}
1221
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222/* Set a POSIX-specific error from errno, and return NULL */
1223
Barry Warsawd58d7641998-07-23 16:14:40 +00001224static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001225posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001226{
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228}
Mark Hammondef8b6542001-05-13 08:04:26 +00001229
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001230#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001231static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001232win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001233{
Victor Stinner8c62be82010-05-06 00:08:46 +00001234 /* XXX We should pass the function name along in the future.
1235 (winreg.c also wants to pass the function name.)
1236 This would however require an additional param to the
1237 Windows error object, which is non-trivial.
1238 */
1239 errno = GetLastError();
1240 if (filename)
1241 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1242 else
1243 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001244}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001245
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001246static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001247win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001248{
1249 /* XXX - see win32_error for comments on 'function' */
1250 errno = GetLastError();
1251 if (filename)
1252 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001253 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001254 errno,
1255 filename);
1256 else
1257 return PyErr_SetFromWindowsErr(errno);
1258}
1259
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001260#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001261
Larry Hastings9cf065c2012-06-22 16:30:09 -07001262static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001263path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001264{
1265#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001266 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1267 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001268#else
Victor Stinner292c8352012-10-30 02:17:38 +01001269 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001270#endif
1271}
1272
Larry Hastings31826802013-10-19 00:09:25 -07001273
Larry Hastingsb0827312014-02-09 22:05:19 -08001274static PyObject *
1275path_error2(path_t *path, path_t *path2)
1276{
1277#ifdef MS_WINDOWS
1278 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1279 0, path->object, path2->object);
1280#else
1281 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1282 path->object, path2->object);
1283#endif
1284}
1285
1286
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287/* POSIX generic methods */
1288
Larry Hastings2f936352014-08-05 14:04:04 +10001289static int
1290fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001291{
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001293 int *pointer = (int *)p;
1294 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001296 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001297 *pointer = fd;
1298 return 1;
1299}
1300
1301static PyObject *
1302posix_fildes_fd(int fd, int (*func)(int))
1303{
1304 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001305 int async_err = 0;
1306
Steve Dower8fc89802015-04-12 00:26:27 -04001307 if (!_PyVerify_fd(fd))
1308 return posix_error();
1309
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001310 do {
1311 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001312 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001313 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001314 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001315 Py_END_ALLOW_THREADS
1316 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1317 if (res != 0)
1318 return (!async_err) ? posix_error() : NULL;
1319 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001320}
Guido van Rossum21142a01999-01-08 21:05:37 +00001321
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001323#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001324/* This is a reimplementation of the C library's chdir function,
1325 but one that produces Win32 errors instead of DOS error codes.
1326 chdir is essentially a wrapper around SetCurrentDirectory; however,
1327 it also needs to set "magic" environment variables indicating
1328 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001329static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001330win32_chdir(LPCSTR path)
1331{
Victor Stinner75875072013-11-24 19:23:25 +01001332 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001333 int result;
1334 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 if(!SetCurrentDirectoryA(path))
1337 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001338 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 if (!result)
1340 return FALSE;
1341 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001342 than MAX_PATH-1 (not including the final null character). */
1343 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001344 if (strncmp(new_path, "\\\\", 2) == 0 ||
1345 strncmp(new_path, "//", 2) == 0)
1346 /* UNC path, nothing to do. */
1347 return TRUE;
1348 env[1] = new_path[0];
1349 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001350}
1351
1352/* The Unicode version differs from the ANSI version
1353 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001354static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001355win32_wchdir(LPCWSTR path)
1356{
Victor Stinnered537822015-12-13 21:40:26 +01001357 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 int result;
1359 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 if(!SetCurrentDirectoryW(path))
1362 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001363 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 if (!result)
1365 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001366 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001367 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 if (!new_path) {
1369 SetLastError(ERROR_OUTOFMEMORY);
1370 return FALSE;
1371 }
1372 result = GetCurrentDirectoryW(result, new_path);
1373 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001374 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 return FALSE;
1376 }
1377 }
1378 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1379 wcsncmp(new_path, L"//", 2) == 0)
1380 /* UNC path, nothing to do. */
1381 return TRUE;
1382 env[1] = new_path[0];
1383 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001384 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001385 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001387}
1388#endif
1389
Martin v. Löwis14694662006-02-03 12:54:16 +00001390#ifdef MS_WINDOWS
1391/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1392 - time stamps are restricted to second resolution
1393 - file modification times suffer from forth-and-back conversions between
1394 UTC and local time
1395 Therefore, we implement our own stat, based on the Win32 API directly.
1396*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001397#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001398#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001399
Guido van Rossumd8faa362007-04-27 19:54:29 +00001400static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001401attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001402{
Victor Stinner8c62be82010-05-06 00:08:46 +00001403 HANDLE hFindFile;
1404 WIN32_FIND_DATAA FileData;
1405 hFindFile = FindFirstFileA(pszFile, &FileData);
1406 if (hFindFile == INVALID_HANDLE_VALUE)
1407 return FALSE;
1408 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001409 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001410 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001411 info->dwFileAttributes = FileData.dwFileAttributes;
1412 info->ftCreationTime = FileData.ftCreationTime;
1413 info->ftLastAccessTime = FileData.ftLastAccessTime;
1414 info->ftLastWriteTime = FileData.ftLastWriteTime;
1415 info->nFileSizeHigh = FileData.nFileSizeHigh;
1416 info->nFileSizeLow = FileData.nFileSizeLow;
1417/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001418 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1419 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001421}
1422
Victor Stinner6036e442015-03-08 01:58:04 +01001423static void
1424find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1425 BY_HANDLE_FILE_INFORMATION *info,
1426 ULONG *reparse_tag)
1427{
1428 memset(info, 0, sizeof(*info));
1429 info->dwFileAttributes = pFileData->dwFileAttributes;
1430 info->ftCreationTime = pFileData->ftCreationTime;
1431 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1432 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1433 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1434 info->nFileSizeLow = pFileData->nFileSizeLow;
1435/* info->nNumberOfLinks = 1; */
1436 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1437 *reparse_tag = pFileData->dwReserved0;
1438 else
1439 *reparse_tag = 0;
1440}
1441
Guido van Rossumd8faa362007-04-27 19:54:29 +00001442static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001443attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001444{
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 HANDLE hFindFile;
1446 WIN32_FIND_DATAW FileData;
1447 hFindFile = FindFirstFileW(pszFile, &FileData);
1448 if (hFindFile == INVALID_HANDLE_VALUE)
1449 return FALSE;
1450 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001451 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001453}
1454
Brian Curtind25aef52011-06-13 15:16:04 -05001455static BOOL
1456get_target_path(HANDLE hdl, wchar_t **target_path)
1457{
1458 int buf_size, result_length;
1459 wchar_t *buf;
1460
1461 /* We have a good handle to the target, use it to determine
1462 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001463 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1464 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001465 if(!buf_size)
1466 return FALSE;
1467
Victor Stinnerc36674a2016-03-16 14:30:16 +01001468 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001469 if (!buf) {
1470 SetLastError(ERROR_OUTOFMEMORY);
1471 return FALSE;
1472 }
1473
Steve Dower2ea51c92015-03-20 21:49:12 -07001474 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001475 buf, buf_size, VOLUME_NAME_DOS);
1476
1477 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001478 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001479 return FALSE;
1480 }
1481
1482 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001483 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001484 return FALSE;
1485 }
1486
1487 buf[result_length] = 0;
1488
1489 *target_path = buf;
1490 return TRUE;
1491}
1492
1493static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001494win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001495 BOOL traverse);
1496static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001497win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001498 BOOL traverse)
1499{
Victor Stinner26de69d2011-06-17 15:15:38 +02001500 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001501 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001502 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001503 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001504 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001505 const char *dot;
1506
1507 hFile = CreateFileA(
1508 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001509 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 0, /* share mode */
1511 NULL, /* security attributes */
1512 OPEN_EXISTING,
1513 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001514 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1515 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001516 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001517 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1518 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001519 NULL);
1520
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 /* Either the target doesn't exist, or we don't have access to
1523 get a handle to it. If the former, we need to return an error.
1524 If the latter, we can use attributes_from_dir. */
1525 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526 return -1;
1527 /* Could not get attributes on open file. Fall back to
1528 reading the directory. */
1529 if (!attributes_from_dir(path, &info, &reparse_tag))
1530 /* Very strange. This should not fail now */
1531 return -1;
1532 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1533 if (traverse) {
1534 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001535 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001536 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001537 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001539 } else {
1540 if (!GetFileInformationByHandle(hFile, &info)) {
1541 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001542 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001543 }
1544 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001545 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1546 return -1;
1547
1548 /* Close the outer open file handle now that we're about to
1549 reopen it with different flags. */
1550 if (!CloseHandle(hFile))
1551 return -1;
1552
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001553 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001554 /* In order to call GetFinalPathNameByHandle we need to open
1555 the file without the reparse handling flag set. */
1556 hFile2 = CreateFileA(
1557 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1558 NULL, OPEN_EXISTING,
1559 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1560 NULL);
1561 if (hFile2 == INVALID_HANDLE_VALUE)
1562 return -1;
1563
1564 if (!get_target_path(hFile2, &target_path))
1565 return -1;
1566
1567 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001568 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001569 return code;
1570 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001571 } else
1572 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001574 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575
1576 /* Set S_IEXEC if it is an .exe, .bat, ... */
1577 dot = strrchr(path, '.');
1578 if (dot) {
1579 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1580 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1581 result->st_mode |= 0111;
1582 }
1583 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001584}
1585
1586static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001587win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001588 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589{
1590 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001591 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001592 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001593 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001594 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 const wchar_t *dot;
1596
1597 hFile = CreateFileW(
1598 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001599 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001600 0, /* share mode */
1601 NULL, /* security attributes */
1602 OPEN_EXISTING,
1603 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001604 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1605 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001606 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001607 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001608 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 NULL);
1610
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001611 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001612 /* Either the target doesn't exist, or we don't have access to
1613 get a handle to it. If the former, we need to return an error.
1614 If the latter, we can use attributes_from_dir. */
1615 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001616 return -1;
1617 /* Could not get attributes on open file. Fall back to
1618 reading the directory. */
1619 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1620 /* Very strange. This should not fail now */
1621 return -1;
1622 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1623 if (traverse) {
1624 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001627 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001628 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001629 } else {
1630 if (!GetFileInformationByHandle(hFile, &info)) {
1631 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001632 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001633 }
1634 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001635 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1636 return -1;
1637
1638 /* Close the outer open file handle now that we're about to
1639 reopen it with different flags. */
1640 if (!CloseHandle(hFile))
1641 return -1;
1642
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001644 /* In order to call GetFinalPathNameByHandle we need to open
1645 the file without the reparse handling flag set. */
1646 hFile2 = CreateFileW(
1647 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1648 NULL, OPEN_EXISTING,
1649 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1650 NULL);
1651 if (hFile2 == INVALID_HANDLE_VALUE)
1652 return -1;
1653
1654 if (!get_target_path(hFile2, &target_path))
1655 return -1;
1656
1657 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001658 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001659 return code;
1660 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001661 } else
1662 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001664 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001665
1666 /* Set S_IEXEC if it is an .exe, .bat, ... */
1667 dot = wcsrchr(path, '.');
1668 if (dot) {
1669 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1670 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1671 result->st_mode |= 0111;
1672 }
1673 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674}
1675
1676static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001677win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 /* Protocol violation: we explicitly clear errno, instead of
1680 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001681 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001682 errno = 0;
1683 return code;
1684}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001687win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688{
1689 /* Protocol violation: we explicitly clear errno, instead of
1690 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001691 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 errno = 0;
1693 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694}
Brian Curtind25aef52011-06-13 15:16:04 -05001695/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001696
1697 In Posix, stat automatically traverses symlinks and returns the stat
1698 structure for the target. In Windows, the equivalent GetFileAttributes by
1699 default does not traverse symlinks and instead returns attributes for
1700 the symlink.
1701
1702 Therefore, win32_lstat will get the attributes traditionally, and
1703 win32_stat will first explicitly resolve the symlink target and then will
1704 call win32_lstat on that result.
1705
Ezio Melotti4969f702011-03-15 05:59:46 +02001706 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001707
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001708static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001709win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001710{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001712}
1713
Victor Stinner8c62be82010-05-06 00:08:46 +00001714static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001715win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001716{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001717 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001718}
1719
1720static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001721win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001722{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001724}
1725
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001726static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001727win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001728{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001730}
1731
Martin v. Löwis14694662006-02-03 12:54:16 +00001732#endif /* MS_WINDOWS */
1733
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001735"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001736This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001737 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001738or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1739\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001740Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1741or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001742\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001743See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001744
1745static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 {"st_mode", "protection bits"},
1747 {"st_ino", "inode"},
1748 {"st_dev", "device"},
1749 {"st_nlink", "number of hard links"},
1750 {"st_uid", "user ID of owner"},
1751 {"st_gid", "group ID of owner"},
1752 {"st_size", "total size, in bytes"},
1753 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1754 {NULL, "integer time of last access"},
1755 {NULL, "integer time of last modification"},
1756 {NULL, "integer time of last change"},
1757 {"st_atime", "time of last access"},
1758 {"st_mtime", "time of last modification"},
1759 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001760 {"st_atime_ns", "time of last access in nanoseconds"},
1761 {"st_mtime_ns", "time of last modification in nanoseconds"},
1762 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001763#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001766#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001768#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001769#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001772#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001774#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001775#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001777#endif
1778#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001780#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001781#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1782 {"st_file_attributes", "Windows file attribute bits"},
1783#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785};
1786
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001788#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001790#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791#endif
1792
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001793#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001794#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1795#else
1796#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1797#endif
1798
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001799#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001800#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1801#else
1802#define ST_RDEV_IDX ST_BLOCKS_IDX
1803#endif
1804
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001805#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1806#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1807#else
1808#define ST_FLAGS_IDX ST_RDEV_IDX
1809#endif
1810
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001811#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001812#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001813#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001814#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001815#endif
1816
1817#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1818#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1819#else
1820#define ST_BIRTHTIME_IDX ST_GEN_IDX
1821#endif
1822
Zachary Ware63f277b2014-06-19 09:46:37 -05001823#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1824#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1825#else
1826#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1827#endif
1828
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 "stat_result", /* name */
1831 stat_result__doc__, /* doc */
1832 stat_result_fields,
1833 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834};
1835
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1838This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001839 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001840or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001842See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001843
1844static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 {"f_bsize", },
1846 {"f_frsize", },
1847 {"f_blocks", },
1848 {"f_bfree", },
1849 {"f_bavail", },
1850 {"f_files", },
1851 {"f_ffree", },
1852 {"f_favail", },
1853 {"f_flag", },
1854 {"f_namemax",},
1855 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856};
1857
1858static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 "statvfs_result", /* name */
1860 statvfs_result__doc__, /* doc */
1861 statvfs_result_fields,
1862 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001863};
1864
Ross Lagerwall7807c352011-03-17 20:20:30 +02001865#if defined(HAVE_WAITID) && !defined(__APPLE__)
1866PyDoc_STRVAR(waitid_result__doc__,
1867"waitid_result: Result from waitid.\n\n\
1868This object may be accessed either as a tuple of\n\
1869 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1870or via the attributes si_pid, si_uid, and so on.\n\
1871\n\
1872See os.waitid for more information.");
1873
1874static PyStructSequence_Field waitid_result_fields[] = {
1875 {"si_pid", },
1876 {"si_uid", },
1877 {"si_signo", },
1878 {"si_status", },
1879 {"si_code", },
1880 {0}
1881};
1882
1883static PyStructSequence_Desc waitid_result_desc = {
1884 "waitid_result", /* name */
1885 waitid_result__doc__, /* doc */
1886 waitid_result_fields,
1887 5
1888};
1889static PyTypeObject WaitidResultType;
1890#endif
1891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001892static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893static PyTypeObject StatResultType;
1894static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001895#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001896static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001897#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001898static newfunc structseq_new;
1899
1900static PyObject *
1901statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1902{
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 PyStructSequence *result;
1904 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 result = (PyStructSequence*)structseq_new(type, args, kwds);
1907 if (!result)
1908 return NULL;
1909 /* If we have been initialized from a tuple,
1910 st_?time might be set to None. Initialize it
1911 from the int slots. */
1912 for (i = 7; i <= 9; i++) {
1913 if (result->ob_item[i+3] == Py_None) {
1914 Py_DECREF(Py_None);
1915 Py_INCREF(result->ob_item[i]);
1916 result->ob_item[i+3] = result->ob_item[i];
1917 }
1918 }
1919 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001920}
1921
1922
1923
1924/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001925static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001926
1927PyDoc_STRVAR(stat_float_times__doc__,
1928"stat_float_times([newval]) -> oldval\n\n\
1929Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001930\n\
1931If value is True, future calls to stat() return floats; if it is False,\n\
1932future calls return ints.\n\
1933If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001934
Larry Hastings2f936352014-08-05 14:04:04 +10001935/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001936static PyObject*
1937stat_float_times(PyObject* self, PyObject *args)
1938{
Victor Stinner8c62be82010-05-06 00:08:46 +00001939 int newval = -1;
1940 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1941 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001942 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1943 "stat_float_times() is deprecated",
1944 1))
1945 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 if (newval == -1)
1947 /* Return old value */
1948 return PyBool_FromLong(_stat_float_times);
1949 _stat_float_times = newval;
1950 Py_INCREF(Py_None);
1951 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001952}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001953
Larry Hastings6fe20b32012-04-19 15:07:49 -07001954static PyObject *billion = NULL;
1955
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001956static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001957fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001958{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001959 PyObject *s = _PyLong_FromTime_t(sec);
1960 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1961 PyObject *s_in_ns = NULL;
1962 PyObject *ns_total = NULL;
1963 PyObject *float_s = NULL;
1964
1965 if (!(s && ns_fractional))
1966 goto exit;
1967
1968 s_in_ns = PyNumber_Multiply(s, billion);
1969 if (!s_in_ns)
1970 goto exit;
1971
1972 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1973 if (!ns_total)
1974 goto exit;
1975
Victor Stinner4195b5c2012-02-08 23:03:19 +01001976 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001977 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1978 if (!float_s)
1979 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001981 else {
1982 float_s = s;
1983 Py_INCREF(float_s);
1984 }
1985
1986 PyStructSequence_SET_ITEM(v, index, s);
1987 PyStructSequence_SET_ITEM(v, index+3, float_s);
1988 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1989 s = NULL;
1990 float_s = NULL;
1991 ns_total = NULL;
1992exit:
1993 Py_XDECREF(s);
1994 Py_XDECREF(ns_fractional);
1995 Py_XDECREF(s_in_ns);
1996 Py_XDECREF(ns_total);
1997 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001998}
1999
Tim Peters5aa91602002-01-30 05:46:57 +00002000/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002001 (used by posix_stat() and posix_fstat()) */
2002static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002003_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002004{
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 unsigned long ansec, mnsec, cnsec;
2006 PyObject *v = PyStructSequence_New(&StatResultType);
2007 if (v == NULL)
2008 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002009
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002011#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 PyStructSequence_SET_ITEM(v, 1,
2013 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002014#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002016#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002017#ifdef MS_WINDOWS
2018 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002019#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002020 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002023#if defined(MS_WINDOWS)
2024 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2025 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2026#else
2027 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2028 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2029#endif
Fred Drake699f3522000-06-29 21:12:41 +00002030#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 PyStructSequence_SET_ITEM(v, 6,
2032 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002035#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002036
Martin v. Löwis14694662006-02-03 12:54:16 +00002037#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 ansec = st->st_atim.tv_nsec;
2039 mnsec = st->st_mtim.tv_nsec;
2040 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002041#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 ansec = st->st_atimespec.tv_nsec;
2043 mnsec = st->st_mtimespec.tv_nsec;
2044 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002045#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 ansec = st->st_atime_nsec;
2047 mnsec = st->st_mtime_nsec;
2048 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002049#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002051#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002052 fill_time(v, 7, st->st_atime, ansec);
2053 fill_time(v, 8, st->st_mtime, mnsec);
2054 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002055
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002056#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2058 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002059#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002060#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2062 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002063#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002064#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2066 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002067#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002068#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2070 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002071#endif
2072#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002074 PyObject *val;
2075 unsigned long bsec,bnsec;
2076 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002077#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002078 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002079#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002080 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002081#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002082 if (_stat_float_times) {
2083 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2084 } else {
2085 val = PyLong_FromLong((long)bsec);
2086 }
2087 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2088 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002090#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002091#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2093 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002094#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002095#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2096 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2097 PyLong_FromUnsignedLong(st->st_file_attributes));
2098#endif
Fred Drake699f3522000-06-29 21:12:41 +00002099
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 if (PyErr_Occurred()) {
2101 Py_DECREF(v);
2102 return NULL;
2103 }
Fred Drake699f3522000-06-29 21:12:41 +00002104
Victor Stinner8c62be82010-05-06 00:08:46 +00002105 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002106}
2107
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108/* POSIX methods */
2109
Guido van Rossum94f6f721999-01-06 18:42:14 +00002110
2111static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002112posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002113 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002114{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002115 STRUCT_STAT st;
2116 int result;
2117
2118#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2119 if (follow_symlinks_specified(function_name, follow_symlinks))
2120 return NULL;
2121#endif
2122
2123 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2124 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2125 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2126 return NULL;
2127
2128 Py_BEGIN_ALLOW_THREADS
2129 if (path->fd != -1)
2130 result = FSTAT(path->fd, &st);
2131 else
2132#ifdef MS_WINDOWS
2133 if (path->wide) {
2134 if (follow_symlinks)
2135 result = win32_stat_w(path->wide, &st);
2136 else
2137 result = win32_lstat_w(path->wide, &st);
2138 }
2139 else
2140#endif
2141#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2142 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2143 result = LSTAT(path->narrow, &st);
2144 else
2145#endif
2146#ifdef HAVE_FSTATAT
2147 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2148 result = fstatat(dir_fd, path->narrow, &st,
2149 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2150 else
2151#endif
2152 result = STAT(path->narrow, &st);
2153 Py_END_ALLOW_THREADS
2154
Victor Stinner292c8352012-10-30 02:17:38 +01002155 if (result != 0) {
2156 return path_error(path);
2157 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002158
2159 return _pystat_fromstructstat(&st);
2160}
2161
Larry Hastings2f936352014-08-05 14:04:04 +10002162/*[python input]
2163
2164for s in """
2165
2166FACCESSAT
2167FCHMODAT
2168FCHOWNAT
2169FSTATAT
2170LINKAT
2171MKDIRAT
2172MKFIFOAT
2173MKNODAT
2174OPENAT
2175READLINKAT
2176SYMLINKAT
2177UNLINKAT
2178
2179""".strip().split():
2180 s = s.strip()
2181 print("""
2182#ifdef HAVE_{s}
2183 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002184#else
Larry Hastings2f936352014-08-05 14:04:04 +10002185 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002186#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002187""".rstrip().format(s=s))
2188
2189for s in """
2190
2191FCHDIR
2192FCHMOD
2193FCHOWN
2194FDOPENDIR
2195FEXECVE
2196FPATHCONF
2197FSTATVFS
2198FTRUNCATE
2199
2200""".strip().split():
2201 s = s.strip()
2202 print("""
2203#ifdef HAVE_{s}
2204 #define PATH_HAVE_{s} 1
2205#else
2206 #define PATH_HAVE_{s} 0
2207#endif
2208
2209""".rstrip().format(s=s))
2210[python start generated code]*/
2211
2212#ifdef HAVE_FACCESSAT
2213 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_FCHMODAT
2219 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_FCHOWNAT
2225 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_FSTATAT
2231 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_LINKAT
2237 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_MKDIRAT
2243 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_MKFIFOAT
2249 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_MKNODAT
2255 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_OPENAT
2261 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_READLINKAT
2267 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2268#else
2269 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2270#endif
2271
2272#ifdef HAVE_SYMLINKAT
2273 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2274#else
2275 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2276#endif
2277
2278#ifdef HAVE_UNLINKAT
2279 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2280#else
2281 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2282#endif
2283
2284#ifdef HAVE_FCHDIR
2285 #define PATH_HAVE_FCHDIR 1
2286#else
2287 #define PATH_HAVE_FCHDIR 0
2288#endif
2289
2290#ifdef HAVE_FCHMOD
2291 #define PATH_HAVE_FCHMOD 1
2292#else
2293 #define PATH_HAVE_FCHMOD 0
2294#endif
2295
2296#ifdef HAVE_FCHOWN
2297 #define PATH_HAVE_FCHOWN 1
2298#else
2299 #define PATH_HAVE_FCHOWN 0
2300#endif
2301
2302#ifdef HAVE_FDOPENDIR
2303 #define PATH_HAVE_FDOPENDIR 1
2304#else
2305 #define PATH_HAVE_FDOPENDIR 0
2306#endif
2307
2308#ifdef HAVE_FEXECVE
2309 #define PATH_HAVE_FEXECVE 1
2310#else
2311 #define PATH_HAVE_FEXECVE 0
2312#endif
2313
2314#ifdef HAVE_FPATHCONF
2315 #define PATH_HAVE_FPATHCONF 1
2316#else
2317 #define PATH_HAVE_FPATHCONF 0
2318#endif
2319
2320#ifdef HAVE_FSTATVFS
2321 #define PATH_HAVE_FSTATVFS 1
2322#else
2323 #define PATH_HAVE_FSTATVFS 0
2324#endif
2325
2326#ifdef HAVE_FTRUNCATE
2327 #define PATH_HAVE_FTRUNCATE 1
2328#else
2329 #define PATH_HAVE_FTRUNCATE 0
2330#endif
2331/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002332
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002333#ifdef MS_WINDOWS
2334 #undef PATH_HAVE_FTRUNCATE
2335 #define PATH_HAVE_FTRUNCATE 1
2336#endif
Larry Hastings31826802013-10-19 00:09:25 -07002337
Larry Hastings61272b72014-01-07 12:41:53 -08002338/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002339
2340class path_t_converter(CConverter):
2341
2342 type = "path_t"
2343 impl_by_reference = True
2344 parse_by_reference = True
2345
2346 converter = 'path_converter'
2347
2348 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002349 # right now path_t doesn't support default values.
2350 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002351 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002352 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002353
Larry Hastings2f936352014-08-05 14:04:04 +10002354 if self.c_default not in (None, 'Py_None'):
2355 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002356
2357 self.nullable = nullable
2358 self.allow_fd = allow_fd
2359
Larry Hastings7726ac92014-01-31 22:03:12 -08002360 def pre_render(self):
2361 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002362 if isinstance(value, str):
2363 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002364 return str(int(bool(value)))
2365
2366 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002367 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002368 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002369 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002370 strify(self.nullable),
2371 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002372 )
2373
2374 def cleanup(self):
2375 return "path_cleanup(&" + self.name + ");\n"
2376
2377
2378class dir_fd_converter(CConverter):
2379 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings2f936352014-08-05 14:04:04 +10002381 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002382 if self.default in (unspecified, None):
2383 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002384 if isinstance(requires, str):
2385 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2386 else:
2387 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002388
Larry Hastings2f936352014-08-05 14:04:04 +10002389class fildes_converter(CConverter):
2390 type = 'int'
2391 converter = 'fildes_converter'
2392
2393class uid_t_converter(CConverter):
2394 type = "uid_t"
2395 converter = '_Py_Uid_Converter'
2396
2397class gid_t_converter(CConverter):
2398 type = "gid_t"
2399 converter = '_Py_Gid_Converter'
2400
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002401class dev_t_converter(CConverter):
2402 type = 'dev_t'
2403 converter = '_Py_Dev_Converter'
2404
2405class dev_t_return_converter(unsigned_long_return_converter):
2406 type = 'dev_t'
2407 conversion_fn = '_PyLong_FromDev'
2408 unsigned_cast = '(dev_t)'
2409
Larry Hastings2f936352014-08-05 14:04:04 +10002410class FSConverter_converter(CConverter):
2411 type = 'PyObject *'
2412 converter = 'PyUnicode_FSConverter'
2413 def converter_init(self):
2414 if self.default is not unspecified:
2415 fail("FSConverter_converter does not support default values")
2416 self.c_default = 'NULL'
2417
2418 def cleanup(self):
2419 return "Py_XDECREF(" + self.name + ");\n"
2420
2421class pid_t_converter(CConverter):
2422 type = 'pid_t'
2423 format_unit = '" _Py_PARSE_PID "'
2424
2425class idtype_t_converter(int_converter):
2426 type = 'idtype_t'
2427
2428class id_t_converter(CConverter):
2429 type = 'id_t'
2430 format_unit = '" _Py_PARSE_PID "'
2431
2432class Py_intptr_t_converter(CConverter):
2433 type = 'Py_intptr_t'
2434 format_unit = '" _Py_PARSE_INTPTR "'
2435
2436class Py_off_t_converter(CConverter):
2437 type = 'Py_off_t'
2438 converter = 'Py_off_t_converter'
2439
2440class Py_off_t_return_converter(long_return_converter):
2441 type = 'Py_off_t'
2442 conversion_fn = 'PyLong_FromPy_off_t'
2443
2444class path_confname_converter(CConverter):
2445 type="int"
2446 converter="conv_path_confname"
2447
2448class confstr_confname_converter(path_confname_converter):
2449 converter='conv_confstr_confname'
2450
2451class sysconf_confname_converter(path_confname_converter):
2452 converter="conv_sysconf_confname"
2453
2454class sched_param_converter(CConverter):
2455 type = 'struct sched_param'
2456 converter = 'convert_sched_param'
2457 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002458
Larry Hastings61272b72014-01-07 12:41:53 -08002459[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002460/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002461
Larry Hastings61272b72014-01-07 12:41:53 -08002462/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002463
Larry Hastings2a727912014-01-16 11:32:01 -08002464os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002465
2466 path : path_t(allow_fd=True)
2467 Path to be examined; can be string, bytes, or open-file-descriptor int.
2468
2469 *
2470
Larry Hastings2f936352014-08-05 14:04:04 +10002471 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002472 If not None, it should be a file descriptor open to a directory,
2473 and path should be a relative string; path will then be relative to
2474 that directory.
2475
2476 follow_symlinks: bool = True
2477 If False, and the last element of the path is a symbolic link,
2478 stat will examine the symbolic link itself instead of the file
2479 the link points to.
2480
2481Perform a stat system call on the given path.
2482
2483dir_fd and follow_symlinks may not be implemented
2484 on your platform. If they are unavailable, using them will raise a
2485 NotImplementedError.
2486
2487It's an error to use dir_fd or follow_symlinks when specifying path as
2488 an open file descriptor.
2489
Larry Hastings61272b72014-01-07 12:41:53 -08002490[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002491
Larry Hastings31826802013-10-19 00:09:25 -07002492static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002493os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd,
2494 int follow_symlinks)
2495/*[clinic end generated code: output=e4f7569f95d523ca input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002496{
2497 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2498}
2499
Larry Hastings2f936352014-08-05 14:04:04 +10002500
2501/*[clinic input]
2502os.lstat
2503
2504 path : path_t
2505
2506 *
2507
2508 dir_fd : dir_fd(requires='fstatat') = None
2509
2510Perform a stat system call on the given path, without following symbolic links.
2511
2512Like stat(), but do not follow symbolic links.
2513Equivalent to stat(path, follow_symlinks=False).
2514[clinic start generated code]*/
2515
Larry Hastings2f936352014-08-05 14:04:04 +10002516static PyObject *
2517os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002518/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002519{
2520 int follow_symlinks = 0;
2521 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2522}
Larry Hastings31826802013-10-19 00:09:25 -07002523
Larry Hastings2f936352014-08-05 14:04:04 +10002524
Larry Hastings61272b72014-01-07 12:41:53 -08002525/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002526os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002527
2528 path: path_t(allow_fd=True)
2529 Path to be tested; can be string, bytes, or open-file-descriptor int.
2530
2531 mode: int
2532 Operating-system mode bitfield. Can be F_OK to test existence,
2533 or the inclusive-OR of R_OK, W_OK, and X_OK.
2534
2535 *
2536
Larry Hastings2f936352014-08-05 14:04:04 +10002537 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002538 If not None, it should be a file descriptor open to a directory,
2539 and path should be relative; path will then be relative to that
2540 directory.
2541
2542 effective_ids: bool = False
2543 If True, access will use the effective uid/gid instead of
2544 the real uid/gid.
2545
2546 follow_symlinks: bool = True
2547 If False, and the last element of the path is a symbolic link,
2548 access will examine the symbolic link itself instead of the file
2549 the link points to.
2550
2551Use the real uid/gid to test for access to a path.
2552
2553{parameters}
2554dir_fd, effective_ids, and follow_symlinks may not be implemented
2555 on your platform. If they are unavailable, using them will raise a
2556 NotImplementedError.
2557
2558Note that most operations will use the effective uid/gid, therefore this
2559 routine can be used in a suid/sgid environment to test if the invoking user
2560 has the specified access to the path.
2561
Larry Hastings61272b72014-01-07 12:41:53 -08002562[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002563
Larry Hastings2f936352014-08-05 14:04:04 +10002564static int
Larry Hastings89964c42015-04-14 18:07:59 -04002565os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2566 int effective_ids, int follow_symlinks)
2567/*[clinic end generated code: output=abaa53340210088d input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002568{
Larry Hastings2f936352014-08-05 14:04:04 +10002569 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002570
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002571#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002572 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002573#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002574 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002575#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576
Larry Hastings9cf065c2012-06-22 16:30:09 -07002577#ifndef HAVE_FACCESSAT
2578 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002579 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580
2581 if (effective_ids) {
2582 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002583 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 }
2585#endif
2586
2587#ifdef MS_WINDOWS
2588 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002589 if (path->wide != NULL)
2590 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002592 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593 Py_END_ALLOW_THREADS
2594
2595 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002596 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002597 * * we didn't get a -1, and
2598 * * write access wasn't requested,
2599 * * or the file isn't read-only,
2600 * * or it's a directory.
2601 * (Directories cannot be read-only on Windows.)
2602 */
Larry Hastings2f936352014-08-05 14:04:04 +10002603 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002604 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002606 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002607#else
2608
2609 Py_BEGIN_ALLOW_THREADS
2610#ifdef HAVE_FACCESSAT
2611 if ((dir_fd != DEFAULT_DIR_FD) ||
2612 effective_ids ||
2613 !follow_symlinks) {
2614 int flags = 0;
2615 if (!follow_symlinks)
2616 flags |= AT_SYMLINK_NOFOLLOW;
2617 if (effective_ids)
2618 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002619 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620 }
2621 else
2622#endif
Larry Hastings31826802013-10-19 00:09:25 -07002623 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002625 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626#endif
2627
Larry Hastings9cf065c2012-06-22 16:30:09 -07002628 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002629}
2630
Guido van Rossumd371ff11999-01-25 16:12:23 +00002631#ifndef F_OK
2632#define F_OK 0
2633#endif
2634#ifndef R_OK
2635#define R_OK 4
2636#endif
2637#ifndef W_OK
2638#define W_OK 2
2639#endif
2640#ifndef X_OK
2641#define X_OK 1
2642#endif
2643
Larry Hastings31826802013-10-19 00:09:25 -07002644
Guido van Rossumd371ff11999-01-25 16:12:23 +00002645#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002646/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002647os.ttyname -> DecodeFSDefault
2648
2649 fd: int
2650 Integer file descriptor handle.
2651
2652 /
2653
2654Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002655[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002656
Larry Hastings31826802013-10-19 00:09:25 -07002657static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002658os_ttyname_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002659/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002660{
2661 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002662
Larry Hastings31826802013-10-19 00:09:25 -07002663 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002664 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002665 posix_error();
2666 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002667}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002668#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002669
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002670#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002671/*[clinic input]
2672os.ctermid
2673
2674Return the name of the controlling terminal for this process.
2675[clinic start generated code]*/
2676
Larry Hastings2f936352014-08-05 14:04:04 +10002677static PyObject *
2678os_ctermid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002679/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002680{
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 char *ret;
2682 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683
Greg Wardb48bc172000-03-01 21:51:56 +00002684#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002687 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002688#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002689 if (ret == NULL)
2690 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002691 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692}
Larry Hastings2f936352014-08-05 14:04:04 +10002693#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002694
Larry Hastings2f936352014-08-05 14:04:04 +10002695
2696/*[clinic input]
2697os.chdir
2698
2699 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2700
2701Change the current working directory to the specified path.
2702
2703path may always be specified as a string.
2704On some platforms, path may also be specified as an open file descriptor.
2705 If this functionality is unavailable, using it raises an exception.
2706[clinic start generated code]*/
2707
Larry Hastings2f936352014-08-05 14:04:04 +10002708static PyObject *
2709os_chdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002710/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002711{
2712 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002713
2714 Py_BEGIN_ALLOW_THREADS
2715#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002716 if (path->wide)
2717 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002718 else
Larry Hastings2f936352014-08-05 14:04:04 +10002719 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002720 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721#else
2722#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002723 if (path->fd != -1)
2724 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002725 else
2726#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002727 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002728#endif
2729 Py_END_ALLOW_THREADS
2730
2731 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002732 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002733 }
2734
Larry Hastings2f936352014-08-05 14:04:04 +10002735 Py_RETURN_NONE;
2736}
2737
2738
2739#ifdef HAVE_FCHDIR
2740/*[clinic input]
2741os.fchdir
2742
2743 fd: fildes
2744
2745Change to the directory of the given file descriptor.
2746
2747fd must be opened on a directory, not a file.
2748Equivalent to os.chdir(fd).
2749
2750[clinic start generated code]*/
2751
Fred Drake4d1e64b2002-04-15 19:40:07 +00002752static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002753os_fchdir_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002754/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002755{
Larry Hastings2f936352014-08-05 14:04:04 +10002756 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002757}
2758#endif /* HAVE_FCHDIR */
2759
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002760
Larry Hastings2f936352014-08-05 14:04:04 +10002761/*[clinic input]
2762os.chmod
2763
2764 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2765 Path to be modified. May always be specified as a str or bytes.
2766 On some platforms, path may also be specified as an open file descriptor.
2767 If this functionality is unavailable, using it raises an exception.
2768
2769 mode: int
2770 Operating-system mode bitfield.
2771
2772 *
2773
2774 dir_fd : dir_fd(requires='fchmodat') = None
2775 If not None, it should be a file descriptor open to a directory,
2776 and path should be relative; path will then be relative to that
2777 directory.
2778
2779 follow_symlinks: bool = True
2780 If False, and the last element of the path is a symbolic link,
2781 chmod will modify the symbolic link itself instead of the file
2782 the link points to.
2783
2784Change the access permissions of a file.
2785
2786It is an error to use dir_fd or follow_symlinks when specifying path as
2787 an open file descriptor.
2788dir_fd and follow_symlinks may not be implemented on your platform.
2789 If they are unavailable, using them will raise a NotImplementedError.
2790
2791[clinic start generated code]*/
2792
Larry Hastings2f936352014-08-05 14:04:04 +10002793static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002794os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2795 int follow_symlinks)
2796/*[clinic end generated code: output=05e7f73b1a843ba2 input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002797{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002800#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002801 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002803
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804#ifdef HAVE_FCHMODAT
2805 int fchmodat_nofollow_unsupported = 0;
2806#endif
2807
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2809 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002810 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811#endif
2812
2813#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002815 if (path->wide)
2816 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002817 else
Larry Hastings2f936352014-08-05 14:04:04 +10002818 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002819 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002820 result = 0;
2821 else {
2822 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002823 attr &= ~FILE_ATTRIBUTE_READONLY;
2824 else
2825 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002826 if (path->wide)
2827 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828 else
Larry Hastings2f936352014-08-05 14:04:04 +10002829 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002830 }
2831 Py_END_ALLOW_THREADS
2832
2833 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002834 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 }
2836#else /* MS_WINDOWS */
2837 Py_BEGIN_ALLOW_THREADS
2838#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002839 if (path->fd != -1)
2840 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002841 else
2842#endif
2843#ifdef HAVE_LCHMOD
2844 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002845 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002846 else
2847#endif
2848#ifdef HAVE_FCHMODAT
2849 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2850 /*
2851 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2852 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002853 * and then says it isn't implemented yet.
2854 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 *
2856 * Once it is supported, os.chmod will automatically
2857 * support dir_fd and follow_symlinks=False. (Hopefully.)
2858 * Until then, we need to be careful what exception we raise.
2859 */
Larry Hastings2f936352014-08-05 14:04:04 +10002860 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002861 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2862 /*
2863 * But wait! We can't throw the exception without allowing threads,
2864 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2865 */
2866 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002867 result &&
2868 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2869 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002870 }
2871 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002872#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002873 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002874 Py_END_ALLOW_THREADS
2875
2876 if (result) {
2877#ifdef HAVE_FCHMODAT
2878 if (fchmodat_nofollow_unsupported) {
2879 if (dir_fd != DEFAULT_DIR_FD)
2880 dir_fd_and_follow_symlinks_invalid("chmod",
2881 dir_fd, follow_symlinks);
2882 else
2883 follow_symlinks_specified("chmod", follow_symlinks);
2884 }
2885 else
2886#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002887 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888 }
2889#endif
2890
Larry Hastings2f936352014-08-05 14:04:04 +10002891 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002892}
2893
Larry Hastings9cf065c2012-06-22 16:30:09 -07002894
Christian Heimes4e30a842007-11-30 22:12:06 +00002895#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002896/*[clinic input]
2897os.fchmod
2898
2899 fd: int
2900 mode: int
2901
2902Change the access permissions of the file given by file descriptor fd.
2903
2904Equivalent to os.chmod(fd, mode).
2905[clinic start generated code]*/
2906
Larry Hastings2f936352014-08-05 14:04:04 +10002907static PyObject *
2908os_fchmod_impl(PyModuleDef *module, int fd, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002909/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002910{
2911 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002912 int async_err = 0;
2913
2914 do {
2915 Py_BEGIN_ALLOW_THREADS
2916 res = fchmod(fd, mode);
2917 Py_END_ALLOW_THREADS
2918 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2919 if (res != 0)
2920 return (!async_err) ? posix_error() : NULL;
2921
Victor Stinner8c62be82010-05-06 00:08:46 +00002922 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002923}
2924#endif /* HAVE_FCHMOD */
2925
Larry Hastings2f936352014-08-05 14:04:04 +10002926
Christian Heimes4e30a842007-11-30 22:12:06 +00002927#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002928/*[clinic input]
2929os.lchmod
2930
2931 path: path_t
2932 mode: int
2933
2934Change the access permissions of a file, without following symbolic links.
2935
2936If path is a symlink, this affects the link itself rather than the target.
2937Equivalent to chmod(path, mode, follow_symlinks=False)."
2938[clinic start generated code]*/
2939
Larry Hastings2f936352014-08-05 14:04:04 +10002940static PyObject *
2941os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002942/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002943{
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002945 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002946 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002947 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002948 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002949 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002950 return NULL;
2951 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002952 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002953}
2954#endif /* HAVE_LCHMOD */
2955
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002956
Thomas Wouterscf297e42007-02-23 15:07:44 +00002957#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002958/*[clinic input]
2959os.chflags
2960
2961 path: path_t
2962 flags: unsigned_long(bitwise=True)
2963 follow_symlinks: bool=True
2964
2965Set file flags.
2966
2967If follow_symlinks is False, and the last element of the path is a symbolic
2968 link, chflags will change flags on the symbolic link itself instead of the
2969 file the link points to.
2970follow_symlinks may not be implemented on your platform. If it is
2971unavailable, using it will raise a NotImplementedError.
2972
2973[clinic start generated code]*/
2974
Larry Hastings2f936352014-08-05 14:04:04 +10002975static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002976os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags,
2977 int follow_symlinks)
2978/*[clinic end generated code: output=ff2d6e73534a95b9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002979{
2980 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002981
2982#ifndef HAVE_LCHFLAGS
2983 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002984 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985#endif
2986
Victor Stinner8c62be82010-05-06 00:08:46 +00002987 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002988#ifdef HAVE_LCHFLAGS
2989 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002990 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002991 else
2992#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002993 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002994 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002995
Larry Hastings2f936352014-08-05 14:04:04 +10002996 if (result)
2997 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002998
Larry Hastings2f936352014-08-05 14:04:04 +10002999 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000}
3001#endif /* HAVE_CHFLAGS */
3002
Larry Hastings2f936352014-08-05 14:04:04 +10003003
Thomas Wouterscf297e42007-02-23 15:07:44 +00003004#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003005/*[clinic input]
3006os.lchflags
3007
3008 path: path_t
3009 flags: unsigned_long(bitwise=True)
3010
3011Set file flags.
3012
3013This function will not follow symbolic links.
3014Equivalent to chflags(path, flags, follow_symlinks=False).
3015[clinic start generated code]*/
3016
Larry Hastings2f936352014-08-05 14:04:04 +10003017static PyObject *
3018os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003019/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003020{
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003022 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003023 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003024 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003025 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003026 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003027 }
Victor Stinner292c8352012-10-30 02:17:38 +01003028 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003029}
3030#endif /* HAVE_LCHFLAGS */
3031
Larry Hastings2f936352014-08-05 14:04:04 +10003032
Martin v. Löwis244edc82001-10-04 22:44:26 +00003033#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003034/*[clinic input]
3035os.chroot
3036 path: path_t
3037
3038Change root directory to path.
3039
3040[clinic start generated code]*/
3041
Larry Hastings2f936352014-08-05 14:04:04 +10003042static PyObject *
3043os_chroot_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003044/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003045{
3046 int res;
3047 Py_BEGIN_ALLOW_THREADS
3048 res = chroot(path->narrow);
3049 Py_END_ALLOW_THREADS
3050 if (res < 0)
3051 return path_error(path);
3052 Py_RETURN_NONE;
3053}
3054#endif /* HAVE_CHROOT */
3055
Martin v. Löwis244edc82001-10-04 22:44:26 +00003056
Guido van Rossum21142a01999-01-08 21:05:37 +00003057#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003058/*[clinic input]
3059os.fsync
3060
3061 fd: fildes
3062
3063Force write of fd to disk.
3064[clinic start generated code]*/
3065
Larry Hastings2f936352014-08-05 14:04:04 +10003066static PyObject *
3067os_fsync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003068/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003069{
3070 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003071}
3072#endif /* HAVE_FSYNC */
3073
Larry Hastings2f936352014-08-05 14:04:04 +10003074
Ross Lagerwall7807c352011-03-17 20:20:30 +02003075#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003076/*[clinic input]
3077os.sync
3078
3079Force write of everything to disk.
3080[clinic start generated code]*/
3081
Larry Hastings2f936352014-08-05 14:04:04 +10003082static PyObject *
3083os_sync_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003084/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003085{
3086 Py_BEGIN_ALLOW_THREADS
3087 sync();
3088 Py_END_ALLOW_THREADS
3089 Py_RETURN_NONE;
3090}
Larry Hastings2f936352014-08-05 14:04:04 +10003091#endif /* HAVE_SYNC */
3092
Ross Lagerwall7807c352011-03-17 20:20:30 +02003093
Guido van Rossum21142a01999-01-08 21:05:37 +00003094#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003095#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003096extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3097#endif
3098
Larry Hastings2f936352014-08-05 14:04:04 +10003099/*[clinic input]
3100os.fdatasync
3101
3102 fd: fildes
3103
3104Force write of fd to disk without forcing update of metadata.
3105[clinic start generated code]*/
3106
Larry Hastings2f936352014-08-05 14:04:04 +10003107static PyObject *
3108os_fdatasync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003109/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003110{
3111 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003112}
3113#endif /* HAVE_FDATASYNC */
3114
3115
Fredrik Lundh10723342000-07-10 16:38:09 +00003116#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003117/*[clinic input]
3118os.chown
3119
3120 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3121 Path to be examined; can be string, bytes, or open-file-descriptor int.
3122
3123 uid: uid_t
3124
3125 gid: gid_t
3126
3127 *
3128
3129 dir_fd : dir_fd(requires='fchownat') = None
3130 If not None, it should be a file descriptor open to a directory,
3131 and path should be relative; path will then be relative to that
3132 directory.
3133
3134 follow_symlinks: bool = True
3135 If False, and the last element of the path is a symbolic link,
3136 stat will examine the symbolic link itself instead of the file
3137 the link points to.
3138
3139Change the owner and group id of path to the numeric uid and gid.\
3140
3141path may always be specified as a string.
3142On some platforms, path may also be specified as an open file descriptor.
3143 If this functionality is unavailable, using it raises an exception.
3144If dir_fd is not None, it should be a file descriptor open to a directory,
3145 and path should be relative; path will then be relative to that directory.
3146If follow_symlinks is False, and the last element of the path is a symbolic
3147 link, chown will modify the symbolic link itself instead of the file the
3148 link points to.
3149It is an error to use dir_fd or follow_symlinks when specifying path as
3150 an open file descriptor.
3151dir_fd and follow_symlinks may not be implemented on your platform.
3152 If they are unavailable, using them will raise a NotImplementedError.
3153
3154[clinic start generated code]*/
3155
Larry Hastings2f936352014-08-05 14:04:04 +10003156static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003157os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid,
3158 int dir_fd, int follow_symlinks)
3159/*[clinic end generated code: output=e0a4559f394dbd91 input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003160{
3161 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162
3163#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3164 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003165 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003167 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3168 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3169 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003170
3171#ifdef __APPLE__
3172 /*
3173 * This is for Mac OS X 10.3, which doesn't have lchown.
3174 * (But we still have an lchown symbol because of weak-linking.)
3175 * It doesn't have fchownat either. So there's no possibility
3176 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003177 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003178 if ((!follow_symlinks) && (lchown == NULL)) {
3179 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003180 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181 }
3182#endif
3183
Victor Stinner8c62be82010-05-06 00:08:46 +00003184 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003185#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003186 if (path->fd != -1)
3187 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003188 else
3189#endif
3190#ifdef HAVE_LCHOWN
3191 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003192 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003193 else
3194#endif
3195#ifdef HAVE_FCHOWNAT
3196 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003197 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003198 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3199 else
3200#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003201 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003202 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003203
Larry Hastings2f936352014-08-05 14:04:04 +10003204 if (result)
3205 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003206
Larry Hastings2f936352014-08-05 14:04:04 +10003207 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003208}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003209#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003210
Larry Hastings2f936352014-08-05 14:04:04 +10003211
Christian Heimes4e30a842007-11-30 22:12:06 +00003212#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003213/*[clinic input]
3214os.fchown
3215
3216 fd: int
3217 uid: uid_t
3218 gid: gid_t
3219
3220Change the owner and group id of the file specified by file descriptor.
3221
3222Equivalent to os.chown(fd, uid, gid).
3223
3224[clinic start generated code]*/
3225
Larry Hastings2f936352014-08-05 14:04:04 +10003226static PyObject *
3227os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003228/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003229{
Victor Stinner8c62be82010-05-06 00:08:46 +00003230 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003231 int async_err = 0;
3232
3233 do {
3234 Py_BEGIN_ALLOW_THREADS
3235 res = fchown(fd, uid, gid);
3236 Py_END_ALLOW_THREADS
3237 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3238 if (res != 0)
3239 return (!async_err) ? posix_error() : NULL;
3240
Victor Stinner8c62be82010-05-06 00:08:46 +00003241 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003242}
3243#endif /* HAVE_FCHOWN */
3244
Larry Hastings2f936352014-08-05 14:04:04 +10003245
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003246#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003247/*[clinic input]
3248os.lchown
3249
3250 path : path_t
3251 uid: uid_t
3252 gid: gid_t
3253
3254Change the owner and group id of path to the numeric uid and gid.
3255
3256This function will not follow symbolic links.
3257Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3258[clinic start generated code]*/
3259
Larry Hastings2f936352014-08-05 14:04:04 +10003260static PyObject *
3261os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003262/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003263{
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003265 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003266 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003267 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003268 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003269 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003270 }
Larry Hastings2f936352014-08-05 14:04:04 +10003271 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003272}
3273#endif /* HAVE_LCHOWN */
3274
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003275
Barry Warsaw53699e91996-12-10 23:23:01 +00003276static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003277posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003278{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003279 char *buf, *tmpbuf;
3280 char *cwd;
3281 const size_t chunk = 1024;
3282 size_t buflen = 0;
3283 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003284
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003285#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003287 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 wchar_t *wbuf2 = wbuf;
3289 PyObject *resobj;
3290 DWORD len;
3291 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003292 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003293 /* If the buffer is large enough, len does not include the
3294 terminating \0. If the buffer is too small, len includes
3295 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003296 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003297 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003298 if (wbuf2)
3299 len = GetCurrentDirectoryW(len, wbuf2);
3300 }
3301 Py_END_ALLOW_THREADS
3302 if (!wbuf2) {
3303 PyErr_NoMemory();
3304 return NULL;
3305 }
3306 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003307 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003308 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003309 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 }
3311 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003312 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003313 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003314 return resobj;
3315 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003316
3317 if (win32_warn_bytes_api())
3318 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003319#endif
3320
Victor Stinner4403d7d2015-04-25 00:16:10 +02003321 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003322 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003323 do {
3324 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003325#ifdef MS_WINDOWS
3326 if (buflen > INT_MAX) {
3327 PyErr_NoMemory();
3328 break;
3329 }
3330#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003331 tmpbuf = PyMem_RawRealloc(buf, buflen);
3332 if (tmpbuf == NULL)
3333 break;
3334
3335 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003336#ifdef MS_WINDOWS
3337 cwd = getcwd(buf, (int)buflen);
3338#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003339 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003340#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003341 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003342 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003343
3344 if (cwd == NULL) {
3345 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003346 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003347 }
3348
Victor Stinner8c62be82010-05-06 00:08:46 +00003349 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003350 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3351 else
3352 obj = PyUnicode_DecodeFSDefault(buf);
3353 PyMem_RawFree(buf);
3354
3355 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003356}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003357
Larry Hastings2f936352014-08-05 14:04:04 +10003358
3359/*[clinic input]
3360os.getcwd
3361
3362Return a unicode string representing the current working directory.
3363[clinic start generated code]*/
3364
Larry Hastings2f936352014-08-05 14:04:04 +10003365static PyObject *
3366os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003367/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003368{
3369 return posix_getcwd(0);
3370}
3371
Larry Hastings2f936352014-08-05 14:04:04 +10003372
3373/*[clinic input]
3374os.getcwdb
3375
3376Return a bytes string representing the current working directory.
3377[clinic start generated code]*/
3378
Larry Hastings2f936352014-08-05 14:04:04 +10003379static PyObject *
3380os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003381/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003382{
3383 return posix_getcwd(1);
3384}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003385
Larry Hastings2f936352014-08-05 14:04:04 +10003386
Larry Hastings9cf065c2012-06-22 16:30:09 -07003387#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3388#define HAVE_LINK 1
3389#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003390
Guido van Rossumb6775db1994-08-01 11:34:53 +00003391#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003392/*[clinic input]
3393
3394os.link
3395
3396 src : path_t
3397 dst : path_t
3398 *
3399 src_dir_fd : dir_fd = None
3400 dst_dir_fd : dir_fd = None
3401 follow_symlinks: bool = True
3402
3403Create a hard link to a file.
3404
3405If either src_dir_fd or dst_dir_fd is not None, it should be a file
3406 descriptor open to a directory, and the respective path string (src or dst)
3407 should be relative; the path will then be relative to that directory.
3408If follow_symlinks is False, and the last element of src is a symbolic
3409 link, link will create a link to the symbolic link itself instead of the
3410 file the link points to.
3411src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3412 platform. If they are unavailable, using them will raise a
3413 NotImplementedError.
3414[clinic start generated code]*/
3415
Larry Hastings2f936352014-08-05 14:04:04 +10003416static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003417os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
3418 int dst_dir_fd, int follow_symlinks)
3419/*[clinic end generated code: output=f47a7e88f7b391b6 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003420{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421#ifdef MS_WINDOWS
3422 BOOL result;
3423#else
3424 int result;
3425#endif
3426
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427#ifndef HAVE_LINKAT
3428 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3429 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003430 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431 }
3432#endif
3433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435 PyErr_SetString(PyExc_NotImplementedError,
3436 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003437 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003439
Brian Curtin1b9df392010-11-24 20:24:31 +00003440#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003442 if (src->wide)
3443 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 else
Larry Hastings2f936352014-08-05 14:04:04 +10003445 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003447
Larry Hastings2f936352014-08-05 14:04:04 +10003448 if (!result)
3449 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450#else
3451 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003452#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3454 (dst_dir_fd != DEFAULT_DIR_FD) ||
3455 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003456 result = linkat(src_dir_fd, src->narrow,
3457 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3459 else
3460#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003461 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003463
Larry Hastings2f936352014-08-05 14:04:04 +10003464 if (result)
3465 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466#endif
3467
Larry Hastings2f936352014-08-05 14:04:04 +10003468 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003469}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470#endif
3471
Brian Curtin1b9df392010-11-24 20:24:31 +00003472
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003473#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003474static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003475_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003476{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003477 PyObject *v;
3478 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3479 BOOL result;
3480 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003481 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003483 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485
Gregory P. Smith40a21602013-03-20 20:52:50 -07003486 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 WIN32_FIND_DATAW wFileData;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003488 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003489
Gregory P. Smith40a21602013-03-20 20:52:50 -07003490 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003491 po_wchars = L".";
3492 len = 1;
3493 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003494 po_wchars = path->wide;
3495 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003496 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003497 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003498 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 if (!wnamebuf) {
3500 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003503 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003505 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003506 if (wch != SEP && wch != ALTSEP && wch != L':')
3507 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 wcscpy(wnamebuf + len, L"*.*");
3509 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 if ((list = PyList_New(0)) == NULL) {
3511 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003513 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003515 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 if (hFindFile == INVALID_HANDLE_VALUE) {
3517 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 if (error == ERROR_FILE_NOT_FOUND)
3519 goto exit;
3520 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003521 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003522 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003523 }
3524 do {
3525 /* Skip over . and .. */
3526 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3527 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003528 v = PyUnicode_FromWideChar(wFileData.cFileName,
3529 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003530 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003531 Py_DECREF(list);
3532 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 break;
3534 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003536 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
3538 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 break;
3540 }
3541 Py_DECREF(v);
3542 }
3543 Py_BEGIN_ALLOW_THREADS
3544 result = FindNextFileW(hFindFile, &wFileData);
3545 Py_END_ALLOW_THREADS
3546 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3547 it got to the end of the directory. */
3548 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003550 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003551 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003552 }
3553 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003554
Larry Hastings9cf065c2012-06-22 16:30:09 -07003555 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003557 strcpy(namebuf, path->narrow);
3558 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 if (len > 0) {
3560 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003561 if (ch != '\\' && ch != '/' && ch != ':')
3562 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003563 strcpy(namebuf + len, "*.*");
3564 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003565
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003568
Antoine Pitroub73caab2010-08-09 23:39:31 +00003569 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003571 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 if (hFindFile == INVALID_HANDLE_VALUE) {
3573 int error = GetLastError();
3574 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 goto exit;
3576 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003577 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 }
3580 do {
3581 /* Skip over . and .. */
3582 if (strcmp(FileData.cFileName, ".") != 0 &&
3583 strcmp(FileData.cFileName, "..") != 0) {
3584 v = PyBytes_FromString(FileData.cFileName);
3585 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003586 Py_DECREF(list);
3587 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 break;
3589 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003591 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
3593 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003594 break;
3595 }
3596 Py_DECREF(v);
3597 }
3598 Py_BEGIN_ALLOW_THREADS
3599 result = FindNextFile(hFindFile, &FileData);
3600 Py_END_ALLOW_THREADS
3601 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3602 it got to the end of the directory. */
3603 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003605 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003606 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003607 }
3608 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003609
Larry Hastings9cf065c2012-06-22 16:30:09 -07003610exit:
3611 if (hFindFile != INVALID_HANDLE_VALUE) {
3612 if (FindClose(hFindFile) == FALSE) {
3613 if (list != NULL) {
3614 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003615 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003616 }
3617 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003619 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003620
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003622} /* end of _listdir_windows_no_opendir */
3623
3624#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3625
3626static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003627_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003628{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003629 PyObject *v;
3630 DIR *dirp = NULL;
3631 struct dirent *ep;
3632 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003633#ifdef HAVE_FDOPENDIR
3634 int fd = -1;
3635#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003636
Victor Stinner8c62be82010-05-06 00:08:46 +00003637 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003639 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003640 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003641 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003642 if (fd == -1)
3643 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003644
Larry Hastingsfdaea062012-06-25 04:42:23 -07003645 return_str = 1;
3646
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 Py_BEGIN_ALLOW_THREADS
3648 dirp = fdopendir(fd);
3649 Py_END_ALLOW_THREADS
3650 }
3651 else
3652#endif
3653 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003654 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003655 if (path->narrow) {
3656 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003657 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003658 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003659 }
3660 else {
3661 name = ".";
3662 return_str = 1;
3663 }
3664
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665 Py_BEGIN_ALLOW_THREADS
3666 dirp = opendir(name);
3667 Py_END_ALLOW_THREADS
3668 }
3669
3670 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003671 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003672#ifdef HAVE_FDOPENDIR
3673 if (fd != -1) {
3674 Py_BEGIN_ALLOW_THREADS
3675 close(fd);
3676 Py_END_ALLOW_THREADS
3677 }
3678#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 goto exit;
3680 }
3681 if ((list = PyList_New(0)) == NULL) {
3682 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003683 }
3684 for (;;) {
3685 errno = 0;
3686 Py_BEGIN_ALLOW_THREADS
3687 ep = readdir(dirp);
3688 Py_END_ALLOW_THREADS
3689 if (ep == NULL) {
3690 if (errno == 0) {
3691 break;
3692 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003694 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 }
3697 }
3698 if (ep->d_name[0] == '.' &&
3699 (NAMLEN(ep) == 1 ||
3700 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3701 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003702 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003703 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3704 else
3705 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003707 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003708 break;
3709 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003713 break;
3714 }
3715 Py_DECREF(v);
3716 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003717
Larry Hastings9cf065c2012-06-22 16:30:09 -07003718exit:
3719 if (dirp != NULL) {
3720 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003721#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003722 if (fd > -1)
3723 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003724#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003725 closedir(dirp);
3726 Py_END_ALLOW_THREADS
3727 }
3728
Larry Hastings9cf065c2012-06-22 16:30:09 -07003729 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003730} /* end of _posix_listdir */
3731#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003732
Larry Hastings2f936352014-08-05 14:04:04 +10003733
3734/*[clinic input]
3735os.listdir
3736
3737 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3738
3739Return a list containing the names of the files in the directory.
3740
3741path can be specified as either str or bytes. If path is bytes,
3742 the filenames returned will also be bytes; in all other circumstances
3743 the filenames returned will be str.
3744If path is None, uses the path='.'.
3745On some platforms, path may also be specified as an open file descriptor;\
3746 the file descriptor must refer to a directory.
3747 If this functionality is unavailable, using it raises NotImplementedError.
3748
3749The list is in arbitrary order. It does not include the special
3750entries '.' and '..' even if they are present in the directory.
3751
3752
3753[clinic start generated code]*/
3754
Larry Hastings2f936352014-08-05 14:04:04 +10003755static PyObject *
3756os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003757/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003758{
3759#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3760 return _listdir_windows_no_opendir(path, NULL);
3761#else
3762 return _posix_listdir(path, NULL);
3763#endif
3764}
3765
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003766#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003767/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003768/*[clinic input]
3769os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003770
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003771 path: path_t
3772 /
3773
3774[clinic start generated code]*/
3775
3776static PyObject *
3777os__getfullpathname_impl(PyModuleDef *module, path_t *path)
3778/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/
3779{
3780 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003781 {
Victor Stinner75875072013-11-24 19:23:25 +01003782 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003783 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 DWORD result;
3785 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003786
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003788 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003789 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003790 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003791 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003792 if (!woutbufp)
3793 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003794 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 }
3796 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003797 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003798 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003799 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003801 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 return v;
3803 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003804 else {
3805 char outbuf[MAX_PATH];
3806 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003807
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003808 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3809 outbuf, &temp)) {
3810 win32_error_object("GetFullPathName", path->object);
3811 return NULL;
3812 }
3813 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003814 }
Larry Hastings2f936352014-08-05 14:04:04 +10003815}
Brian Curtind40e6f72010-07-08 21:39:08 +00003816
Brian Curtind25aef52011-06-13 15:16:04 -05003817
Larry Hastings2f936352014-08-05 14:04:04 +10003818/*[clinic input]
3819os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003820
Larry Hastings2f936352014-08-05 14:04:04 +10003821 path: unicode
3822 /
3823
3824A helper function for samepath on windows.
3825[clinic start generated code]*/
3826
Larry Hastings2f936352014-08-05 14:04:04 +10003827static PyObject *
3828os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003829/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003830{
3831 HANDLE hFile;
3832 int buf_size;
3833 wchar_t *target_path;
3834 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003835 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003836 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003837
Larry Hastings2f936352014-08-05 14:04:04 +10003838 path_wchar = PyUnicode_AsUnicode(path);
3839 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003840 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003841
Brian Curtind40e6f72010-07-08 21:39:08 +00003842 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003843 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003844 0, /* desired access */
3845 0, /* share mode */
3846 NULL, /* security attributes */
3847 OPEN_EXISTING,
3848 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3849 FILE_FLAG_BACKUP_SEMANTICS,
3850 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003851
Victor Stinnereb5657a2011-09-30 01:44:27 +02003852 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003853 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003854
3855 /* We have a good handle to the target, use it to determine the
3856 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003857 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003858
3859 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003860 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003861
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003862 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003863 if(!target_path)
3864 return PyErr_NoMemory();
3865
Steve Dower2ea51c92015-03-20 21:49:12 -07003866 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3867 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003868 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003869 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003870
3871 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003872 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003873
3874 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003875 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003876 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003877 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003878}
Brian Curtin62857742010-09-06 17:07:27 +00003879
Brian Curtin95d028f2011-06-09 09:10:38 -05003880PyDoc_STRVAR(posix__isdir__doc__,
3881"Return true if the pathname refers to an existing directory.");
3882
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003883/*[clinic input]
3884os._isdir
3885
3886 path: path_t
3887 /
3888
3889[clinic start generated code]*/
3890
Brian Curtin9c669cc2011-06-08 18:17:18 -05003891static PyObject *
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003892os__isdir_impl(PyModuleDef *module, path_t *path)
3893/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003894{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003895 DWORD attributes;
3896
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003897 if (!path->narrow)
3898 attributes = GetFileAttributesW(path->wide);
3899 else
3900 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003901
Brian Curtin9c669cc2011-06-08 18:17:18 -05003902 if (attributes == INVALID_FILE_ATTRIBUTES)
3903 Py_RETURN_FALSE;
3904
Brian Curtin9c669cc2011-06-08 18:17:18 -05003905 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3906 Py_RETURN_TRUE;
3907 else
3908 Py_RETURN_FALSE;
3909}
Tim Golden6b528062013-08-01 12:44:00 +01003910
Tim Golden6b528062013-08-01 12:44:00 +01003911
Larry Hastings2f936352014-08-05 14:04:04 +10003912/*[clinic input]
3913os._getvolumepathname
3914
3915 path: unicode
3916
3917A helper function for ismount on Win32.
3918[clinic start generated code]*/
3919
Larry Hastings2f936352014-08-05 14:04:04 +10003920static PyObject *
3921os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003922/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003923{
3924 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003925 const wchar_t *path_wchar;
3926 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003927 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003928 BOOL ret;
3929
Larry Hastings2f936352014-08-05 14:04:04 +10003930 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3931 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003932 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003933 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003934
3935 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003936 buflen = Py_MAX(buflen, MAX_PATH);
3937
3938 if (buflen > DWORD_MAX) {
3939 PyErr_SetString(PyExc_OverflowError, "path too long");
3940 return NULL;
3941 }
3942
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003943 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003944 if (mountpath == NULL)
3945 return PyErr_NoMemory();
3946
3947 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003948 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003949 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003950 Py_END_ALLOW_THREADS
3951
3952 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003953 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003954 goto exit;
3955 }
3956 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3957
3958exit:
3959 PyMem_Free(mountpath);
3960 return result;
3961}
Tim Golden6b528062013-08-01 12:44:00 +01003962
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003963#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003964
Larry Hastings2f936352014-08-05 14:04:04 +10003965
3966/*[clinic input]
3967os.mkdir
3968
3969 path : path_t
3970
3971 mode: int = 0o777
3972
3973 *
3974
3975 dir_fd : dir_fd(requires='mkdirat') = None
3976
3977# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3978
3979Create a directory.
3980
3981If dir_fd is not None, it should be a file descriptor open to a directory,
3982 and path should be relative; path will then be relative to that directory.
3983dir_fd may not be implemented on your platform.
3984 If it is unavailable, using it will raise a NotImplementedError.
3985
3986The mode argument is ignored on Windows.
3987[clinic start generated code]*/
3988
Larry Hastings2f936352014-08-05 14:04:04 +10003989static PyObject *
3990os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003991/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003992{
3993 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003994
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003995#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003996 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003997 if (path->wide)
3998 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 else
Larry Hastings2f936352014-08-05 14:04:04 +10004000 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004001 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004002
Larry Hastings2f936352014-08-05 14:04:04 +10004003 if (!result)
4004 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004005#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007#if HAVE_MKDIRAT
4008 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004009 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004010 else
4011#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004012#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004013 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004014#else
Larry Hastings2f936352014-08-05 14:04:04 +10004015 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004016#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004017 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004018 if (result < 0)
4019 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004020#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004021 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004022}
4023
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004024
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004025/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4026#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004027#include <sys/resource.h>
4028#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004029
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004030
4031#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004032/*[clinic input]
4033os.nice
4034
4035 increment: int
4036 /
4037
4038Add increment to the priority of process and return the new priority.
4039[clinic start generated code]*/
4040
Larry Hastings2f936352014-08-05 14:04:04 +10004041static PyObject *
4042os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004043/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004044{
4045 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004046
Victor Stinner8c62be82010-05-06 00:08:46 +00004047 /* There are two flavours of 'nice': one that returns the new
4048 priority (as required by almost all standards out there) and the
4049 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4050 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004051
Victor Stinner8c62be82010-05-06 00:08:46 +00004052 If we are of the nice family that returns the new priority, we
4053 need to clear errno before the call, and check if errno is filled
4054 before calling posix_error() on a returnvalue of -1, because the
4055 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004056
Victor Stinner8c62be82010-05-06 00:08:46 +00004057 errno = 0;
4058 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004059#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 if (value == 0)
4061 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004062#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004063 if (value == -1 && errno != 0)
4064 /* either nice() or getpriority() returned an error */
4065 return posix_error();
4066 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004067}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004068#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004069
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004070
4071#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004072/*[clinic input]
4073os.getpriority
4074
4075 which: int
4076 who: int
4077
4078Return program scheduling priority.
4079[clinic start generated code]*/
4080
Larry Hastings2f936352014-08-05 14:04:04 +10004081static PyObject *
4082os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004083/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004084{
4085 int retval;
4086
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004087 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004088 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004089 if (errno != 0)
4090 return posix_error();
4091 return PyLong_FromLong((long)retval);
4092}
4093#endif /* HAVE_GETPRIORITY */
4094
4095
4096#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004097/*[clinic input]
4098os.setpriority
4099
4100 which: int
4101 who: int
4102 priority: int
4103
4104Set program scheduling priority.
4105[clinic start generated code]*/
4106
Larry Hastings2f936352014-08-05 14:04:04 +10004107static PyObject *
4108os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004109/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004110{
4111 int retval;
4112
4113 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004114 if (retval == -1)
4115 return posix_error();
4116 Py_RETURN_NONE;
4117}
4118#endif /* HAVE_SETPRIORITY */
4119
4120
Barry Warsaw53699e91996-12-10 23:23:01 +00004121static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004122internal_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 +00004123{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004124 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004127#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004128 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004129 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004130#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004132#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4135 (dst_dir_fd != DEFAULT_DIR_FD);
4136#ifndef HAVE_RENAMEAT
4137 if (dir_fd_specified) {
4138 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004139 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140 }
4141#endif
4142
Larry Hastings2f936352014-08-05 14:04:04 +10004143 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144 PyErr_Format(PyExc_ValueError,
4145 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004146 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 }
4148
4149#ifdef MS_WINDOWS
4150 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004151 if (src->wide)
4152 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004153 else
Larry Hastings2f936352014-08-05 14:04:04 +10004154 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 Py_END_ALLOW_THREADS
4156
Larry Hastings2f936352014-08-05 14:04:04 +10004157 if (!result)
4158 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004159
4160#else
4161 Py_BEGIN_ALLOW_THREADS
4162#ifdef HAVE_RENAMEAT
4163 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004164 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004165 else
4166#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004167 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004168 Py_END_ALLOW_THREADS
4169
Larry Hastings2f936352014-08-05 14:04:04 +10004170 if (result)
4171 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004173 Py_RETURN_NONE;
4174}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004175
Larry Hastings2f936352014-08-05 14:04:04 +10004176
4177/*[clinic input]
4178os.rename
4179
4180 src : path_t
4181 dst : path_t
4182 *
4183 src_dir_fd : dir_fd = None
4184 dst_dir_fd : dir_fd = None
4185
4186Rename a file or directory.
4187
4188If either src_dir_fd or dst_dir_fd is not None, it should be a file
4189 descriptor open to a directory, and the respective path string (src or dst)
4190 should be relative; the path will then be relative to that directory.
4191src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4192 If they are unavailable, using them will raise a NotImplementedError.
4193[clinic start generated code]*/
4194
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004195static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004196os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
4197 int dst_dir_fd)
4198/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004199{
Larry Hastings2f936352014-08-05 14:04:04 +10004200 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004201}
4202
Larry Hastings2f936352014-08-05 14:04:04 +10004203
4204/*[clinic input]
4205os.replace = os.rename
4206
4207Rename a file or directory, overwriting the destination.
4208
4209If either src_dir_fd or dst_dir_fd is not None, it should be a file
4210 descriptor open to a directory, and the respective path string (src or dst)
4211 should be relative; the path will then be relative to that directory.
4212src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4213 If they are unavailable, using them will raise a NotImplementedError."
4214[clinic start generated code]*/
4215
Larry Hastings2f936352014-08-05 14:04:04 +10004216static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004217os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst,
4218 int src_dir_fd, int dst_dir_fd)
4219/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004220{
4221 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4222}
4223
4224
4225/*[clinic input]
4226os.rmdir
4227
4228 path: path_t
4229 *
4230 dir_fd: dir_fd(requires='unlinkat') = None
4231
4232Remove a directory.
4233
4234If dir_fd is not None, it should be a file descriptor open to a directory,
4235 and path should be relative; path will then be relative to that directory.
4236dir_fd may not be implemented on your platform.
4237 If it is unavailable, using it will raise a NotImplementedError.
4238[clinic start generated code]*/
4239
Larry Hastings2f936352014-08-05 14:04:04 +10004240static PyObject *
4241os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004242/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004243{
4244 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004245
4246 Py_BEGIN_ALLOW_THREADS
4247#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004248 if (path->wide)
4249 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004250 else
Larry Hastings2f936352014-08-05 14:04:04 +10004251 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252 result = !result; /* Windows, success=1, UNIX, success=0 */
4253#else
4254#ifdef HAVE_UNLINKAT
4255 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004256 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004257 else
4258#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004259 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004260#endif
4261 Py_END_ALLOW_THREADS
4262
Larry Hastings2f936352014-08-05 14:04:04 +10004263 if (result)
4264 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004265
Larry Hastings2f936352014-08-05 14:04:04 +10004266 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004267}
4268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004269
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004270#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004271#ifdef MS_WINDOWS
4272/*[clinic input]
4273os.system -> long
4274
4275 command: Py_UNICODE
4276
4277Execute the command in a subshell.
4278[clinic start generated code]*/
4279
Larry Hastings2f936352014-08-05 14:04:04 +10004280static long
4281os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004282/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004283{
4284 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004285 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004286 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004287 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004288 return result;
4289}
4290#else /* MS_WINDOWS */
4291/*[clinic input]
4292os.system -> long
4293
4294 command: FSConverter
4295
4296Execute the command in a subshell.
4297[clinic start generated code]*/
4298
Larry Hastings2f936352014-08-05 14:04:04 +10004299static long
4300os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004301/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004302{
4303 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004304 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004305 Py_BEGIN_ALLOW_THREADS
4306 result = system(bytes);
4307 Py_END_ALLOW_THREADS
4308 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004309}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004310#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004311#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004312
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004313
Larry Hastings2f936352014-08-05 14:04:04 +10004314/*[clinic input]
4315os.umask
4316
4317 mask: int
4318 /
4319
4320Set the current numeric umask and return the previous umask.
4321[clinic start generated code]*/
4322
Larry Hastings2f936352014-08-05 14:04:04 +10004323static PyObject *
4324os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004325/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004326{
4327 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004328 if (i < 0)
4329 return posix_error();
4330 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004331}
4332
Brian Curtind40e6f72010-07-08 21:39:08 +00004333#ifdef MS_WINDOWS
4334
4335/* override the default DeleteFileW behavior so that directory
4336symlinks can be removed with this function, the same as with
4337Unix symlinks */
4338BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4339{
4340 WIN32_FILE_ATTRIBUTE_DATA info;
4341 WIN32_FIND_DATAW find_data;
4342 HANDLE find_data_handle;
4343 int is_directory = 0;
4344 int is_link = 0;
4345
4346 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4347 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004348
Brian Curtind40e6f72010-07-08 21:39:08 +00004349 /* Get WIN32_FIND_DATA structure for the path to determine if
4350 it is a symlink */
4351 if(is_directory &&
4352 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4353 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4354
4355 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004356 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4357 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4358 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4359 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004360 FindClose(find_data_handle);
4361 }
4362 }
4363 }
4364
4365 if (is_directory && is_link)
4366 return RemoveDirectoryW(lpFileName);
4367
4368 return DeleteFileW(lpFileName);
4369}
4370#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004371
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004372
Larry Hastings2f936352014-08-05 14:04:04 +10004373/*[clinic input]
4374os.unlink
4375
4376 path: path_t
4377 *
4378 dir_fd: dir_fd(requires='unlinkat')=None
4379
4380Remove a file (same as remove()).
4381
4382If dir_fd is not None, it should be a file descriptor open to a directory,
4383 and path should be relative; path will then be relative to that directory.
4384dir_fd may not be implemented on your platform.
4385 If it is unavailable, using it will raise a NotImplementedError.
4386
4387[clinic start generated code]*/
4388
Larry Hastings2f936352014-08-05 14:04:04 +10004389static PyObject *
4390os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004391/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004392{
4393 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394
4395 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004396 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004398 if (path->wide)
4399 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004400 else
Larry Hastings2f936352014-08-05 14:04:04 +10004401 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004402 result = !result; /* Windows, success=1, UNIX, success=0 */
4403#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004404#ifdef HAVE_UNLINKAT
4405 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004406 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004407 else
4408#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004409 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004410#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004411 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004412 Py_END_ALLOW_THREADS
4413
Larry Hastings2f936352014-08-05 14:04:04 +10004414 if (result)
4415 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004416
Larry Hastings2f936352014-08-05 14:04:04 +10004417 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004418}
4419
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004420
Larry Hastings2f936352014-08-05 14:04:04 +10004421/*[clinic input]
4422os.remove = os.unlink
4423
4424Remove a file (same as unlink()).
4425
4426If dir_fd is not None, it should be a file descriptor open to a directory,
4427 and path should be relative; path will then be relative to that directory.
4428dir_fd may not be implemented on your platform.
4429 If it is unavailable, using it will raise a NotImplementedError.
4430[clinic start generated code]*/
4431
Larry Hastings2f936352014-08-05 14:04:04 +10004432static PyObject *
4433os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004434/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004435{
4436 return os_unlink_impl(module, path, dir_fd);
4437}
4438
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004439
Larry Hastings605a62d2012-06-24 04:33:36 -07004440static PyStructSequence_Field uname_result_fields[] = {
4441 {"sysname", "operating system name"},
4442 {"nodename", "name of machine on network (implementation-defined)"},
4443 {"release", "operating system release"},
4444 {"version", "operating system version"},
4445 {"machine", "hardware identifier"},
4446 {NULL}
4447};
4448
4449PyDoc_STRVAR(uname_result__doc__,
4450"uname_result: Result from os.uname().\n\n\
4451This object may be accessed either as a tuple of\n\
4452 (sysname, nodename, release, version, machine),\n\
4453or via the attributes sysname, nodename, release, version, and machine.\n\
4454\n\
4455See os.uname for more information.");
4456
4457static PyStructSequence_Desc uname_result_desc = {
4458 "uname_result", /* name */
4459 uname_result__doc__, /* doc */
4460 uname_result_fields,
4461 5
4462};
4463
4464static PyTypeObject UnameResultType;
4465
4466
4467#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004468/*[clinic input]
4469os.uname
4470
4471Return an object identifying the current operating system.
4472
4473The object behaves like a named tuple with the following fields:
4474 (sysname, nodename, release, version, machine)
4475
4476[clinic start generated code]*/
4477
Larry Hastings2f936352014-08-05 14:04:04 +10004478static PyObject *
4479os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004480/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004481{
Victor Stinner8c62be82010-05-06 00:08:46 +00004482 struct utsname u;
4483 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004484 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004485
Victor Stinner8c62be82010-05-06 00:08:46 +00004486 Py_BEGIN_ALLOW_THREADS
4487 res = uname(&u);
4488 Py_END_ALLOW_THREADS
4489 if (res < 0)
4490 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004491
4492 value = PyStructSequence_New(&UnameResultType);
4493 if (value == NULL)
4494 return NULL;
4495
4496#define SET(i, field) \
4497 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004498 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004499 if (!o) { \
4500 Py_DECREF(value); \
4501 return NULL; \
4502 } \
4503 PyStructSequence_SET_ITEM(value, i, o); \
4504 } \
4505
4506 SET(0, u.sysname);
4507 SET(1, u.nodename);
4508 SET(2, u.release);
4509 SET(3, u.version);
4510 SET(4, u.machine);
4511
4512#undef SET
4513
4514 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004515}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004516#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004517
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004518
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519
4520typedef struct {
4521 int now;
4522 time_t atime_s;
4523 long atime_ns;
4524 time_t mtime_s;
4525 long mtime_ns;
4526} utime_t;
4527
4528/*
Victor Stinner484df002014-10-09 13:52:31 +02004529 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004530 * they also intentionally leak the declaration of a pointer named "time"
4531 */
4532#define UTIME_TO_TIMESPEC \
4533 struct timespec ts[2]; \
4534 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004535 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536 time = NULL; \
4537 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004538 ts[0].tv_sec = ut->atime_s; \
4539 ts[0].tv_nsec = ut->atime_ns; \
4540 ts[1].tv_sec = ut->mtime_s; \
4541 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 time = ts; \
4543 } \
4544
4545#define UTIME_TO_TIMEVAL \
4546 struct timeval tv[2]; \
4547 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004548 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 time = NULL; \
4550 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004551 tv[0].tv_sec = ut->atime_s; \
4552 tv[0].tv_usec = ut->atime_ns / 1000; \
4553 tv[1].tv_sec = ut->mtime_s; \
4554 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 time = tv; \
4556 } \
4557
4558#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004559 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004561 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562 time = NULL; \
4563 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004564 u.actime = ut->atime_s; \
4565 u.modtime = ut->mtime_s; \
4566 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567 }
4568
4569#define UTIME_TO_TIME_T \
4570 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004571 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004572 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004573 time = NULL; \
4574 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004575 timet[0] = ut->atime_s; \
4576 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004577 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004578 } \
4579
4580
Victor Stinner528a9ab2015-09-03 21:30:26 +02004581#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582
4583static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004584utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585{
4586#ifdef HAVE_UTIMENSAT
4587 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4588 UTIME_TO_TIMESPEC;
4589 return utimensat(dir_fd, path, time, flags);
4590#elif defined(HAVE_FUTIMESAT)
4591 UTIME_TO_TIMEVAL;
4592 /*
4593 * follow_symlinks will never be false here;
4594 * we only allow !follow_symlinks and dir_fd together
4595 * if we have utimensat()
4596 */
4597 assert(follow_symlinks);
4598 return futimesat(dir_fd, path, time);
4599#endif
4600}
4601
Larry Hastings2f936352014-08-05 14:04:04 +10004602 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4603#else
4604 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605#endif
4606
Victor Stinner528a9ab2015-09-03 21:30:26 +02004607#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608
4609static int
Victor Stinner484df002014-10-09 13:52:31 +02004610utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611{
4612#ifdef HAVE_FUTIMENS
4613 UTIME_TO_TIMESPEC;
4614 return futimens(fd, time);
4615#else
4616 UTIME_TO_TIMEVAL;
4617 return futimes(fd, time);
4618#endif
4619}
4620
Larry Hastings2f936352014-08-05 14:04:04 +10004621 #define PATH_UTIME_HAVE_FD 1
4622#else
4623 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004624#endif
4625
Victor Stinner5ebae872015-09-22 01:29:33 +02004626#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4627# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4628#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004629
Victor Stinner4552ced2015-09-21 22:37:15 +02004630#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631
4632static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004633utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004634{
4635#ifdef HAVE_UTIMENSAT
4636 UTIME_TO_TIMESPEC;
4637 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4638#else
4639 UTIME_TO_TIMEVAL;
4640 return lutimes(path, time);
4641#endif
4642}
4643
4644#endif
4645
4646#ifndef MS_WINDOWS
4647
4648static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004649utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004650{
4651#ifdef HAVE_UTIMENSAT
4652 UTIME_TO_TIMESPEC;
4653 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4654#elif defined(HAVE_UTIMES)
4655 UTIME_TO_TIMEVAL;
4656 return utimes(path, time);
4657#elif defined(HAVE_UTIME_H)
4658 UTIME_TO_UTIMBUF;
4659 return utime(path, time);
4660#else
4661 UTIME_TO_TIME_T;
4662 return utime(path, time);
4663#endif
4664}
4665
4666#endif
4667
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668static int
4669split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4670{
4671 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004672 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004673 divmod = PyNumber_Divmod(py_long, billion);
4674 if (!divmod)
4675 goto exit;
4676 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4677 if ((*s == -1) && PyErr_Occurred())
4678 goto exit;
4679 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004680 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004681 goto exit;
4682
4683 result = 1;
4684exit:
4685 Py_XDECREF(divmod);
4686 return result;
4687}
4688
Larry Hastings2f936352014-08-05 14:04:04 +10004689
4690/*[clinic input]
4691os.utime
4692
4693 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4694 times: object = NULL
4695 *
4696 ns: object = NULL
4697 dir_fd: dir_fd(requires='futimensat') = None
4698 follow_symlinks: bool=True
4699
Martin Panter0ff89092015-09-09 01:56:53 +00004700# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004701
4702Set the access and modified time of path.
4703
4704path may always be specified as a string.
4705On some platforms, path may also be specified as an open file descriptor.
4706 If this functionality is unavailable, using it raises an exception.
4707
4708If times is not None, it must be a tuple (atime, mtime);
4709 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004710If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004711 atime_ns and mtime_ns should be expressed as integer nanoseconds
4712 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004713If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004714Specifying tuples for both times and ns is an error.
4715
4716If dir_fd is not None, it should be a file descriptor open to a directory,
4717 and path should be relative; path will then be relative to that directory.
4718If follow_symlinks is False, and the last element of the path is a symbolic
4719 link, utime will modify the symbolic link itself instead of the file the
4720 link points to.
4721It is an error to use dir_fd or follow_symlinks when specifying path
4722 as an open file descriptor.
4723dir_fd and follow_symlinks may not be available on your platform.
4724 If they are unavailable, using them will raise a NotImplementedError.
4725
4726[clinic start generated code]*/
4727
Larry Hastings2f936352014-08-05 14:04:04 +10004728static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004729os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times,
4730 PyObject *ns, int dir_fd, int follow_symlinks)
Martin Panter0ff89092015-09-09 01:56:53 +00004731/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004732{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004733#ifdef MS_WINDOWS
4734 HANDLE hFile;
4735 FILETIME atime, mtime;
4736#else
4737 int result;
4738#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004739
Larry Hastings9cf065c2012-06-22 16:30:09 -07004740 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004741 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742
Christian Heimesb3c87242013-08-01 00:08:16 +02004743 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004744
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 if (times && (times != Py_None) && ns) {
4746 PyErr_SetString(PyExc_ValueError,
4747 "utime: you may specify either 'times'"
4748 " or 'ns' but not both");
4749 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004750 }
4751
4752 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004753 time_t a_sec, m_sec;
4754 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004755 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 PyErr_SetString(PyExc_TypeError,
4757 "utime: 'times' must be either"
4758 " a tuple of two ints or None");
4759 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004762 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004763 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004764 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004765 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004767 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004768 utime.atime_s = a_sec;
4769 utime.atime_ns = a_nsec;
4770 utime.mtime_s = m_sec;
4771 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004772 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004774 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 PyErr_SetString(PyExc_TypeError,
4776 "utime: 'ns' must be a tuple of two ints");
4777 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004778 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004780 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004782 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783 &utime.mtime_s, &utime.mtime_ns)) {
4784 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004785 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004786 }
4787 else {
4788 /* times and ns are both None/unspecified. use "now". */
4789 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004790 }
4791
Victor Stinner4552ced2015-09-21 22:37:15 +02004792#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004793 if (follow_symlinks_specified("utime", follow_symlinks))
4794 goto exit;
4795#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004796
Larry Hastings2f936352014-08-05 14:04:04 +10004797 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4798 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4799 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004800 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004801
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802#if !defined(HAVE_UTIMENSAT)
4803 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004804 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004805 "utime: cannot use dir_fd and follow_symlinks "
4806 "together on this platform");
4807 goto exit;
4808 }
4809#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004810
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004811#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004812 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004813 if (path->wide)
4814 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004815 NULL, OPEN_EXISTING,
4816 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004817 else
Larry Hastings2f936352014-08-05 14:04:04 +10004818 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 NULL, OPEN_EXISTING,
4820 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821 Py_END_ALLOW_THREADS
4822 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004823 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004825 }
4826
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004828 GetSystemTimeAsFileTime(&mtime);
4829 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004830 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004832 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4833 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004834 }
4835 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4836 /* Avoid putting the file name into the error here,
4837 as that may confuse the user into believing that
4838 something is wrong with the file, when it also
4839 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004840 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004841 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004843#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004845
Victor Stinner4552ced2015-09-21 22:37:15 +02004846#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004847 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004848 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004849 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004850#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004851
Victor Stinner528a9ab2015-09-03 21:30:26 +02004852#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004853 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004854 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004855 else
4856#endif
4857
Victor Stinner528a9ab2015-09-03 21:30:26 +02004858#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004859 if (path->fd != -1)
4860 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004861 else
4862#endif
4863
Larry Hastings2f936352014-08-05 14:04:04 +10004864 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004865
4866 Py_END_ALLOW_THREADS
4867
4868 if (result < 0) {
4869 /* see previous comment about not putting filename in error here */
4870 return_value = posix_error();
4871 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004872 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004873
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004874#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004875
4876 Py_INCREF(Py_None);
4877 return_value = Py_None;
4878
4879exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004880#ifdef MS_WINDOWS
4881 if (hFile != INVALID_HANDLE_VALUE)
4882 CloseHandle(hFile);
4883#endif
4884 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004885}
4886
Guido van Rossum3b066191991-06-04 19:40:25 +00004887/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004888
Larry Hastings2f936352014-08-05 14:04:04 +10004889
4890/*[clinic input]
4891os._exit
4892
4893 status: int
4894
4895Exit to the system with specified status, without normal exit processing.
4896[clinic start generated code]*/
4897
Larry Hastings2f936352014-08-05 14:04:04 +10004898static PyObject *
4899os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004900/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004901{
4902 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004903 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004904}
4905
Martin v. Löwis114619e2002-10-07 06:44:21 +00004906#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4907static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004908free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004909{
Victor Stinner8c62be82010-05-06 00:08:46 +00004910 Py_ssize_t i;
4911 for (i = 0; i < count; i++)
4912 PyMem_Free(array[i]);
4913 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004914}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004915
Antoine Pitrou69f71142009-05-24 21:25:49 +00004916static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004917int fsconvert_strdup(PyObject *o, char**out)
4918{
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 PyObject *bytes;
4920 Py_ssize_t size;
4921 if (!PyUnicode_FSConverter(o, &bytes))
4922 return 0;
4923 size = PyBytes_GET_SIZE(bytes);
4924 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004925 if (!*out) {
4926 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004927 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004928 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004929 memcpy(*out, PyBytes_AsString(bytes), size+1);
4930 Py_DECREF(bytes);
4931 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004932}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004933#endif
4934
Ross Lagerwall7807c352011-03-17 20:20:30 +02004935#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004936static char**
4937parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4938{
Victor Stinner8c62be82010-05-06 00:08:46 +00004939 char **envlist;
4940 Py_ssize_t i, pos, envc;
4941 PyObject *keys=NULL, *vals=NULL;
4942 PyObject *key, *val, *key2, *val2;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004943 char *p;
4944 const char *k, *v;
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004946
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 i = PyMapping_Size(env);
4948 if (i < 0)
4949 return NULL;
4950 envlist = PyMem_NEW(char *, i + 1);
4951 if (envlist == NULL) {
4952 PyErr_NoMemory();
4953 return NULL;
4954 }
4955 envc = 0;
4956 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004957 if (!keys)
4958 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004959 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004960 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004961 goto error;
4962 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4963 PyErr_Format(PyExc_TypeError,
4964 "env.keys() or env.values() is not a list");
4965 goto error;
4966 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004967
Victor Stinner8c62be82010-05-06 00:08:46 +00004968 for (pos = 0; pos < i; pos++) {
4969 key = PyList_GetItem(keys, pos);
4970 val = PyList_GetItem(vals, pos);
4971 if (!key || !val)
4972 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004973
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 if (PyUnicode_FSConverter(key, &key2) == 0)
4975 goto error;
4976 if (PyUnicode_FSConverter(val, &val2) == 0) {
4977 Py_DECREF(key2);
4978 goto error;
4979 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 k = PyBytes_AsString(key2);
4982 v = PyBytes_AsString(val2);
4983 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
Victor Stinner8c62be82010-05-06 00:08:46 +00004985 p = PyMem_NEW(char, len);
4986 if (p == NULL) {
4987 PyErr_NoMemory();
4988 Py_DECREF(key2);
4989 Py_DECREF(val2);
4990 goto error;
4991 }
4992 PyOS_snprintf(p, len, "%s=%s", k, v);
4993 envlist[envc++] = p;
4994 Py_DECREF(key2);
4995 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 }
4997 Py_DECREF(vals);
4998 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004999
Victor Stinner8c62be82010-05-06 00:08:46 +00005000 envlist[envc] = 0;
5001 *envc_ptr = envc;
5002 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005003
5004error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005005 Py_XDECREF(keys);
5006 Py_XDECREF(vals);
5007 while (--envc >= 0)
5008 PyMem_DEL(envlist[envc]);
5009 PyMem_DEL(envlist);
5010 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005011}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005012
Ross Lagerwall7807c352011-03-17 20:20:30 +02005013static char**
5014parse_arglist(PyObject* argv, Py_ssize_t *argc)
5015{
5016 int i;
5017 char **argvlist = PyMem_NEW(char *, *argc+1);
5018 if (argvlist == NULL) {
5019 PyErr_NoMemory();
5020 return NULL;
5021 }
5022 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005023 PyObject* item = PySequence_ITEM(argv, i);
5024 if (item == NULL)
5025 goto fail;
5026 if (!fsconvert_strdup(item, &argvlist[i])) {
5027 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028 goto fail;
5029 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005030 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005031 }
5032 argvlist[*argc] = NULL;
5033 return argvlist;
5034fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005035 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005036 free_string_array(argvlist, *argc);
5037 return NULL;
5038}
5039#endif
5040
Larry Hastings2f936352014-08-05 14:04:04 +10005041
Ross Lagerwall7807c352011-03-17 20:20:30 +02005042#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005043/*[clinic input]
5044os.execv
5045
5046 path: FSConverter
5047 Path of executable file.
5048 argv: object
5049 Tuple or list of strings.
5050 /
5051
5052Execute an executable path with arguments, replacing current process.
5053[clinic start generated code]*/
5054
Larry Hastings2f936352014-08-05 14:04:04 +10005055static PyObject *
5056os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005057/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005058{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005059 const char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005060 char **argvlist;
5061 Py_ssize_t argc;
5062
5063 /* execv has two arguments: (path, argv), where
5064 argv is a list or tuple of strings. */
5065
Larry Hastings2f936352014-08-05 14:04:04 +10005066 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005067 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5068 PyErr_SetString(PyExc_TypeError,
5069 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070 return NULL;
5071 }
5072 argc = PySequence_Size(argv);
5073 if (argc < 1) {
5074 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005075 return NULL;
5076 }
5077
5078 argvlist = parse_arglist(argv, &argc);
5079 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080 return NULL;
5081 }
5082
Larry Hastings2f936352014-08-05 14:04:04 +10005083 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084
5085 /* If we get here it's definitely an error */
5086
5087 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005088 return posix_error();
5089}
5090
Larry Hastings2f936352014-08-05 14:04:04 +10005091
5092/*[clinic input]
5093os.execve
5094
5095 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5096 Path of executable file.
5097 argv: object
5098 Tuple or list of strings.
5099 env: object
5100 Dictionary of strings mapping to strings.
5101
5102Execute an executable path with arguments, replacing current process.
5103[clinic start generated code]*/
5104
Larry Hastings2f936352014-08-05 14:04:04 +10005105static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005106os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv,
5107 PyObject *env)
5108/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005109{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005110 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005112 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 /* execve has three arguments: (path, argv, env), where
5115 argv is a list or tuple of strings and env is a dictionary
5116 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005117
Ross Lagerwall7807c352011-03-17 20:20:30 +02005118 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005120 "execve: argv must be a tuple or list");
5121 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005123 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 if (!PyMapping_Check(env)) {
5125 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126 "execve: environment must be a mapping object");
5127 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005128 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005129
Ross Lagerwall7807c352011-03-17 20:20:30 +02005130 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005132 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005134
Victor Stinner8c62be82010-05-06 00:08:46 +00005135 envlist = parse_envlist(env, &envc);
5136 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005137 goto fail;
5138
Larry Hastings9cf065c2012-06-22 16:30:09 -07005139#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005140 if (path->fd > -1)
5141 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005142 else
5143#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005144 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005145
5146 /* If we get here it's definitely an error */
5147
Larry Hastings2f936352014-08-05 14:04:04 +10005148 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005149
5150 while (--envc >= 0)
5151 PyMem_DEL(envlist[envc]);
5152 PyMem_DEL(envlist);
5153 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005154 if (argvlist)
5155 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005156 return NULL;
5157}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005158#endif /* HAVE_EXECV */
5159
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005160
Guido van Rossuma1065681999-01-25 23:20:23 +00005161#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005162/*[clinic input]
5163os.spawnv
5164
5165 mode: int
5166 Mode of process creation.
5167 path: FSConverter
5168 Path of executable file.
5169 argv: object
5170 Tuple or list of strings.
5171 /
5172
5173Execute the program specified by path in a new process.
5174[clinic start generated code]*/
5175
Larry Hastings2f936352014-08-05 14:04:04 +10005176static PyObject *
5177os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005178/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005179{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005180 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005182 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 Py_ssize_t argc;
5184 Py_intptr_t spawnval;
5185 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005186
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 /* spawnv has three arguments: (mode, path, argv), where
5188 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
Larry Hastings2f936352014-08-05 14:04:04 +10005190 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 if (PyList_Check(argv)) {
5192 argc = PyList_Size(argv);
5193 getitem = PyList_GetItem;
5194 }
5195 else if (PyTuple_Check(argv)) {
5196 argc = PyTuple_Size(argv);
5197 getitem = PyTuple_GetItem;
5198 }
5199 else {
5200 PyErr_SetString(PyExc_TypeError,
5201 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 return NULL;
5203 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 argvlist = PyMem_NEW(char *, argc+1);
5206 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 return PyErr_NoMemory();
5208 }
5209 for (i = 0; i < argc; i++) {
5210 if (!fsconvert_strdup((*getitem)(argv, i),
5211 &argvlist[i])) {
5212 free_string_array(argvlist, i);
5213 PyErr_SetString(
5214 PyExc_TypeError,
5215 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 return NULL;
5217 }
5218 }
5219 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005220
Victor Stinner8c62be82010-05-06 00:08:46 +00005221 if (mode == _OLD_P_OVERLAY)
5222 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005223
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005225 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005229
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 if (spawnval == -1)
5231 return posix_error();
5232 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005233 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005234}
5235
5236
Larry Hastings2f936352014-08-05 14:04:04 +10005237/*[clinic input]
5238os.spawnve
5239
5240 mode: int
5241 Mode of process creation.
5242 path: FSConverter
5243 Path of executable file.
5244 argv: object
5245 Tuple or list of strings.
5246 env: object
5247 Dictionary of strings mapping to strings.
5248 /
5249
5250Execute the program specified by path in a new process.
5251[clinic start generated code]*/
5252
Larry Hastings2f936352014-08-05 14:04:04 +10005253static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005254os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path,
5255 PyObject *argv, PyObject *env)
5256/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005257{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005258 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005259 char **argvlist;
5260 char **envlist;
5261 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005262 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 Py_intptr_t spawnval;
5264 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5265 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005266
Victor Stinner8c62be82010-05-06 00:08:46 +00005267 /* spawnve has four arguments: (mode, path, argv, env), where
5268 argv is a list or tuple of strings and env is a dictionary
5269 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005270
Larry Hastings2f936352014-08-05 14:04:04 +10005271 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 if (PyList_Check(argv)) {
5273 argc = PyList_Size(argv);
5274 getitem = PyList_GetItem;
5275 }
5276 else if (PyTuple_Check(argv)) {
5277 argc = PyTuple_Size(argv);
5278 getitem = PyTuple_GetItem;
5279 }
5280 else {
5281 PyErr_SetString(PyExc_TypeError,
5282 "spawnve() arg 2 must be a tuple or list");
5283 goto fail_0;
5284 }
5285 if (!PyMapping_Check(env)) {
5286 PyErr_SetString(PyExc_TypeError,
5287 "spawnve() arg 3 must be a mapping object");
5288 goto fail_0;
5289 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005290
Victor Stinner8c62be82010-05-06 00:08:46 +00005291 argvlist = PyMem_NEW(char *, argc+1);
5292 if (argvlist == NULL) {
5293 PyErr_NoMemory();
5294 goto fail_0;
5295 }
5296 for (i = 0; i < argc; i++) {
5297 if (!fsconvert_strdup((*getitem)(argv, i),
5298 &argvlist[i]))
5299 {
5300 lastarg = i;
5301 goto fail_1;
5302 }
5303 }
5304 lastarg = argc;
5305 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005306
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 envlist = parse_envlist(env, &envc);
5308 if (envlist == NULL)
5309 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005310
Victor Stinner8c62be82010-05-06 00:08:46 +00005311 if (mode == _OLD_P_OVERLAY)
5312 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005313
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005315 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005317
Victor Stinner8c62be82010-05-06 00:08:46 +00005318 if (spawnval == -1)
5319 (void) posix_error();
5320 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005321 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005322
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 while (--envc >= 0)
5324 PyMem_DEL(envlist[envc]);
5325 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005326 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005328 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005329 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005330}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005331
Guido van Rossuma1065681999-01-25 23:20:23 +00005332#endif /* HAVE_SPAWNV */
5333
5334
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005335#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005336/*[clinic input]
5337os.fork1
5338
5339Fork a child process with a single multiplexed (i.e., not bound) thread.
5340
5341Return 0 to child process and PID of child to parent process.
5342[clinic start generated code]*/
5343
Larry Hastings2f936352014-08-05 14:04:04 +10005344static PyObject *
5345os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005346/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005347{
Victor Stinner8c62be82010-05-06 00:08:46 +00005348 pid_t pid;
5349 int result = 0;
5350 _PyImport_AcquireLock();
5351 pid = fork1();
5352 if (pid == 0) {
5353 /* child: this clobbers and resets the import lock. */
5354 PyOS_AfterFork();
5355 } else {
5356 /* parent: release the import lock. */
5357 result = _PyImport_ReleaseLock();
5358 }
5359 if (pid == -1)
5360 return posix_error();
5361 if (result < 0) {
5362 /* Don't clobber the OSError if the fork failed. */
5363 PyErr_SetString(PyExc_RuntimeError,
5364 "not holding the import lock");
5365 return NULL;
5366 }
5367 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005368}
Larry Hastings2f936352014-08-05 14:04:04 +10005369#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005370
5371
Guido van Rossumad0ee831995-03-01 10:34:45 +00005372#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005373/*[clinic input]
5374os.fork
5375
5376Fork a child process.
5377
5378Return 0 to child process and PID of child to parent process.
5379[clinic start generated code]*/
5380
Larry Hastings2f936352014-08-05 14:04:04 +10005381static PyObject *
5382os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005383/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005384{
Victor Stinner8c62be82010-05-06 00:08:46 +00005385 pid_t pid;
5386 int result = 0;
5387 _PyImport_AcquireLock();
5388 pid = fork();
5389 if (pid == 0) {
5390 /* child: this clobbers and resets the import lock. */
5391 PyOS_AfterFork();
5392 } else {
5393 /* parent: release the import lock. */
5394 result = _PyImport_ReleaseLock();
5395 }
5396 if (pid == -1)
5397 return posix_error();
5398 if (result < 0) {
5399 /* Don't clobber the OSError if the fork failed. */
5400 PyErr_SetString(PyExc_RuntimeError,
5401 "not holding the import lock");
5402 return NULL;
5403 }
5404 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005405}
Larry Hastings2f936352014-08-05 14:04:04 +10005406#endif /* HAVE_FORK */
5407
Guido van Rossum85e3b011991-06-03 12:42:10 +00005408
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005409#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005410#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005411/*[clinic input]
5412os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005413
Larry Hastings2f936352014-08-05 14:04:04 +10005414 policy: int
5415
5416Get the maximum scheduling priority for policy.
5417[clinic start generated code]*/
5418
Larry Hastings2f936352014-08-05 14:04:04 +10005419static PyObject *
5420os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005421/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005422{
5423 int max;
5424
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005425 max = sched_get_priority_max(policy);
5426 if (max < 0)
5427 return posix_error();
5428 return PyLong_FromLong(max);
5429}
5430
Larry Hastings2f936352014-08-05 14:04:04 +10005431
5432/*[clinic input]
5433os.sched_get_priority_min
5434
5435 policy: int
5436
5437Get the minimum scheduling priority for policy.
5438[clinic start generated code]*/
5439
Larry Hastings2f936352014-08-05 14:04:04 +10005440static PyObject *
5441os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005442/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005443{
5444 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005445 if (min < 0)
5446 return posix_error();
5447 return PyLong_FromLong(min);
5448}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005449#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5450
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005451
Larry Hastings2f936352014-08-05 14:04:04 +10005452#ifdef HAVE_SCHED_SETSCHEDULER
5453/*[clinic input]
5454os.sched_getscheduler
5455 pid: pid_t
5456 /
5457
5458Get the scheduling policy for the process identifiedy by pid.
5459
5460Passing 0 for pid returns the scheduling policy for the calling process.
5461[clinic start generated code]*/
5462
Larry Hastings2f936352014-08-05 14:04:04 +10005463static PyObject *
5464os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005465/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005466{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005467 int policy;
5468
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005469 policy = sched_getscheduler(pid);
5470 if (policy < 0)
5471 return posix_error();
5472 return PyLong_FromLong(policy);
5473}
Larry Hastings2f936352014-08-05 14:04:04 +10005474#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005476
5477#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005478/*[clinic input]
5479class os.sched_param "PyObject *" "&SchedParamType"
5480
5481@classmethod
5482os.sched_param.__new__
5483
5484 sched_priority: object
5485 A scheduling parameter.
5486
5487Current has only one field: sched_priority");
5488[clinic start generated code]*/
5489
Larry Hastings2f936352014-08-05 14:04:04 +10005490static PyObject *
5491os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005492/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005493{
5494 PyObject *res;
5495
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 res = PyStructSequence_New(type);
5497 if (!res)
5498 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005499 Py_INCREF(sched_priority);
5500 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005501 return res;
5502}
5503
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005505PyDoc_VAR(os_sched_param__doc__);
5506
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005507static PyStructSequence_Field sched_param_fields[] = {
5508 {"sched_priority", "the scheduling priority"},
5509 {0}
5510};
5511
5512static PyStructSequence_Desc sched_param_desc = {
5513 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005514 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515 sched_param_fields,
5516 1
5517};
5518
5519static int
5520convert_sched_param(PyObject *param, struct sched_param *res)
5521{
5522 long priority;
5523
5524 if (Py_TYPE(param) != &SchedParamType) {
5525 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5526 return 0;
5527 }
5528 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5529 if (priority == -1 && PyErr_Occurred())
5530 return 0;
5531 if (priority > INT_MAX || priority < INT_MIN) {
5532 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5533 return 0;
5534 }
5535 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5536 return 1;
5537}
Larry Hastings2f936352014-08-05 14:04:04 +10005538#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005539
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005540
5541#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005542/*[clinic input]
5543os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005544
Larry Hastings2f936352014-08-05 14:04:04 +10005545 pid: pid_t
5546 policy: int
5547 param: sched_param
5548 /
5549
5550Set the scheduling policy for the process identified by pid.
5551
5552If pid is 0, the calling process is changed.
5553param is an instance of sched_param.
5554[clinic start generated code]*/
5555
Larry Hastings2f936352014-08-05 14:04:04 +10005556static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005557os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy,
5558 struct sched_param *param)
5559/*[clinic end generated code: output=37053e5c528c35c9 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005560{
Jesus Cea9c822272011-09-10 01:40:52 +02005561 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005562 ** sched_setscheduler() returns 0 in Linux, but the previous
5563 ** scheduling policy under Solaris/Illumos, and others.
5564 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005565 */
Larry Hastings2f936352014-08-05 14:04:04 +10005566 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005567 return posix_error();
5568 Py_RETURN_NONE;
5569}
Larry Hastings2f936352014-08-05 14:04:04 +10005570#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005572
5573#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005574/*[clinic input]
5575os.sched_getparam
5576 pid: pid_t
5577 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005578
Larry Hastings2f936352014-08-05 14:04:04 +10005579Returns scheduling parameters for the process identified by pid.
5580
5581If pid is 0, returns parameters for the calling process.
5582Return value is an instance of sched_param.
5583[clinic start generated code]*/
5584
Larry Hastings2f936352014-08-05 14:04:04 +10005585static PyObject *
5586os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005587/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005588{
5589 struct sched_param param;
5590 PyObject *result;
5591 PyObject *priority;
5592
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005593 if (sched_getparam(pid, &param))
5594 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005595 result = PyStructSequence_New(&SchedParamType);
5596 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005597 return NULL;
5598 priority = PyLong_FromLong(param.sched_priority);
5599 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005600 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005601 return NULL;
5602 }
Larry Hastings2f936352014-08-05 14:04:04 +10005603 PyStructSequence_SET_ITEM(result, 0, priority);
5604 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005605}
5606
Larry Hastings2f936352014-08-05 14:04:04 +10005607
5608/*[clinic input]
5609os.sched_setparam
5610 pid: pid_t
5611 param: sched_param
5612 /
5613
5614Set scheduling parameters for the process identified by pid.
5615
5616If pid is 0, sets parameters for the calling process.
5617param should be an instance of sched_param.
5618[clinic start generated code]*/
5619
Larry Hastings2f936352014-08-05 14:04:04 +10005620static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005621os_sched_setparam_impl(PyModuleDef *module, pid_t pid,
5622 struct sched_param *param)
5623/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005624{
5625 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005626 return posix_error();
5627 Py_RETURN_NONE;
5628}
Larry Hastings2f936352014-08-05 14:04:04 +10005629#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005630
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005631
5632#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005633/*[clinic input]
5634os.sched_rr_get_interval -> double
5635 pid: pid_t
5636 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005637
Larry Hastings2f936352014-08-05 14:04:04 +10005638Return the round-robin quantum for the process identified by pid, in seconds.
5639
5640Value returned is a float.
5641[clinic start generated code]*/
5642
Larry Hastings2f936352014-08-05 14:04:04 +10005643static double
5644os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005645/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005646{
5647 struct timespec interval;
5648 if (sched_rr_get_interval(pid, &interval)) {
5649 posix_error();
5650 return -1.0;
5651 }
5652 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5653}
5654#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005655
Larry Hastings2f936352014-08-05 14:04:04 +10005656
5657/*[clinic input]
5658os.sched_yield
5659
5660Voluntarily relinquish the CPU.
5661[clinic start generated code]*/
5662
Larry Hastings2f936352014-08-05 14:04:04 +10005663static PyObject *
5664os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005665/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005666{
5667 if (sched_yield())
5668 return posix_error();
5669 Py_RETURN_NONE;
5670}
5671
Benjamin Peterson2740af82011-08-02 17:41:34 -05005672#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005673/* The minimum number of CPUs allocated in a cpu_set_t */
5674static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005675
Larry Hastings2f936352014-08-05 14:04:04 +10005676/*[clinic input]
5677os.sched_setaffinity
5678 pid: pid_t
5679 mask : object
5680 /
5681
5682Set the CPU affinity of the process identified by pid to mask.
5683
5684mask should be an iterable of integers identifying CPUs.
5685[clinic start generated code]*/
5686
Larry Hastings2f936352014-08-05 14:04:04 +10005687static PyObject *
5688os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005689/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005690{
Antoine Pitrou84869872012-08-04 16:16:35 +02005691 int ncpus;
5692 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005693 cpu_set_t *cpu_set = NULL;
5694 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005695
Larry Hastings2f936352014-08-05 14:04:04 +10005696 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005697 if (iterator == NULL)
5698 return NULL;
5699
5700 ncpus = NCPUS_START;
5701 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005702 cpu_set = CPU_ALLOC(ncpus);
5703 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005704 PyErr_NoMemory();
5705 goto error;
5706 }
Larry Hastings2f936352014-08-05 14:04:04 +10005707 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005708
5709 while ((item = PyIter_Next(iterator))) {
5710 long cpu;
5711 if (!PyLong_Check(item)) {
5712 PyErr_Format(PyExc_TypeError,
5713 "expected an iterator of ints, "
5714 "but iterator yielded %R",
5715 Py_TYPE(item));
5716 Py_DECREF(item);
5717 goto error;
5718 }
5719 cpu = PyLong_AsLong(item);
5720 Py_DECREF(item);
5721 if (cpu < 0) {
5722 if (!PyErr_Occurred())
5723 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5724 goto error;
5725 }
5726 if (cpu > INT_MAX - 1) {
5727 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5728 goto error;
5729 }
5730 if (cpu >= ncpus) {
5731 /* Grow CPU mask to fit the CPU number */
5732 int newncpus = ncpus;
5733 cpu_set_t *newmask;
5734 size_t newsetsize;
5735 while (newncpus <= cpu) {
5736 if (newncpus > INT_MAX / 2)
5737 newncpus = cpu + 1;
5738 else
5739 newncpus = newncpus * 2;
5740 }
5741 newmask = CPU_ALLOC(newncpus);
5742 if (newmask == NULL) {
5743 PyErr_NoMemory();
5744 goto error;
5745 }
5746 newsetsize = CPU_ALLOC_SIZE(newncpus);
5747 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005748 memcpy(newmask, cpu_set, setsize);
5749 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005750 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005751 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005752 ncpus = newncpus;
5753 }
Larry Hastings2f936352014-08-05 14:04:04 +10005754 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005755 }
5756 Py_CLEAR(iterator);
5757
Larry Hastings2f936352014-08-05 14:04:04 +10005758 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005759 posix_error();
5760 goto error;
5761 }
Larry Hastings2f936352014-08-05 14:04:04 +10005762 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005763 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005764
5765error:
Larry Hastings2f936352014-08-05 14:04:04 +10005766 if (cpu_set)
5767 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005768 Py_XDECREF(iterator);
5769 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005770}
5771
Larry Hastings2f936352014-08-05 14:04:04 +10005772
5773/*[clinic input]
5774os.sched_getaffinity
5775 pid: pid_t
5776 /
5777
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005778Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005779
5780The affinity is returned as a set of CPU identifiers.
5781[clinic start generated code]*/
5782
Larry Hastings2f936352014-08-05 14:04:04 +10005783static PyObject *
5784os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Charles-François Natali80d62e62015-08-13 20:37:08 +01005785/*[clinic end generated code: output=b431a8f310e369e7 input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005786{
Antoine Pitrou84869872012-08-04 16:16:35 +02005787 int cpu, ncpus, count;
5788 size_t setsize;
5789 cpu_set_t *mask = NULL;
5790 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005791
Antoine Pitrou84869872012-08-04 16:16:35 +02005792 ncpus = NCPUS_START;
5793 while (1) {
5794 setsize = CPU_ALLOC_SIZE(ncpus);
5795 mask = CPU_ALLOC(ncpus);
5796 if (mask == NULL)
5797 return PyErr_NoMemory();
5798 if (sched_getaffinity(pid, setsize, mask) == 0)
5799 break;
5800 CPU_FREE(mask);
5801 if (errno != EINVAL)
5802 return posix_error();
5803 if (ncpus > INT_MAX / 2) {
5804 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5805 "a large enough CPU set");
5806 return NULL;
5807 }
5808 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005809 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005810
5811 res = PySet_New(NULL);
5812 if (res == NULL)
5813 goto error;
5814 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5815 if (CPU_ISSET_S(cpu, setsize, mask)) {
5816 PyObject *cpu_num = PyLong_FromLong(cpu);
5817 --count;
5818 if (cpu_num == NULL)
5819 goto error;
5820 if (PySet_Add(res, cpu_num)) {
5821 Py_DECREF(cpu_num);
5822 goto error;
5823 }
5824 Py_DECREF(cpu_num);
5825 }
5826 }
5827 CPU_FREE(mask);
5828 return res;
5829
5830error:
5831 if (mask)
5832 CPU_FREE(mask);
5833 Py_XDECREF(res);
5834 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005835}
5836
Benjamin Peterson2740af82011-08-02 17:41:34 -05005837#endif /* HAVE_SCHED_SETAFFINITY */
5838
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005839#endif /* HAVE_SCHED_H */
5840
Larry Hastings2f936352014-08-05 14:04:04 +10005841
Neal Norwitzb59798b2003-03-21 01:43:31 +00005842/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005843/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5844#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005845#define DEV_PTY_FILE "/dev/ptc"
5846#define HAVE_DEV_PTMX
5847#else
5848#define DEV_PTY_FILE "/dev/ptmx"
5849#endif
5850
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005851#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005852#ifdef HAVE_PTY_H
5853#include <pty.h>
5854#else
5855#ifdef HAVE_LIBUTIL_H
5856#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005857#else
5858#ifdef HAVE_UTIL_H
5859#include <util.h>
5860#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005861#endif /* HAVE_LIBUTIL_H */
5862#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005863#ifdef HAVE_STROPTS_H
5864#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005865#endif
5866#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005867
Larry Hastings2f936352014-08-05 14:04:04 +10005868
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005869#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005870/*[clinic input]
5871os.openpty
5872
5873Open a pseudo-terminal.
5874
5875Return a tuple of (master_fd, slave_fd) containing open file descriptors
5876for both the master and slave ends.
5877[clinic start generated code]*/
5878
Larry Hastings2f936352014-08-05 14:04:04 +10005879static PyObject *
5880os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005881/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005882{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005883 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005884#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005886#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005887#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005889#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005891#endif
5892#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005893
Thomas Wouters70c21a12000-07-14 14:28:33 +00005894#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005896 goto posix_error;
5897
5898 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5899 goto error;
5900 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5901 goto error;
5902
Neal Norwitzb59798b2003-03-21 01:43:31 +00005903#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005904 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5905 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005906 goto posix_error;
5907 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5908 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005909
Victor Stinnerdaf45552013-08-28 00:53:59 +02005910 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005911 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005912 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005913
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005914#else
Victor Stinner000de532013-11-25 23:19:58 +01005915 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005917 goto posix_error;
5918
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005920
Victor Stinner8c62be82010-05-06 00:08:46 +00005921 /* change permission of slave */
5922 if (grantpt(master_fd) < 0) {
5923 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005924 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005926
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 /* unlock slave */
5928 if (unlockpt(master_fd) < 0) {
5929 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005930 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005932
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005934
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 slave_name = ptsname(master_fd); /* get name of slave */
5936 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005937 goto posix_error;
5938
5939 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005940 if (slave_fd == -1)
5941 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005942
5943 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5944 goto posix_error;
5945
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005946#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005947 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5948 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005949#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005951#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005952#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005953#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005954
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005956
Victor Stinnerdaf45552013-08-28 00:53:59 +02005957posix_error:
5958 posix_error();
5959error:
5960 if (master_fd != -1)
5961 close(master_fd);
5962 if (slave_fd != -1)
5963 close(slave_fd);
5964 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005965}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005966#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005967
Larry Hastings2f936352014-08-05 14:04:04 +10005968
Fred Drake8cef4cf2000-06-28 16:40:38 +00005969#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005970/*[clinic input]
5971os.forkpty
5972
5973Fork a new process with a new pseudo-terminal as controlling tty.
5974
5975Returns a tuple of (pid, master_fd).
5976Like fork(), return pid of 0 to the child process,
5977and pid of child to the parent process.
5978To both, return fd of newly opened pseudo-terminal.
5979[clinic start generated code]*/
5980
Larry Hastings2f936352014-08-05 14:04:04 +10005981static PyObject *
5982os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005983/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005984{
Victor Stinner8c62be82010-05-06 00:08:46 +00005985 int master_fd = -1, result = 0;
5986 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005987
Victor Stinner8c62be82010-05-06 00:08:46 +00005988 _PyImport_AcquireLock();
5989 pid = forkpty(&master_fd, NULL, NULL, NULL);
5990 if (pid == 0) {
5991 /* child: this clobbers and resets the import lock. */
5992 PyOS_AfterFork();
5993 } else {
5994 /* parent: release the import lock. */
5995 result = _PyImport_ReleaseLock();
5996 }
5997 if (pid == -1)
5998 return posix_error();
5999 if (result < 0) {
6000 /* Don't clobber the OSError if the fork failed. */
6001 PyErr_SetString(PyExc_RuntimeError,
6002 "not holding the import lock");
6003 return NULL;
6004 }
6005 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006006}
Larry Hastings2f936352014-08-05 14:04:04 +10006007#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006008
Ross Lagerwall7807c352011-03-17 20:20:30 +02006009
Guido van Rossumad0ee831995-03-01 10:34:45 +00006010#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006011/*[clinic input]
6012os.getegid
6013
6014Return the current process's effective group id.
6015[clinic start generated code]*/
6016
Larry Hastings2f936352014-08-05 14:04:04 +10006017static PyObject *
6018os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006019/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006020{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006021 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006022}
Larry Hastings2f936352014-08-05 14:04:04 +10006023#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006025
Guido van Rossumad0ee831995-03-01 10:34:45 +00006026#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006027/*[clinic input]
6028os.geteuid
6029
6030Return the current process's effective user id.
6031[clinic start generated code]*/
6032
Larry Hastings2f936352014-08-05 14:04:04 +10006033static PyObject *
6034os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006035/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006036{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006037 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006038}
Larry Hastings2f936352014-08-05 14:04:04 +10006039#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006040
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006041
Guido van Rossumad0ee831995-03-01 10:34:45 +00006042#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006043/*[clinic input]
6044os.getgid
6045
6046Return the current process's group id.
6047[clinic start generated code]*/
6048
Larry Hastings2f936352014-08-05 14:04:04 +10006049static PyObject *
6050os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006051/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006052{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006053 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006054}
Larry Hastings2f936352014-08-05 14:04:04 +10006055#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006056
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006057
Larry Hastings2f936352014-08-05 14:04:04 +10006058/*[clinic input]
6059os.getpid
6060
6061Return the current process id.
6062[clinic start generated code]*/
6063
Larry Hastings2f936352014-08-05 14:04:04 +10006064static PyObject *
6065os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006066/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006067{
Victor Stinner8c62be82010-05-06 00:08:46 +00006068 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006069}
6070
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006071#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006072
6073/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006074PyDoc_STRVAR(posix_getgrouplist__doc__,
6075"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6076Returns a list of groups to which a user belongs.\n\n\
6077 user: username to lookup\n\
6078 group: base group id of the user");
6079
6080static PyObject *
6081posix_getgrouplist(PyObject *self, PyObject *args)
6082{
6083#ifdef NGROUPS_MAX
6084#define MAX_GROUPS NGROUPS_MAX
6085#else
6086 /* defined to be 16 on Solaris7, so this should be a small number */
6087#define MAX_GROUPS 64
6088#endif
6089
6090 const char *user;
6091 int i, ngroups;
6092 PyObject *list;
6093#ifdef __APPLE__
6094 int *groups, basegid;
6095#else
6096 gid_t *groups, basegid;
6097#endif
6098 ngroups = MAX_GROUPS;
6099
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006100#ifdef __APPLE__
6101 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006102 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006103#else
6104 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6105 _Py_Gid_Converter, &basegid))
6106 return NULL;
6107#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006108
6109#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006110 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006111#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006112 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006113#endif
6114 if (groups == NULL)
6115 return PyErr_NoMemory();
6116
6117 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6118 PyMem_Del(groups);
6119 return posix_error();
6120 }
6121
6122 list = PyList_New(ngroups);
6123 if (list == NULL) {
6124 PyMem_Del(groups);
6125 return NULL;
6126 }
6127
6128 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006129#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006130 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006131#else
6132 PyObject *o = _PyLong_FromGid(groups[i]);
6133#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006134 if (o == NULL) {
6135 Py_DECREF(list);
6136 PyMem_Del(groups);
6137 return NULL;
6138 }
6139 PyList_SET_ITEM(list, i, o);
6140 }
6141
6142 PyMem_Del(groups);
6143
6144 return list;
6145}
Larry Hastings2f936352014-08-05 14:04:04 +10006146#endif /* HAVE_GETGROUPLIST */
6147
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006148
Fred Drakec9680921999-12-13 16:37:25 +00006149#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006150/*[clinic input]
6151os.getgroups
6152
6153Return list of supplemental group IDs for the process.
6154[clinic start generated code]*/
6155
Larry Hastings2f936352014-08-05 14:04:04 +10006156static PyObject *
6157os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006158/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006159{
6160 PyObject *result = NULL;
6161
Fred Drakec9680921999-12-13 16:37:25 +00006162#ifdef NGROUPS_MAX
6163#define MAX_GROUPS NGROUPS_MAX
6164#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006165 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006166#define MAX_GROUPS 64
6167#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006168 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006169
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006170 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006171 * This is a helper variable to store the intermediate result when
6172 * that happens.
6173 *
6174 * To keep the code readable the OSX behaviour is unconditional,
6175 * according to the POSIX spec this should be safe on all unix-y
6176 * systems.
6177 */
6178 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006179 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006180
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006181#ifdef __APPLE__
6182 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6183 * there are more groups than can fit in grouplist. Therefore, on OS X
6184 * always first call getgroups with length 0 to get the actual number
6185 * of groups.
6186 */
6187 n = getgroups(0, NULL);
6188 if (n < 0) {
6189 return posix_error();
6190 } else if (n <= MAX_GROUPS) {
6191 /* groups will fit in existing array */
6192 alt_grouplist = grouplist;
6193 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006194 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006195 if (alt_grouplist == NULL) {
6196 errno = EINVAL;
6197 return posix_error();
6198 }
6199 }
6200
6201 n = getgroups(n, alt_grouplist);
6202 if (n == -1) {
6203 if (alt_grouplist != grouplist) {
6204 PyMem_Free(alt_grouplist);
6205 }
6206 return posix_error();
6207 }
6208#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006209 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006210 if (n < 0) {
6211 if (errno == EINVAL) {
6212 n = getgroups(0, NULL);
6213 if (n == -1) {
6214 return posix_error();
6215 }
6216 if (n == 0) {
6217 /* Avoid malloc(0) */
6218 alt_grouplist = grouplist;
6219 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006220 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006221 if (alt_grouplist == NULL) {
6222 errno = EINVAL;
6223 return posix_error();
6224 }
6225 n = getgroups(n, alt_grouplist);
6226 if (n == -1) {
6227 PyMem_Free(alt_grouplist);
6228 return posix_error();
6229 }
6230 }
6231 } else {
6232 return posix_error();
6233 }
6234 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006235#endif
6236
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006237 result = PyList_New(n);
6238 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 int i;
6240 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006241 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006242 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006243 Py_DECREF(result);
6244 result = NULL;
6245 break;
Fred Drakec9680921999-12-13 16:37:25 +00006246 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006248 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006249 }
6250
6251 if (alt_grouplist != grouplist) {
6252 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006253 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006254
Fred Drakec9680921999-12-13 16:37:25 +00006255 return result;
6256}
Larry Hastings2f936352014-08-05 14:04:04 +10006257#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006258
Antoine Pitroub7572f02009-12-02 20:46:48 +00006259#ifdef HAVE_INITGROUPS
6260PyDoc_STRVAR(posix_initgroups__doc__,
6261"initgroups(username, gid) -> None\n\n\
6262Call the system initgroups() to initialize the group access list with all of\n\
6263the groups of which the specified username is a member, plus the specified\n\
6264group id.");
6265
Larry Hastings2f936352014-08-05 14:04:04 +10006266/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006267static PyObject *
6268posix_initgroups(PyObject *self, PyObject *args)
6269{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006270 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006271 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006272 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006273#ifdef __APPLE__
6274 int gid;
6275#else
6276 gid_t gid;
6277#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006278
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006279#ifdef __APPLE__
6280 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6281 PyUnicode_FSConverter, &oname,
6282 &gid))
6283#else
6284 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6285 PyUnicode_FSConverter, &oname,
6286 _Py_Gid_Converter, &gid))
6287#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006288 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006289 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006290
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006291 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006292 Py_DECREF(oname);
6293 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006295
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 Py_INCREF(Py_None);
6297 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006298}
Larry Hastings2f936352014-08-05 14:04:04 +10006299#endif /* HAVE_INITGROUPS */
6300
Antoine Pitroub7572f02009-12-02 20:46:48 +00006301
Martin v. Löwis606edc12002-06-13 21:09:11 +00006302#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006303/*[clinic input]
6304os.getpgid
6305
6306 pid: pid_t
6307
6308Call the system call getpgid(), and return the result.
6309[clinic start generated code]*/
6310
Larry Hastings2f936352014-08-05 14:04:04 +10006311static PyObject *
6312os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006313/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006314{
6315 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 if (pgid < 0)
6317 return posix_error();
6318 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006319}
6320#endif /* HAVE_GETPGID */
6321
6322
Guido van Rossumb6775db1994-08-01 11:34:53 +00006323#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006324/*[clinic input]
6325os.getpgrp
6326
6327Return the current process group id.
6328[clinic start generated code]*/
6329
Larry Hastings2f936352014-08-05 14:04:04 +10006330static PyObject *
6331os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006332/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006333{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006334#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006336#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006337 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006338#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006339}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006340#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006341
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006342
Guido van Rossumb6775db1994-08-01 11:34:53 +00006343#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006344/*[clinic input]
6345os.setpgrp
6346
6347Make the current process the leader of its process group.
6348[clinic start generated code]*/
6349
Larry Hastings2f936352014-08-05 14:04:04 +10006350static PyObject *
6351os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006352/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006353{
Guido van Rossum64933891994-10-20 21:56:42 +00006354#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006356#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006357 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006358#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006359 return posix_error();
6360 Py_INCREF(Py_None);
6361 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006362}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006363#endif /* HAVE_SETPGRP */
6364
Guido van Rossumad0ee831995-03-01 10:34:45 +00006365#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006366
6367#ifdef MS_WINDOWS
6368#include <tlhelp32.h>
6369
6370static PyObject*
6371win32_getppid()
6372{
6373 HANDLE snapshot;
6374 pid_t mypid;
6375 PyObject* result = NULL;
6376 BOOL have_record;
6377 PROCESSENTRY32 pe;
6378
6379 mypid = getpid(); /* This function never fails */
6380
6381 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6382 if (snapshot == INVALID_HANDLE_VALUE)
6383 return PyErr_SetFromWindowsErr(GetLastError());
6384
6385 pe.dwSize = sizeof(pe);
6386 have_record = Process32First(snapshot, &pe);
6387 while (have_record) {
6388 if (mypid == (pid_t)pe.th32ProcessID) {
6389 /* We could cache the ulong value in a static variable. */
6390 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6391 break;
6392 }
6393
6394 have_record = Process32Next(snapshot, &pe);
6395 }
6396
6397 /* If our loop exits and our pid was not found (result will be NULL)
6398 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6399 * error anyway, so let's raise it. */
6400 if (!result)
6401 result = PyErr_SetFromWindowsErr(GetLastError());
6402
6403 CloseHandle(snapshot);
6404
6405 return result;
6406}
6407#endif /*MS_WINDOWS*/
6408
Larry Hastings2f936352014-08-05 14:04:04 +10006409
6410/*[clinic input]
6411os.getppid
6412
6413Return the parent's process id.
6414
6415If the parent process has already exited, Windows machines will still
6416return its id; others systems will return the id of the 'init' process (1).
6417[clinic start generated code]*/
6418
Larry Hastings2f936352014-08-05 14:04:04 +10006419static PyObject *
6420os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006421/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006422{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006423#ifdef MS_WINDOWS
6424 return win32_getppid();
6425#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006426 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006427#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006428}
6429#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006430
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006431
Fred Drake12c6e2d1999-12-14 21:25:03 +00006432#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006433/*[clinic input]
6434os.getlogin
6435
6436Return the actual login name.
6437[clinic start generated code]*/
6438
Larry Hastings2f936352014-08-05 14:04:04 +10006439static PyObject *
6440os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006441/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006442{
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006444#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006445 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006446 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006447
6448 if (GetUserNameW(user_name, &num_chars)) {
6449 /* num_chars is the number of unicode chars plus null terminator */
6450 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006451 }
6452 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006453 result = PyErr_SetFromWindowsErr(GetLastError());
6454#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 char *name;
6456 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006457
Victor Stinner8c62be82010-05-06 00:08:46 +00006458 errno = 0;
6459 name = getlogin();
6460 if (name == NULL) {
6461 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006462 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006463 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006464 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006465 }
6466 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006467 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006468 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006469#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006470 return result;
6471}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006472#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006473
Larry Hastings2f936352014-08-05 14:04:04 +10006474
Guido van Rossumad0ee831995-03-01 10:34:45 +00006475#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006476/*[clinic input]
6477os.getuid
6478
6479Return the current process's user id.
6480[clinic start generated code]*/
6481
Larry Hastings2f936352014-08-05 14:04:04 +10006482static PyObject *
6483os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006484/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006485{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006486 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006487}
Larry Hastings2f936352014-08-05 14:04:04 +10006488#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006489
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006490
Brian Curtineb24d742010-04-12 17:16:38 +00006491#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006492#define HAVE_KILL
6493#endif /* MS_WINDOWS */
6494
6495#ifdef HAVE_KILL
6496/*[clinic input]
6497os.kill
6498
6499 pid: pid_t
6500 signal: Py_ssize_t
6501 /
6502
6503Kill a process with a signal.
6504[clinic start generated code]*/
6505
Larry Hastings2f936352014-08-05 14:04:04 +10006506static PyObject *
6507os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006508/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006509#ifndef MS_WINDOWS
6510{
6511 if (kill(pid, (int)signal) == -1)
6512 return posix_error();
6513 Py_RETURN_NONE;
6514}
6515#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006516{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006517 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006518 DWORD sig = (DWORD)signal;
6519 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006521
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 /* Console processes which share a common console can be sent CTRL+C or
6523 CTRL+BREAK events, provided they handle said events. */
6524 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006525 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 err = GetLastError();
6527 PyErr_SetFromWindowsErr(err);
6528 }
6529 else
6530 Py_RETURN_NONE;
6531 }
Brian Curtineb24d742010-04-12 17:16:38 +00006532
Victor Stinner8c62be82010-05-06 00:08:46 +00006533 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6534 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006535 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 if (handle == NULL) {
6537 err = GetLastError();
6538 return PyErr_SetFromWindowsErr(err);
6539 }
Brian Curtineb24d742010-04-12 17:16:38 +00006540
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 if (TerminateProcess(handle, sig) == 0) {
6542 err = GetLastError();
6543 result = PyErr_SetFromWindowsErr(err);
6544 } else {
6545 Py_INCREF(Py_None);
6546 result = Py_None;
6547 }
Brian Curtineb24d742010-04-12 17:16:38 +00006548
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 CloseHandle(handle);
6550 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006551}
Larry Hastings2f936352014-08-05 14:04:04 +10006552#endif /* !MS_WINDOWS */
6553#endif /* HAVE_KILL */
6554
6555
6556#ifdef HAVE_KILLPG
6557/*[clinic input]
6558os.killpg
6559
6560 pgid: pid_t
6561 signal: int
6562 /
6563
6564Kill a process group with a signal.
6565[clinic start generated code]*/
6566
Larry Hastings2f936352014-08-05 14:04:04 +10006567static PyObject *
6568os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006569/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006570{
6571 /* XXX some man pages make the `pgid` parameter an int, others
6572 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6573 take the same type. Moreover, pid_t is always at least as wide as
6574 int (else compilation of this module fails), which is safe. */
6575 if (killpg(pgid, signal) == -1)
6576 return posix_error();
6577 Py_RETURN_NONE;
6578}
6579#endif /* HAVE_KILLPG */
6580
Brian Curtineb24d742010-04-12 17:16:38 +00006581
Guido van Rossumc0125471996-06-28 18:55:32 +00006582#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006583#ifdef HAVE_SYS_LOCK_H
6584#include <sys/lock.h>
6585#endif
6586
Larry Hastings2f936352014-08-05 14:04:04 +10006587/*[clinic input]
6588os.plock
6589 op: int
6590 /
6591
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006592Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006593[clinic start generated code]*/
6594
Larry Hastings2f936352014-08-05 14:04:04 +10006595static PyObject *
6596os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006597/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006598{
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 if (plock(op) == -1)
6600 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006601 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006602}
Larry Hastings2f936352014-08-05 14:04:04 +10006603#endif /* HAVE_PLOCK */
6604
Guido van Rossumc0125471996-06-28 18:55:32 +00006605
Guido van Rossumb6775db1994-08-01 11:34:53 +00006606#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006607/*[clinic input]
6608os.setuid
6609
6610 uid: uid_t
6611 /
6612
6613Set the current process's user id.
6614[clinic start generated code]*/
6615
Larry Hastings2f936352014-08-05 14:04:04 +10006616static PyObject *
6617os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006618/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006619{
Victor Stinner8c62be82010-05-06 00:08:46 +00006620 if (setuid(uid) < 0)
6621 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006622 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006623}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006624#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006625
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006626
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006627#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006628/*[clinic input]
6629os.seteuid
6630
6631 euid: uid_t
6632 /
6633
6634Set the current process's effective user id.
6635[clinic start generated code]*/
6636
Larry Hastings2f936352014-08-05 14:04:04 +10006637static PyObject *
6638os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006639/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006640{
6641 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006643 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006644}
6645#endif /* HAVE_SETEUID */
6646
Larry Hastings2f936352014-08-05 14:04:04 +10006647
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006648#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006649/*[clinic input]
6650os.setegid
6651
6652 egid: gid_t
6653 /
6654
6655Set the current process's effective group id.
6656[clinic start generated code]*/
6657
Larry Hastings2f936352014-08-05 14:04:04 +10006658static PyObject *
6659os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006660/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006661{
6662 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006664 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006665}
6666#endif /* HAVE_SETEGID */
6667
Larry Hastings2f936352014-08-05 14:04:04 +10006668
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006669#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006670/*[clinic input]
6671os.setreuid
6672
6673 ruid: uid_t
6674 euid: uid_t
6675 /
6676
6677Set the current process's real and effective user ids.
6678[clinic start generated code]*/
6679
Larry Hastings2f936352014-08-05 14:04:04 +10006680static PyObject *
6681os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006682/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006683{
Victor Stinner8c62be82010-05-06 00:08:46 +00006684 if (setreuid(ruid, euid) < 0) {
6685 return posix_error();
6686 } else {
6687 Py_INCREF(Py_None);
6688 return Py_None;
6689 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006690}
6691#endif /* HAVE_SETREUID */
6692
Larry Hastings2f936352014-08-05 14:04:04 +10006693
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006694#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006695/*[clinic input]
6696os.setregid
6697
6698 rgid: gid_t
6699 egid: gid_t
6700 /
6701
6702Set the current process's real and effective group ids.
6703[clinic start generated code]*/
6704
Larry Hastings2f936352014-08-05 14:04:04 +10006705static PyObject *
6706os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006707/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006708{
6709 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006711 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006712}
6713#endif /* HAVE_SETREGID */
6714
Larry Hastings2f936352014-08-05 14:04:04 +10006715
Guido van Rossumb6775db1994-08-01 11:34:53 +00006716#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006717/*[clinic input]
6718os.setgid
6719 gid: gid_t
6720 /
6721
6722Set the current process's group id.
6723[clinic start generated code]*/
6724
Larry Hastings2f936352014-08-05 14:04:04 +10006725static PyObject *
6726os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006727/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 if (setgid(gid) < 0)
6730 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006731 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006732}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006733#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006734
Larry Hastings2f936352014-08-05 14:04:04 +10006735
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006736#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006737/*[clinic input]
6738os.setgroups
6739
6740 groups: object
6741 /
6742
6743Set the groups of the current process to list.
6744[clinic start generated code]*/
6745
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006746static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006747os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006748/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006749{
Victor Stinner8c62be82010-05-06 00:08:46 +00006750 int i, len;
6751 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006752
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 if (!PySequence_Check(groups)) {
6754 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6755 return NULL;
6756 }
6757 len = PySequence_Size(groups);
6758 if (len > MAX_GROUPS) {
6759 PyErr_SetString(PyExc_ValueError, "too many groups");
6760 return NULL;
6761 }
6762 for(i = 0; i < len; i++) {
6763 PyObject *elem;
6764 elem = PySequence_GetItem(groups, i);
6765 if (!elem)
6766 return NULL;
6767 if (!PyLong_Check(elem)) {
6768 PyErr_SetString(PyExc_TypeError,
6769 "groups must be integers");
6770 Py_DECREF(elem);
6771 return NULL;
6772 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006773 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 Py_DECREF(elem);
6775 return NULL;
6776 }
6777 }
6778 Py_DECREF(elem);
6779 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006780
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 if (setgroups(len, grouplist) < 0)
6782 return posix_error();
6783 Py_INCREF(Py_None);
6784 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006785}
6786#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006787
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006788#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6789static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006790wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006791{
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 PyObject *result;
6793 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006794 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006795
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 if (pid == -1)
6797 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006798
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 if (struct_rusage == NULL) {
6800 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6801 if (m == NULL)
6802 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006803 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 Py_DECREF(m);
6805 if (struct_rusage == NULL)
6806 return NULL;
6807 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6810 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6811 if (!result)
6812 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006813
6814#ifndef doubletime
6815#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6816#endif
6817
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006819 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006820 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006821 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006822#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006823 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6824 SET_INT(result, 2, ru->ru_maxrss);
6825 SET_INT(result, 3, ru->ru_ixrss);
6826 SET_INT(result, 4, ru->ru_idrss);
6827 SET_INT(result, 5, ru->ru_isrss);
6828 SET_INT(result, 6, ru->ru_minflt);
6829 SET_INT(result, 7, ru->ru_majflt);
6830 SET_INT(result, 8, ru->ru_nswap);
6831 SET_INT(result, 9, ru->ru_inblock);
6832 SET_INT(result, 10, ru->ru_oublock);
6833 SET_INT(result, 11, ru->ru_msgsnd);
6834 SET_INT(result, 12, ru->ru_msgrcv);
6835 SET_INT(result, 13, ru->ru_nsignals);
6836 SET_INT(result, 14, ru->ru_nvcsw);
6837 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006838#undef SET_INT
6839
Victor Stinner8c62be82010-05-06 00:08:46 +00006840 if (PyErr_Occurred()) {
6841 Py_DECREF(result);
6842 return NULL;
6843 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006844
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846}
6847#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6848
Larry Hastings2f936352014-08-05 14:04:04 +10006849
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006851/*[clinic input]
6852os.wait3
6853
6854 options: int
6855Wait for completion of a child process.
6856
6857Returns a tuple of information about the child process:
6858 (pid, status, rusage)
6859[clinic start generated code]*/
6860
Larry Hastings2f936352014-08-05 14:04:04 +10006861static PyObject *
6862os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006863/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864{
Victor Stinner8c62be82010-05-06 00:08:46 +00006865 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006867 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 WAIT_TYPE status;
6869 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006870
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006871 do {
6872 Py_BEGIN_ALLOW_THREADS
6873 pid = wait3(&status, options, &ru);
6874 Py_END_ALLOW_THREADS
6875 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6876 if (pid < 0)
6877 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006878
Victor Stinner4195b5c2012-02-08 23:03:19 +01006879 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880}
6881#endif /* HAVE_WAIT3 */
6882
Larry Hastings2f936352014-08-05 14:04:04 +10006883
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006884#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006885/*[clinic input]
6886
6887os.wait4
6888
6889 pid: pid_t
6890 options: int
6891
6892Wait for completion of a specific child process.
6893
6894Returns a tuple of information about the child process:
6895 (pid, status, rusage)
6896[clinic start generated code]*/
6897
Larry Hastings2f936352014-08-05 14:04:04 +10006898static PyObject *
6899os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006900/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006901{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006902 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006905 WAIT_TYPE status;
6906 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006907
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006908 do {
6909 Py_BEGIN_ALLOW_THREADS
6910 res = wait4(pid, &status, options, &ru);
6911 Py_END_ALLOW_THREADS
6912 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6913 if (res < 0)
6914 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006916 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006917}
6918#endif /* HAVE_WAIT4 */
6919
Larry Hastings2f936352014-08-05 14:04:04 +10006920
Ross Lagerwall7807c352011-03-17 20:20:30 +02006921#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006922/*[clinic input]
6923os.waitid
6924
6925 idtype: idtype_t
6926 Must be one of be P_PID, P_PGID or P_ALL.
6927 id: id_t
6928 The id to wait on.
6929 options: int
6930 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6931 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6932 /
6933
6934Returns the result of waiting for a process or processes.
6935
6936Returns either waitid_result or None if WNOHANG is specified and there are
6937no children in a waitable state.
6938[clinic start generated code]*/
6939
Larry Hastings2f936352014-08-05 14:04:04 +10006940static PyObject *
6941os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006942/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006943{
6944 PyObject *result;
6945 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006947 siginfo_t si;
6948 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006949
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006950 do {
6951 Py_BEGIN_ALLOW_THREADS
6952 res = waitid(idtype, id, &si, options);
6953 Py_END_ALLOW_THREADS
6954 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6955 if (res < 0)
6956 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006957
6958 if (si.si_pid == 0)
6959 Py_RETURN_NONE;
6960
6961 result = PyStructSequence_New(&WaitidResultType);
6962 if (!result)
6963 return NULL;
6964
6965 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006966 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006967 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6968 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6969 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6970 if (PyErr_Occurred()) {
6971 Py_DECREF(result);
6972 return NULL;
6973 }
6974
6975 return result;
6976}
Larry Hastings2f936352014-08-05 14:04:04 +10006977#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006978
Larry Hastings2f936352014-08-05 14:04:04 +10006979
6980#if defined(HAVE_WAITPID)
6981/*[clinic input]
6982os.waitpid
6983 pid: pid_t
6984 options: int
6985 /
6986
6987Wait for completion of a given child process.
6988
6989Returns a tuple of information regarding the child process:
6990 (pid, status)
6991
6992The options argument is ignored on Windows.
6993[clinic start generated code]*/
6994
Larry Hastings2f936352014-08-05 14:04:04 +10006995static PyObject *
6996os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006997/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006998{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006999 pid_t res;
7000 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007001 WAIT_TYPE status;
7002 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007003
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007004 do {
7005 Py_BEGIN_ALLOW_THREADS
7006 res = waitpid(pid, &status, options);
7007 Py_END_ALLOW_THREADS
7008 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7009 if (res < 0)
7010 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007011
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007012 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007013}
Tim Petersab034fa2002-02-01 11:27:43 +00007014#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007015/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007016/*[clinic input]
7017os.waitpid
7018 pid: Py_intptr_t
7019 options: int
7020 /
7021
7022Wait for completion of a given process.
7023
7024Returns a tuple of information regarding the process:
7025 (pid, status << 8)
7026
7027The options argument is ignored on Windows.
7028[clinic start generated code]*/
7029
Larry Hastings2f936352014-08-05 14:04:04 +10007030static PyObject *
7031os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007032/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007033{
7034 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007035 Py_intptr_t res;
7036 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007037
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007038 do {
7039 Py_BEGIN_ALLOW_THREADS
7040 res = _cwait(&status, pid, options);
7041 Py_END_ALLOW_THREADS
7042 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007043 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007044 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007045
Victor Stinner8c62be82010-05-06 00:08:46 +00007046 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007047 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007048}
Larry Hastings2f936352014-08-05 14:04:04 +10007049#endif
7050
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007051
Guido van Rossumad0ee831995-03-01 10:34:45 +00007052#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007053/*[clinic input]
7054os.wait
7055
7056Wait for completion of a child process.
7057
7058Returns a tuple of information about the child process:
7059 (pid, status)
7060[clinic start generated code]*/
7061
Larry Hastings2f936352014-08-05 14:04:04 +10007062static PyObject *
7063os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007064/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007065{
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007067 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007068 WAIT_TYPE status;
7069 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007070
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007071 do {
7072 Py_BEGIN_ALLOW_THREADS
7073 pid = wait(&status);
7074 Py_END_ALLOW_THREADS
7075 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7076 if (pid < 0)
7077 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007078
Victor Stinner8c62be82010-05-06 00:08:46 +00007079 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007080}
Larry Hastings2f936352014-08-05 14:04:04 +10007081#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007082
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007083
Larry Hastings9cf065c2012-06-22 16:30:09 -07007084#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7085PyDoc_STRVAR(readlink__doc__,
7086"readlink(path, *, dir_fd=None) -> path\n\n\
7087Return a string representing the path to which the symbolic link points.\n\
7088\n\
7089If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7090 and path should be relative; path will then be relative to that directory.\n\
7091dir_fd may not be implemented on your platform.\n\
7092 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007093#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007094
Guido van Rossumb6775db1994-08-01 11:34:53 +00007095#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007096
Larry Hastings2f936352014-08-05 14:04:04 +10007097/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007098static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007100{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101 path_t path;
7102 int dir_fd = DEFAULT_DIR_FD;
7103 char buffer[MAXPATHLEN];
7104 ssize_t length;
7105 PyObject *return_value = NULL;
7106 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007107
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007109 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007110 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7111 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007112 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007113 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007114
Victor Stinner8c62be82010-05-06 00:08:46 +00007115 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116#ifdef HAVE_READLINKAT
7117 if (dir_fd != DEFAULT_DIR_FD)
7118 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007119 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120#endif
7121 length = readlink(path.narrow, buffer, sizeof(buffer));
7122 Py_END_ALLOW_THREADS
7123
7124 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007125 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126 goto exit;
7127 }
7128
7129 if (PyUnicode_Check(path.object))
7130 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7131 else
7132 return_value = PyBytes_FromStringAndSize(buffer, length);
7133exit:
7134 path_cleanup(&path);
7135 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007136}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007137
Guido van Rossumb6775db1994-08-01 11:34:53 +00007138#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007139
Larry Hastings2f936352014-08-05 14:04:04 +10007140#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7141
7142static PyObject *
7143win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7144{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007145 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007146 DWORD n_bytes_returned;
7147 DWORD io_result;
7148 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007149 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007150 HANDLE reparse_point_handle;
7151
7152 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7153 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007154 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007155
7156 static char *keywords[] = {"path", "dir_fd", NULL};
7157
7158 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7159 &po,
7160 dir_fd_unavailable, &dir_fd
7161 ))
7162 return NULL;
7163
7164 path = PyUnicode_AsUnicode(po);
7165 if (path == NULL)
7166 return NULL;
7167
7168 /* First get a handle to the reparse point */
7169 Py_BEGIN_ALLOW_THREADS
7170 reparse_point_handle = CreateFileW(
7171 path,
7172 0,
7173 0,
7174 0,
7175 OPEN_EXISTING,
7176 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7177 0);
7178 Py_END_ALLOW_THREADS
7179
7180 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7181 return win32_error_object("readlink", po);
7182
7183 Py_BEGIN_ALLOW_THREADS
7184 /* New call DeviceIoControl to read the reparse point */
7185 io_result = DeviceIoControl(
7186 reparse_point_handle,
7187 FSCTL_GET_REPARSE_POINT,
7188 0, 0, /* in buffer */
7189 target_buffer, sizeof(target_buffer),
7190 &n_bytes_returned,
7191 0 /* we're not using OVERLAPPED_IO */
7192 );
7193 CloseHandle(reparse_point_handle);
7194 Py_END_ALLOW_THREADS
7195
7196 if (io_result==0)
7197 return win32_error_object("readlink", po);
7198
7199 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7200 {
7201 PyErr_SetString(PyExc_ValueError,
7202 "not a symbolic link");
7203 return NULL;
7204 }
7205 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7206 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7207
7208 result = PyUnicode_FromWideChar(print_name,
7209 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7210 return result;
7211}
7212
7213#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7214
7215
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007216
Larry Hastings9cf065c2012-06-22 16:30:09 -07007217#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007218
7219#if defined(MS_WINDOWS)
7220
7221/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007222static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
7223static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPCSTR, LPCSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007224
Larry Hastings9cf065c2012-06-22 16:30:09 -07007225static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007226check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007227{
7228 HINSTANCE hKernel32;
7229 /* only recheck */
7230 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7231 return 1;
7232 hKernel32 = GetModuleHandleW(L"KERNEL32");
7233 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7234 "CreateSymbolicLinkW");
7235 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7236 "CreateSymbolicLinkA");
7237 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7238}
7239
Victor Stinner31b3b922013-06-05 01:49:17 +02007240/* Remove the last portion of the path */
7241static void
7242_dirnameW(WCHAR *path)
7243{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007244 WCHAR *ptr;
7245
7246 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007247 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007248 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007249 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007250 }
7251 *ptr = 0;
7252}
7253
Victor Stinner31b3b922013-06-05 01:49:17 +02007254/* Remove the last portion of the path */
7255static void
7256_dirnameA(char *path)
7257{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007258 char *ptr;
7259
7260 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007261 for(ptr = path + strlen(path); ptr != path; ptr--) {
7262 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007263 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007264 }
7265 *ptr = 0;
7266}
7267
Victor Stinner31b3b922013-06-05 01:49:17 +02007268/* Is this path absolute? */
7269static int
7270_is_absW(const WCHAR *path)
7271{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007272 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7273
7274}
7275
Victor Stinner31b3b922013-06-05 01:49:17 +02007276/* Is this path absolute? */
7277static int
7278_is_absA(const char *path)
7279{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007280 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7281
7282}
7283
Victor Stinner31b3b922013-06-05 01:49:17 +02007284/* join root and rest with a backslash */
7285static void
7286_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7287{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007288 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289
Victor Stinner31b3b922013-06-05 01:49:17 +02007290 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291 wcscpy(dest_path, rest);
7292 return;
7293 }
7294
7295 root_len = wcslen(root);
7296
7297 wcscpy(dest_path, root);
7298 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007299 dest_path[root_len] = L'\\';
7300 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007301 }
7302 wcscpy(dest_path+root_len, rest);
7303}
7304
Victor Stinner31b3b922013-06-05 01:49:17 +02007305/* join root and rest with a backslash */
7306static void
7307_joinA(char *dest_path, const char *root, const char *rest)
7308{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007309 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007310
Victor Stinner31b3b922013-06-05 01:49:17 +02007311 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007312 strcpy(dest_path, rest);
7313 return;
7314 }
7315
7316 root_len = strlen(root);
7317
7318 strcpy(dest_path, root);
7319 if(root_len) {
7320 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007321 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007322 }
7323 strcpy(dest_path+root_len, rest);
7324}
7325
Victor Stinner31b3b922013-06-05 01:49:17 +02007326/* Return True if the path at src relative to dest is a directory */
7327static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007328_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007329{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007330 WIN32_FILE_ATTRIBUTE_DATA src_info;
7331 WCHAR dest_parent[MAX_PATH];
7332 WCHAR src_resolved[MAX_PATH] = L"";
7333
7334 /* dest_parent = os.path.dirname(dest) */
7335 wcscpy(dest_parent, dest);
7336 _dirnameW(dest_parent);
7337 /* src_resolved = os.path.join(dest_parent, src) */
7338 _joinW(src_resolved, dest_parent, src);
7339 return (
7340 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7341 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7342 );
7343}
7344
Victor Stinner31b3b922013-06-05 01:49:17 +02007345/* Return True if the path at src relative to dest is a directory */
7346static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007347_check_dirA(LPCSTR src, LPCSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007348{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007349 WIN32_FILE_ATTRIBUTE_DATA src_info;
7350 char dest_parent[MAX_PATH];
7351 char src_resolved[MAX_PATH] = "";
7352
7353 /* dest_parent = os.path.dirname(dest) */
7354 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007355 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007356 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007357 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007358 return (
7359 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7360 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7361 );
7362}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007363#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007364
Larry Hastings2f936352014-08-05 14:04:04 +10007365
7366/*[clinic input]
7367os.symlink
7368 src: path_t
7369 dst: path_t
7370 target_is_directory: bool = False
7371 *
7372 dir_fd: dir_fd(requires='symlinkat')=None
7373
7374# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7375
7376Create a symbolic link pointing to src named dst.
7377
7378target_is_directory is required on Windows if the target is to be
7379 interpreted as a directory. (On Windows, symlink requires
7380 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7381 target_is_directory is ignored on non-Windows platforms.
7382
7383If dir_fd is not None, it should be a file descriptor open to a directory,
7384 and path should be relative; path will then be relative to that directory.
7385dir_fd may not be implemented on your platform.
7386 If it is unavailable, using it will raise a NotImplementedError.
7387
7388[clinic start generated code]*/
7389
Larry Hastings2f936352014-08-05 14:04:04 +10007390static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04007391os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst,
7392 int target_is_directory, int dir_fd)
7393/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007394{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395#ifdef MS_WINDOWS
7396 DWORD result;
7397#else
7398 int result;
7399#endif
7400
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401#ifdef MS_WINDOWS
7402 if (!check_CreateSymbolicLink()) {
7403 PyErr_SetString(PyExc_NotImplementedError,
7404 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007405 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007406 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407 if (!win32_can_symlink) {
7408 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007409 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007410 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007411#endif
7412
Larry Hastings2f936352014-08-05 14:04:04 +10007413 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007414 PyErr_SetString(PyExc_ValueError,
7415 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007416 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417 }
7418
7419#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007420
Larry Hastings9cf065c2012-06-22 16:30:09 -07007421 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007422 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007423 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007424 target_is_directory |= _check_dirW(src->wide, dst->wide);
7425 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007426 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007427 }
7428 else {
7429 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007430 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7431 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007432 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007433 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434 Py_END_ALLOW_THREADS
7435
Larry Hastings2f936352014-08-05 14:04:04 +10007436 if (!result)
7437 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438
7439#else
7440
7441 Py_BEGIN_ALLOW_THREADS
7442#if HAVE_SYMLINKAT
7443 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007444 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007445 else
7446#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007447 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007448 Py_END_ALLOW_THREADS
7449
Larry Hastings2f936352014-08-05 14:04:04 +10007450 if (result)
7451 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007452#endif
7453
Larry Hastings2f936352014-08-05 14:04:04 +10007454 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007455}
7456#endif /* HAVE_SYMLINK */
7457
Larry Hastings9cf065c2012-06-22 16:30:09 -07007458
Brian Curtind40e6f72010-07-08 21:39:08 +00007459
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007460
Larry Hastings605a62d2012-06-24 04:33:36 -07007461static PyStructSequence_Field times_result_fields[] = {
7462 {"user", "user time"},
7463 {"system", "system time"},
7464 {"children_user", "user time of children"},
7465 {"children_system", "system time of children"},
7466 {"elapsed", "elapsed time since an arbitrary point in the past"},
7467 {NULL}
7468};
7469
7470PyDoc_STRVAR(times_result__doc__,
7471"times_result: Result from os.times().\n\n\
7472This object may be accessed either as a tuple of\n\
7473 (user, system, children_user, children_system, elapsed),\n\
7474or via the attributes user, system, children_user, children_system,\n\
7475and elapsed.\n\
7476\n\
7477See os.times for more information.");
7478
7479static PyStructSequence_Desc times_result_desc = {
7480 "times_result", /* name */
7481 times_result__doc__, /* doc */
7482 times_result_fields,
7483 5
7484};
7485
7486static PyTypeObject TimesResultType;
7487
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007488#ifdef MS_WINDOWS
7489#define HAVE_TIMES /* mandatory, for the method table */
7490#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007491
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007492#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007493
7494static PyObject *
7495build_times_result(double user, double system,
7496 double children_user, double children_system,
7497 double elapsed)
7498{
7499 PyObject *value = PyStructSequence_New(&TimesResultType);
7500 if (value == NULL)
7501 return NULL;
7502
7503#define SET(i, field) \
7504 { \
7505 PyObject *o = PyFloat_FromDouble(field); \
7506 if (!o) { \
7507 Py_DECREF(value); \
7508 return NULL; \
7509 } \
7510 PyStructSequence_SET_ITEM(value, i, o); \
7511 } \
7512
7513 SET(0, user);
7514 SET(1, system);
7515 SET(2, children_user);
7516 SET(3, children_system);
7517 SET(4, elapsed);
7518
7519#undef SET
7520
7521 return value;
7522}
7523
Larry Hastings605a62d2012-06-24 04:33:36 -07007524
Larry Hastings2f936352014-08-05 14:04:04 +10007525#ifndef MS_WINDOWS
7526#define NEED_TICKS_PER_SECOND
7527static long ticks_per_second = -1;
7528#endif /* MS_WINDOWS */
7529
7530/*[clinic input]
7531os.times
7532
7533Return a collection containing process timing information.
7534
7535The object returned behaves like a named tuple with these fields:
7536 (utime, stime, cutime, cstime, elapsed_time)
7537All fields are floating point numbers.
7538[clinic start generated code]*/
7539
Larry Hastings2f936352014-08-05 14:04:04 +10007540static PyObject *
7541os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007542/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007543#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007544{
Victor Stinner8c62be82010-05-06 00:08:46 +00007545 FILETIME create, exit, kernel, user;
7546 HANDLE hProc;
7547 hProc = GetCurrentProcess();
7548 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7549 /* The fields of a FILETIME structure are the hi and lo part
7550 of a 64-bit value expressed in 100 nanosecond units.
7551 1e7 is one second in such units; 1e-7 the inverse.
7552 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7553 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007554 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007555 (double)(user.dwHighDateTime*429.4967296 +
7556 user.dwLowDateTime*1e-7),
7557 (double)(kernel.dwHighDateTime*429.4967296 +
7558 kernel.dwLowDateTime*1e-7),
7559 (double)0,
7560 (double)0,
7561 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007562}
Larry Hastings2f936352014-08-05 14:04:04 +10007563#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007564{
Larry Hastings2f936352014-08-05 14:04:04 +10007565
7566
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007567 struct tms t;
7568 clock_t c;
7569 errno = 0;
7570 c = times(&t);
7571 if (c == (clock_t) -1)
7572 return posix_error();
7573 return build_times_result(
7574 (double)t.tms_utime / ticks_per_second,
7575 (double)t.tms_stime / ticks_per_second,
7576 (double)t.tms_cutime / ticks_per_second,
7577 (double)t.tms_cstime / ticks_per_second,
7578 (double)c / ticks_per_second);
7579}
Larry Hastings2f936352014-08-05 14:04:04 +10007580#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007581#endif /* HAVE_TIMES */
7582
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007583
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007584#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007585/*[clinic input]
7586os.getsid
7587
7588 pid: pid_t
7589 /
7590
7591Call the system call getsid(pid) and return the result.
7592[clinic start generated code]*/
7593
Larry Hastings2f936352014-08-05 14:04:04 +10007594static PyObject *
7595os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007596/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007597{
Victor Stinner8c62be82010-05-06 00:08:46 +00007598 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 sid = getsid(pid);
7600 if (sid < 0)
7601 return posix_error();
7602 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007603}
7604#endif /* HAVE_GETSID */
7605
7606
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007608/*[clinic input]
7609os.setsid
7610
7611Call the system call setsid().
7612[clinic start generated code]*/
7613
Larry Hastings2f936352014-08-05 14:04:04 +10007614static PyObject *
7615os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007616/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007617{
Victor Stinner8c62be82010-05-06 00:08:46 +00007618 if (setsid() < 0)
7619 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007620 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007621}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007622#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007623
Larry Hastings2f936352014-08-05 14:04:04 +10007624
Guido van Rossumb6775db1994-08-01 11:34:53 +00007625#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007626/*[clinic input]
7627os.setpgid
7628
7629 pid: pid_t
7630 pgrp: pid_t
7631 /
7632
7633Call the system call setpgid(pid, pgrp).
7634[clinic start generated code]*/
7635
Larry Hastings2f936352014-08-05 14:04:04 +10007636static PyObject *
7637os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007638/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007639{
Victor Stinner8c62be82010-05-06 00:08:46 +00007640 if (setpgid(pid, pgrp) < 0)
7641 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007642 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007643}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007644#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007645
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007646
Guido van Rossumb6775db1994-08-01 11:34:53 +00007647#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007648/*[clinic input]
7649os.tcgetpgrp
7650
7651 fd: int
7652 /
7653
7654Return the process group associated with the terminal specified by fd.
7655[clinic start generated code]*/
7656
Larry Hastings2f936352014-08-05 14:04:04 +10007657static PyObject *
7658os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007659/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007660{
7661 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007662 if (pgid < 0)
7663 return posix_error();
7664 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007665}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007666#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007667
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007668
Guido van Rossumb6775db1994-08-01 11:34:53 +00007669#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007670/*[clinic input]
7671os.tcsetpgrp
7672
7673 fd: int
7674 pgid: pid_t
7675 /
7676
7677Set the process group associated with the terminal specified by fd.
7678[clinic start generated code]*/
7679
Larry Hastings2f936352014-08-05 14:04:04 +10007680static PyObject *
7681os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007682/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007683{
Victor Stinner8c62be82010-05-06 00:08:46 +00007684 if (tcsetpgrp(fd, pgid) < 0)
7685 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007686 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007687}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007688#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007689
Guido van Rossum687dd131993-05-17 08:34:16 +00007690/* Functions acting on file descriptors */
7691
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692#ifdef O_CLOEXEC
7693extern int _Py_open_cloexec_works;
7694#endif
7695
Larry Hastings2f936352014-08-05 14:04:04 +10007696
7697/*[clinic input]
7698os.open -> int
7699 path: path_t
7700 flags: int
7701 mode: int = 0o777
7702 *
7703 dir_fd: dir_fd(requires='openat') = None
7704
7705# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7706
7707Open a file for low level IO. Returns a file descriptor (integer).
7708
7709If dir_fd is not None, it should be a file descriptor open to a directory,
7710 and path should be relative; path will then be relative to that directory.
7711dir_fd may not be implemented on your platform.
7712 If it is unavailable, using it will raise a NotImplementedError.
7713[clinic start generated code]*/
7714
Larry Hastings2f936352014-08-05 14:04:04 +10007715static int
Larry Hastings89964c42015-04-14 18:07:59 -04007716os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode,
7717 int dir_fd)
7718/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007719{
7720 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007721 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007722
Victor Stinnerdaf45552013-08-28 00:53:59 +02007723#ifdef O_CLOEXEC
7724 int *atomic_flag_works = &_Py_open_cloexec_works;
7725#elif !defined(MS_WINDOWS)
7726 int *atomic_flag_works = NULL;
7727#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007728
Victor Stinnerdaf45552013-08-28 00:53:59 +02007729#ifdef MS_WINDOWS
7730 flags |= O_NOINHERIT;
7731#elif defined(O_CLOEXEC)
7732 flags |= O_CLOEXEC;
7733#endif
7734
Steve Dower8fc89802015-04-12 00:26:27 -04007735 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007736 do {
7737 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007739 if (path->wide)
7740 fd = _wopen(path->wide, flags, mode);
7741 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007742#endif
7743#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007744 if (dir_fd != DEFAULT_DIR_FD)
7745 fd = openat(dir_fd, path->narrow, flags, mode);
7746 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007747#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007748 fd = open(path->narrow, flags, mode);
7749 Py_END_ALLOW_THREADS
7750 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007751 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007752
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007753 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007754 if (!async_err)
7755 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007756 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007757 }
7758
Victor Stinnerdaf45552013-08-28 00:53:59 +02007759#ifndef MS_WINDOWS
7760 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7761 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007762 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007763 }
7764#endif
7765
Larry Hastings2f936352014-08-05 14:04:04 +10007766 return fd;
7767}
7768
7769
7770/*[clinic input]
7771os.close
7772
7773 fd: int
7774
7775Close a file descriptor.
7776[clinic start generated code]*/
7777
Barry Warsaw53699e91996-12-10 23:23:01 +00007778static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007779os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007780/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007781{
Larry Hastings2f936352014-08-05 14:04:04 +10007782 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007783 if (!_PyVerify_fd(fd))
7784 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007785 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7786 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7787 * for more details.
7788 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007790 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007791 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007792 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 Py_END_ALLOW_THREADS
7794 if (res < 0)
7795 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007796 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007797}
7798
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007799
Larry Hastings2f936352014-08-05 14:04:04 +10007800/*[clinic input]
7801os.closerange
7802
7803 fd_low: int
7804 fd_high: int
7805 /
7806
7807Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7808[clinic start generated code]*/
7809
Larry Hastings2f936352014-08-05 14:04:04 +10007810static PyObject *
7811os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007812/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007813{
7814 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007816 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007817 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 if (_PyVerify_fd(i))
7819 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007820 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007821 Py_END_ALLOW_THREADS
7822 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007823}
7824
7825
Larry Hastings2f936352014-08-05 14:04:04 +10007826/*[clinic input]
7827os.dup -> int
7828
7829 fd: int
7830 /
7831
7832Return a duplicate of a file descriptor.
7833[clinic start generated code]*/
7834
Larry Hastings2f936352014-08-05 14:04:04 +10007835static int
7836os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007837/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007838{
7839 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007840}
7841
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007842
Larry Hastings2f936352014-08-05 14:04:04 +10007843/*[clinic input]
7844os.dup2
7845 fd: int
7846 fd2: int
7847 inheritable: bool=True
7848
7849Duplicate file descriptor.
7850[clinic start generated code]*/
7851
Larry Hastings2f936352014-08-05 14:04:04 +10007852static PyObject *
7853os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007854/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007855{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856 int res;
7857#if defined(HAVE_DUP3) && \
7858 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7859 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7860 int dup3_works = -1;
7861#endif
7862
Victor Stinner8c62be82010-05-06 00:08:46 +00007863 if (!_PyVerify_fd_dup2(fd, fd2))
7864 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007865
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007866 /* dup2() can fail with EINTR if the target FD is already open, because it
7867 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7868 * upon close(), and therefore below.
7869 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007870#ifdef MS_WINDOWS
7871 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007872 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007874 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007876 if (res < 0)
7877 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007878
7879 /* Character files like console cannot be make non-inheritable */
7880 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7881 close(fd2);
7882 return NULL;
7883 }
7884
7885#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7886 Py_BEGIN_ALLOW_THREADS
7887 if (!inheritable)
7888 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7889 else
7890 res = dup2(fd, fd2);
7891 Py_END_ALLOW_THREADS
7892 if (res < 0)
7893 return posix_error();
7894
7895#else
7896
7897#ifdef HAVE_DUP3
7898 if (!inheritable && dup3_works != 0) {
7899 Py_BEGIN_ALLOW_THREADS
7900 res = dup3(fd, fd2, O_CLOEXEC);
7901 Py_END_ALLOW_THREADS
7902 if (res < 0) {
7903 if (dup3_works == -1)
7904 dup3_works = (errno != ENOSYS);
7905 if (dup3_works)
7906 return posix_error();
7907 }
7908 }
7909
7910 if (inheritable || dup3_works == 0)
7911 {
7912#endif
7913 Py_BEGIN_ALLOW_THREADS
7914 res = dup2(fd, fd2);
7915 Py_END_ALLOW_THREADS
7916 if (res < 0)
7917 return posix_error();
7918
7919 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7920 close(fd2);
7921 return NULL;
7922 }
7923#ifdef HAVE_DUP3
7924 }
7925#endif
7926
7927#endif
7928
Larry Hastings2f936352014-08-05 14:04:04 +10007929 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007930}
7931
Larry Hastings2f936352014-08-05 14:04:04 +10007932
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007934/*[clinic input]
7935os.lockf
7936
7937 fd: int
7938 An open file descriptor.
7939 command: int
7940 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7941 length: Py_off_t
7942 The number of bytes to lock, starting at the current position.
7943 /
7944
7945Apply, test or remove a POSIX lock on an open file descriptor.
7946
7947[clinic start generated code]*/
7948
Larry Hastings2f936352014-08-05 14:04:04 +10007949static PyObject *
7950os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007951/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007952{
7953 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007954
7955 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007956 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007957 Py_END_ALLOW_THREADS
7958
7959 if (res < 0)
7960 return posix_error();
7961
7962 Py_RETURN_NONE;
7963}
Larry Hastings2f936352014-08-05 14:04:04 +10007964#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007965
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007966
Larry Hastings2f936352014-08-05 14:04:04 +10007967/*[clinic input]
7968os.lseek -> Py_off_t
7969
7970 fd: int
7971 position: Py_off_t
7972 how: int
7973 /
7974
7975Set the position of a file descriptor. Return the new position.
7976
7977Return the new cursor position in number of bytes
7978relative to the beginning of the file.
7979[clinic start generated code]*/
7980
Larry Hastings2f936352014-08-05 14:04:04 +10007981static Py_off_t
7982os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007983/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007984{
7985 Py_off_t result;
7986
7987 if (!_PyVerify_fd(fd)) {
7988 posix_error();
7989 return -1;
7990 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007991#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007992 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7993 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007994 case 0: how = SEEK_SET; break;
7995 case 1: how = SEEK_CUR; break;
7996 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007998#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007999
Victor Stinner8c62be82010-05-06 00:08:46 +00008000 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008001 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008002
Larry Hastings2f936352014-08-05 14:04:04 +10008003 if (!_PyVerify_fd(fd)) {
8004 posix_error();
8005 return -1;
8006 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008008 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008009#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008010 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008011#else
Larry Hastings2f936352014-08-05 14:04:04 +10008012 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008013#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008014 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008015 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008016 if (result < 0)
8017 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008018
Larry Hastings2f936352014-08-05 14:04:04 +10008019 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008020}
8021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008022
Larry Hastings2f936352014-08-05 14:04:04 +10008023/*[clinic input]
8024os.read
8025 fd: int
8026 length: Py_ssize_t
8027 /
8028
8029Read from a file descriptor. Returns a bytes object.
8030[clinic start generated code]*/
8031
Larry Hastings2f936352014-08-05 14:04:04 +10008032static PyObject *
8033os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008034/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008035{
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 Py_ssize_t n;
8037 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008038
8039 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 errno = EINVAL;
8041 return posix_error();
8042 }
Larry Hastings2f936352014-08-05 14:04:04 +10008043
8044#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008045 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008046 if (length > INT_MAX)
8047 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008048#endif
8049
8050 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008051 if (buffer == NULL)
8052 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008053
Victor Stinner66aab0c2015-03-19 22:53:20 +01008054 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8055 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008056 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008057 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 }
Larry Hastings2f936352014-08-05 14:04:04 +10008059
8060 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008062
Victor Stinner8c62be82010-05-06 00:08:46 +00008063 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008064}
8065
Ross Lagerwall7807c352011-03-17 20:20:30 +02008066#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8067 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008068static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008069iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8070{
8071 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008072 Py_ssize_t blen, total = 0;
8073
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074 *iov = PyMem_New(struct iovec, cnt);
8075 if (*iov == NULL) {
8076 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008077 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008079
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 *buf = PyMem_New(Py_buffer, cnt);
8081 if (*buf == NULL) {
8082 PyMem_Del(*iov);
8083 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008084 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008085 }
8086
8087 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008088 PyObject *item = PySequence_GetItem(seq, i);
8089 if (item == NULL)
8090 goto fail;
8091 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8092 Py_DECREF(item);
8093 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008094 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008095 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008096 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008097 blen = (*buf)[i].len;
8098 (*iov)[i].iov_len = blen;
8099 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008100 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008101 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008102
8103fail:
8104 PyMem_Del(*iov);
8105 for (j = 0; j < i; j++) {
8106 PyBuffer_Release(&(*buf)[j]);
8107 }
8108 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008109 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110}
8111
8112static void
8113iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8114{
8115 int i;
8116 PyMem_Del(iov);
8117 for (i = 0; i < cnt; i++) {
8118 PyBuffer_Release(&buf[i]);
8119 }
8120 PyMem_Del(buf);
8121}
8122#endif
8123
Larry Hastings2f936352014-08-05 14:04:04 +10008124
Ross Lagerwall7807c352011-03-17 20:20:30 +02008125#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008126/*[clinic input]
8127os.readv -> Py_ssize_t
8128
8129 fd: int
8130 buffers: object
8131 /
8132
8133Read from a file descriptor fd into an iterable of buffers.
8134
8135The buffers should be mutable buffers accepting bytes.
8136readv will transfer data into each buffer until it is full
8137and then move on to the next buffer in the sequence to hold
8138the rest of the data.
8139
8140readv returns the total number of bytes read,
8141which may be less than the total capacity of all the buffers.
8142[clinic start generated code]*/
8143
Larry Hastings2f936352014-08-05 14:04:04 +10008144static Py_ssize_t
8145os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008146/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008147{
8148 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008150 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151 struct iovec *iov;
8152 Py_buffer *buf;
8153
Larry Hastings2f936352014-08-05 14:04:04 +10008154 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008155 PyErr_SetString(PyExc_TypeError,
8156 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008157 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008158 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159
Larry Hastings2f936352014-08-05 14:04:04 +10008160 cnt = PySequence_Size(buffers);
8161
8162 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8163 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008164
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008165 do {
8166 Py_BEGIN_ALLOW_THREADS
8167 n = readv(fd, iov, cnt);
8168 Py_END_ALLOW_THREADS
8169 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008170
8171 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008172 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008173 if (!async_err)
8174 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008175 return -1;
8176 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008177
Larry Hastings2f936352014-08-05 14:04:04 +10008178 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008179}
Larry Hastings2f936352014-08-05 14:04:04 +10008180#endif /* HAVE_READV */
8181
Ross Lagerwall7807c352011-03-17 20:20:30 +02008182
8183#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008184/*[clinic input]
8185# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8186os.pread
8187
8188 fd: int
8189 length: int
8190 offset: Py_off_t
8191 /
8192
8193Read a number of bytes from a file descriptor starting at a particular offset.
8194
8195Read length bytes from file descriptor fd, starting at offset bytes from
8196the beginning of the file. The file offset remains unchanged.
8197[clinic start generated code]*/
8198
Larry Hastings2f936352014-08-05 14:04:04 +10008199static PyObject *
8200os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008201/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008202{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008203 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008204 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008205 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008206
Larry Hastings2f936352014-08-05 14:04:04 +10008207 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208 errno = EINVAL;
8209 return posix_error();
8210 }
Larry Hastings2f936352014-08-05 14:04:04 +10008211 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008212 if (buffer == NULL)
8213 return NULL;
8214 if (!_PyVerify_fd(fd)) {
8215 Py_DECREF(buffer);
8216 return posix_error();
8217 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008218
8219 do {
8220 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008221 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008222 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008223 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008224 Py_END_ALLOW_THREADS
8225 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8226
Ross Lagerwall7807c352011-03-17 20:20:30 +02008227 if (n < 0) {
8228 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008229 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008230 }
Larry Hastings2f936352014-08-05 14:04:04 +10008231 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008232 _PyBytes_Resize(&buffer, n);
8233 return buffer;
8234}
Larry Hastings2f936352014-08-05 14:04:04 +10008235#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008236
Larry Hastings2f936352014-08-05 14:04:04 +10008237
8238/*[clinic input]
8239os.write -> Py_ssize_t
8240
8241 fd: int
8242 data: Py_buffer
8243 /
8244
8245Write a bytes object to a file descriptor.
8246[clinic start generated code]*/
8247
Larry Hastings2f936352014-08-05 14:04:04 +10008248static Py_ssize_t
8249os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008250/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008251{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008252 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008253}
8254
8255#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008256PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008257"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008258sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008259 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008260Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008261
Larry Hastings2f936352014-08-05 14:04:04 +10008262/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008263static PyObject *
8264posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8265{
8266 int in, out;
8267 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008268 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008269 off_t offset;
8270
8271#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8272#ifndef __APPLE__
8273 Py_ssize_t len;
8274#endif
8275 PyObject *headers = NULL, *trailers = NULL;
8276 Py_buffer *hbuf, *tbuf;
8277 off_t sbytes;
8278 struct sf_hdtr sf;
8279 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008280 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008281 static char *keywords[] = {"out", "in",
8282 "offset", "count",
8283 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008284
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008285 sf.headers = NULL;
8286 sf.trailers = NULL;
8287
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008288#ifdef __APPLE__
8289 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008290 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008291#else
8292 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008293 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008294#endif
8295 &headers, &trailers, &flags))
8296 return NULL;
8297 if (headers != NULL) {
8298 if (!PySequence_Check(headers)) {
8299 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008300 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008301 return NULL;
8302 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008303 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008305 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008306 (i = iov_setup(&(sf.headers), &hbuf,
8307 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008309#ifdef __APPLE__
8310 sbytes += i;
8311#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008312 }
8313 }
8314 if (trailers != NULL) {
8315 if (!PySequence_Check(trailers)) {
8316 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008317 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318 return NULL;
8319 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008320 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008322 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008323 (i = iov_setup(&(sf.trailers), &tbuf,
8324 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008326#ifdef __APPLE__
8327 sbytes += i;
8328#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329 }
8330 }
8331
Steve Dower8fc89802015-04-12 00:26:27 -04008332 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008333 do {
8334 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008336 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008337#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008338 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008339#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008340 Py_END_ALLOW_THREADS
8341 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008342 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008343
8344 if (sf.headers != NULL)
8345 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8346 if (sf.trailers != NULL)
8347 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8348
8349 if (ret < 0) {
8350 if ((errno == EAGAIN) || (errno == EBUSY)) {
8351 if (sbytes != 0) {
8352 // some data has been sent
8353 goto done;
8354 }
8355 else {
8356 // no data has been sent; upper application is supposed
8357 // to retry on EAGAIN or EBUSY
8358 return posix_error();
8359 }
8360 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008361 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008362 }
8363 goto done;
8364
8365done:
8366 #if !defined(HAVE_LARGEFILE_SUPPORT)
8367 return Py_BuildValue("l", sbytes);
8368 #else
8369 return Py_BuildValue("L", sbytes);
8370 #endif
8371
8372#else
8373 Py_ssize_t count;
8374 PyObject *offobj;
8375 static char *keywords[] = {"out", "in",
8376 "offset", "count", NULL};
8377 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8378 keywords, &out, &in, &offobj, &count))
8379 return NULL;
8380#ifdef linux
8381 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008382 do {
8383 Py_BEGIN_ALLOW_THREADS
8384 ret = sendfile(out, in, NULL, count);
8385 Py_END_ALLOW_THREADS
8386 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008387 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008388 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008389 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008390 }
8391#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008392 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008393 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008394
8395 do {
8396 Py_BEGIN_ALLOW_THREADS
8397 ret = sendfile(out, in, &offset, count);
8398 Py_END_ALLOW_THREADS
8399 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008400 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008401 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008402 return Py_BuildValue("n", ret);
8403#endif
8404}
Larry Hastings2f936352014-08-05 14:04:04 +10008405#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008406
Larry Hastings2f936352014-08-05 14:04:04 +10008407
8408/*[clinic input]
8409os.fstat
8410
8411 fd : int
8412
8413Perform a stat system call on the given file descriptor.
8414
8415Like stat(), but for an open file descriptor.
8416Equivalent to os.stat(fd).
8417[clinic start generated code]*/
8418
Larry Hastings2f936352014-08-05 14:04:04 +10008419static PyObject *
8420os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008421/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008422{
Victor Stinner8c62be82010-05-06 00:08:46 +00008423 STRUCT_STAT st;
8424 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008425 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008426
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008427 do {
8428 Py_BEGIN_ALLOW_THREADS
8429 res = FSTAT(fd, &st);
8430 Py_END_ALLOW_THREADS
8431 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008432 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008433#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008434 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008435#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008436 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008437#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008438 }
Tim Peters5aa91602002-01-30 05:46:57 +00008439
Victor Stinner4195b5c2012-02-08 23:03:19 +01008440 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008441}
8442
Larry Hastings2f936352014-08-05 14:04:04 +10008443
8444/*[clinic input]
8445os.isatty -> bool
8446 fd: int
8447 /
8448
8449Return True if the fd is connected to a terminal.
8450
8451Return True if the file descriptor is an open file descriptor
8452connected to the slave end of a terminal.
8453[clinic start generated code]*/
8454
Larry Hastings2f936352014-08-05 14:04:04 +10008455static int
8456os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008457/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008458{
Steve Dower8fc89802015-04-12 00:26:27 -04008459 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008460 if (!_PyVerify_fd(fd))
8461 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008462 _Py_BEGIN_SUPPRESS_IPH
8463 return_value = isatty(fd);
8464 _Py_END_SUPPRESS_IPH
8465 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008466}
8467
8468
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008469#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008470/*[clinic input]
8471os.pipe
8472
8473Create a pipe.
8474
8475Returns a tuple of two file descriptors:
8476 (read_fd, write_fd)
8477[clinic start generated code]*/
8478
Larry Hastings2f936352014-08-05 14:04:04 +10008479static PyObject *
8480os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008481/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008482{
Victor Stinner8c62be82010-05-06 00:08:46 +00008483 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008484#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008485 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008486 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008487 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008488#else
8489 int res;
8490#endif
8491
8492#ifdef MS_WINDOWS
8493 attr.nLength = sizeof(attr);
8494 attr.lpSecurityDescriptor = NULL;
8495 attr.bInheritHandle = FALSE;
8496
8497 Py_BEGIN_ALLOW_THREADS
8498 ok = CreatePipe(&read, &write, &attr, 0);
8499 if (ok) {
8500 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8501 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8502 if (fds[0] == -1 || fds[1] == -1) {
8503 CloseHandle(read);
8504 CloseHandle(write);
8505 ok = 0;
8506 }
8507 }
8508 Py_END_ALLOW_THREADS
8509
Victor Stinner8c62be82010-05-06 00:08:46 +00008510 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008511 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008512#else
8513
8514#ifdef HAVE_PIPE2
8515 Py_BEGIN_ALLOW_THREADS
8516 res = pipe2(fds, O_CLOEXEC);
8517 Py_END_ALLOW_THREADS
8518
8519 if (res != 0 && errno == ENOSYS)
8520 {
8521#endif
8522 Py_BEGIN_ALLOW_THREADS
8523 res = pipe(fds);
8524 Py_END_ALLOW_THREADS
8525
8526 if (res == 0) {
8527 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8528 close(fds[0]);
8529 close(fds[1]);
8530 return NULL;
8531 }
8532 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8533 close(fds[0]);
8534 close(fds[1]);
8535 return NULL;
8536 }
8537 }
8538#ifdef HAVE_PIPE2
8539 }
8540#endif
8541
8542 if (res != 0)
8543 return PyErr_SetFromErrno(PyExc_OSError);
8544#endif /* !MS_WINDOWS */
8545 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008546}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008547#endif /* HAVE_PIPE */
8548
Larry Hastings2f936352014-08-05 14:04:04 +10008549
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008550#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008551/*[clinic input]
8552os.pipe2
8553
8554 flags: int
8555 /
8556
8557Create a pipe with flags set atomically.
8558
8559Returns a tuple of two file descriptors:
8560 (read_fd, write_fd)
8561
8562flags can be constructed by ORing together one or more of these values:
8563O_NONBLOCK, O_CLOEXEC.
8564[clinic start generated code]*/
8565
Larry Hastings2f936352014-08-05 14:04:04 +10008566static PyObject *
8567os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008568/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008569{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008570 int fds[2];
8571 int res;
8572
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008573 res = pipe2(fds, flags);
8574 if (res != 0)
8575 return posix_error();
8576 return Py_BuildValue("(ii)", fds[0], fds[1]);
8577}
8578#endif /* HAVE_PIPE2 */
8579
Larry Hastings2f936352014-08-05 14:04:04 +10008580
Ross Lagerwall7807c352011-03-17 20:20:30 +02008581#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008582/*[clinic input]
8583os.writev -> Py_ssize_t
8584 fd: int
8585 buffers: object
8586 /
8587
8588Iterate over buffers, and write the contents of each to a file descriptor.
8589
8590Returns the total number of bytes written.
8591buffers must be a sequence of bytes-like objects.
8592[clinic start generated code]*/
8593
Larry Hastings2f936352014-08-05 14:04:04 +10008594static Py_ssize_t
8595os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008596/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008597{
8598 int cnt;
8599 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008600 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008601 struct iovec *iov;
8602 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008603
8604 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008605 PyErr_SetString(PyExc_TypeError,
8606 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008607 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008608 }
Larry Hastings2f936352014-08-05 14:04:04 +10008609 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008610
Larry Hastings2f936352014-08-05 14:04:04 +10008611 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8612 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008613 }
8614
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008615 do {
8616 Py_BEGIN_ALLOW_THREADS
8617 result = writev(fd, iov, cnt);
8618 Py_END_ALLOW_THREADS
8619 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008620
8621 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008622 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008623 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008624
Georg Brandl306336b2012-06-24 12:55:33 +02008625 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008626}
Larry Hastings2f936352014-08-05 14:04:04 +10008627#endif /* HAVE_WRITEV */
8628
8629
8630#ifdef HAVE_PWRITE
8631/*[clinic input]
8632os.pwrite -> Py_ssize_t
8633
8634 fd: int
8635 buffer: Py_buffer
8636 offset: Py_off_t
8637 /
8638
8639Write bytes to a file descriptor starting at a particular offset.
8640
8641Write buffer to fd, starting at offset bytes from the beginning of
8642the file. Returns the number of bytes writte. Does not change the
8643current file offset.
8644[clinic start generated code]*/
8645
Larry Hastings2f936352014-08-05 14:04:04 +10008646static Py_ssize_t
Larry Hastings89964c42015-04-14 18:07:59 -04008647os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
8648 Py_off_t offset)
8649/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008650{
8651 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008652 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008653
8654 if (!_PyVerify_fd(fd)) {
8655 posix_error();
8656 return -1;
8657 }
8658
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008659 do {
8660 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008661 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008662 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008663 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008664 Py_END_ALLOW_THREADS
8665 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008666
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008667 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008668 posix_error();
8669 return size;
8670}
8671#endif /* HAVE_PWRITE */
8672
8673
8674#ifdef HAVE_MKFIFO
8675/*[clinic input]
8676os.mkfifo
8677
8678 path: path_t
8679 mode: int=0o666
8680 *
8681 dir_fd: dir_fd(requires='mkfifoat')=None
8682
8683Create a "fifo" (a POSIX named pipe).
8684
8685If dir_fd is not None, it should be a file descriptor open to a directory,
8686 and path should be relative; path will then be relative to that directory.
8687dir_fd may not be implemented on your platform.
8688 If it is unavailable, using it will raise a NotImplementedError.
8689[clinic start generated code]*/
8690
Larry Hastings2f936352014-08-05 14:04:04 +10008691static PyObject *
8692os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008693/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008694{
8695 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008696 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008697
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008698 do {
8699 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008700#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008701 if (dir_fd != DEFAULT_DIR_FD)
8702 result = mkfifoat(dir_fd, path->narrow, mode);
8703 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008704#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008705 result = mkfifo(path->narrow, mode);
8706 Py_END_ALLOW_THREADS
8707 } while (result != 0 && errno == EINTR &&
8708 !(async_err = PyErr_CheckSignals()));
8709 if (result != 0)
8710 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008711
8712 Py_RETURN_NONE;
8713}
8714#endif /* HAVE_MKFIFO */
8715
8716
8717#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8718/*[clinic input]
8719os.mknod
8720
8721 path: path_t
8722 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008723 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008724 *
8725 dir_fd: dir_fd(requires='mknodat')=None
8726
8727Create a node in the file system.
8728
8729Create a node in the file system (file, device special file or named pipe)
8730at path. mode specifies both the permissions to use and the
8731type of node to be created, being combined (bitwise OR) with one of
8732S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8733device defines the newly created device special file (probably using
8734os.makedev()). Otherwise device is ignored.
8735
8736If dir_fd is not None, it should be a file descriptor open to a directory,
8737 and path should be relative; path will then be relative to that directory.
8738dir_fd may not be implemented on your platform.
8739 If it is unavailable, using it will raise a NotImplementedError.
8740[clinic start generated code]*/
8741
Larry Hastings2f936352014-08-05 14:04:04 +10008742static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008743os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
8744 int dir_fd)
8745/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008746{
8747 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008748 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008749
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008750 do {
8751 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008752#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008753 if (dir_fd != DEFAULT_DIR_FD)
8754 result = mknodat(dir_fd, path->narrow, mode, device);
8755 else
Larry Hastings2f936352014-08-05 14:04:04 +10008756#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008757 result = mknod(path->narrow, mode, device);
8758 Py_END_ALLOW_THREADS
8759 } while (result != 0 && errno == EINTR &&
8760 !(async_err = PyErr_CheckSignals()));
8761 if (result != 0)
8762 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008763
8764 Py_RETURN_NONE;
8765}
8766#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8767
8768
8769#ifdef HAVE_DEVICE_MACROS
8770/*[clinic input]
8771os.major -> unsigned_int
8772
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008773 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008774 /
8775
8776Extracts a device major number from a raw device number.
8777[clinic start generated code]*/
8778
Larry Hastings2f936352014-08-05 14:04:04 +10008779static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008780os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008781/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008782{
8783 return major(device);
8784}
8785
8786
8787/*[clinic input]
8788os.minor -> unsigned_int
8789
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008790 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008791 /
8792
8793Extracts a device minor number from a raw device number.
8794[clinic start generated code]*/
8795
Larry Hastings2f936352014-08-05 14:04:04 +10008796static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008797os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008798/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008799{
8800 return minor(device);
8801}
8802
8803
8804/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008805os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008806
8807 major: int
8808 minor: int
8809 /
8810
8811Composes a raw device number from the major and minor device numbers.
8812[clinic start generated code]*/
8813
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008814static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008815os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008816/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008817{
8818 return makedev(major, minor);
8819}
8820#endif /* HAVE_DEVICE_MACROS */
8821
8822
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008823#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008824/*[clinic input]
8825os.ftruncate
8826
8827 fd: int
8828 length: Py_off_t
8829 /
8830
8831Truncate a file, specified by file descriptor, to a specific length.
8832[clinic start generated code]*/
8833
Larry Hastings2f936352014-08-05 14:04:04 +10008834static PyObject *
8835os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008836/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008837{
8838 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008839 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008840
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008841 if (!_PyVerify_fd(fd))
8842 return posix_error();
8843
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008844 do {
8845 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008846 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008847#ifdef MS_WINDOWS
8848 result = _chsize_s(fd, length);
8849#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008850 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008851#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008852 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008853 Py_END_ALLOW_THREADS
8854 } while (result != 0 && errno == EINTR &&
8855 !(async_err = PyErr_CheckSignals()));
8856 if (result != 0)
8857 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008858 Py_RETURN_NONE;
8859}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008860#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008861
8862
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008863#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008864/*[clinic input]
8865os.truncate
8866 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8867 length: Py_off_t
8868
8869Truncate a file, specified by path, to a specific length.
8870
8871On some platforms, path may also be specified as an open file descriptor.
8872 If this functionality is unavailable, using it raises an exception.
8873[clinic start generated code]*/
8874
Larry Hastings2f936352014-08-05 14:04:04 +10008875static PyObject *
8876os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008877/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008878{
8879 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008880#ifdef MS_WINDOWS
8881 int fd;
8882#endif
8883
8884 if (path->fd != -1)
8885 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008886
8887 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008888 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008889#ifdef MS_WINDOWS
8890 if (path->wide)
8891 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008892 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008893 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008894 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008895 result = -1;
8896 else {
8897 result = _chsize_s(fd, length);
8898 close(fd);
8899 if (result < 0)
8900 errno = result;
8901 }
8902#else
8903 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008904#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008905 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008906 Py_END_ALLOW_THREADS
8907 if (result < 0)
8908 return path_error(path);
8909
8910 Py_RETURN_NONE;
8911}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008912#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008913
Ross Lagerwall7807c352011-03-17 20:20:30 +02008914
Victor Stinnerd6b17692014-09-30 12:20:05 +02008915/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8916 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8917 defined, which is the case in Python on AIX. AIX bug report:
8918 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8919#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8920# define POSIX_FADVISE_AIX_BUG
8921#endif
8922
Victor Stinnerec39e262014-09-30 12:35:58 +02008923
Victor Stinnerd6b17692014-09-30 12:20:05 +02008924#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008925/*[clinic input]
8926os.posix_fallocate
8927
8928 fd: int
8929 offset: Py_off_t
8930 length: Py_off_t
8931 /
8932
8933Ensure a file has allocated at least a particular number of bytes on disk.
8934
8935Ensure that the file specified by fd encompasses a range of bytes
8936starting at offset bytes from the beginning and continuing for length bytes.
8937[clinic start generated code]*/
8938
Larry Hastings2f936352014-08-05 14:04:04 +10008939static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008940os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset,
8941 Py_off_t length)
8942/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008943{
8944 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008945 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008946
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008947 do {
8948 Py_BEGIN_ALLOW_THREADS
8949 result = posix_fallocate(fd, offset, length);
8950 Py_END_ALLOW_THREADS
8951 } while (result != 0 && errno == EINTR &&
8952 !(async_err = PyErr_CheckSignals()));
8953 if (result != 0)
8954 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955 Py_RETURN_NONE;
8956}
Victor Stinnerec39e262014-09-30 12:35:58 +02008957#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008958
Ross Lagerwall7807c352011-03-17 20:20:30 +02008959
Victor Stinnerd6b17692014-09-30 12:20:05 +02008960#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008961/*[clinic input]
8962os.posix_fadvise
8963
8964 fd: int
8965 offset: Py_off_t
8966 length: Py_off_t
8967 advice: int
8968 /
8969
8970Announce an intention to access data in a specific pattern.
8971
8972Announce an intention to access data in a specific pattern, thus allowing
8973the kernel to make optimizations.
8974The advice applies to the region of the file specified by fd starting at
8975offset and continuing for length bytes.
8976advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8977POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8978POSIX_FADV_DONTNEED.
8979[clinic start generated code]*/
8980
Larry Hastings2f936352014-08-05 14:04:04 +10008981static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008982os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset,
8983 Py_off_t length, int advice)
8984/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008985{
8986 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008987 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008988
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008989 do {
8990 Py_BEGIN_ALLOW_THREADS
8991 result = posix_fadvise(fd, offset, length, advice);
8992 Py_END_ALLOW_THREADS
8993 } while (result != 0 && errno == EINTR &&
8994 !(async_err = PyErr_CheckSignals()));
8995 if (result != 0)
8996 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008997 Py_RETURN_NONE;
8998}
Victor Stinnerec39e262014-09-30 12:35:58 +02008999#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009000
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009001#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009002
Fred Drake762e2061999-08-26 17:23:54 +00009003/* Save putenv() parameters as values here, so we can collect them when they
9004 * get re-set with another call for the same key. */
9005static PyObject *posix_putenv_garbage;
9006
Larry Hastings2f936352014-08-05 14:04:04 +10009007static void
9008posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009009{
Larry Hastings2f936352014-08-05 14:04:04 +10009010 /* Install the first arg and newstr in posix_putenv_garbage;
9011 * this will cause previous value to be collected. This has to
9012 * happen after the real putenv() call because the old value
9013 * was still accessible until then. */
9014 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9015 /* really not much we can do; just leak */
9016 PyErr_Clear();
9017 else
9018 Py_DECREF(value);
9019}
9020
9021
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009022#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009023/*[clinic input]
9024os.putenv
9025
9026 name: unicode
9027 value: unicode
9028 /
9029
9030Change or add an environment variable.
9031[clinic start generated code]*/
9032
Larry Hastings2f936352014-08-05 14:04:04 +10009033static PyObject *
9034os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009035/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009036{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009037 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10009038
9039 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9040 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009041 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009042 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009043 }
Larry Hastings2f936352014-08-05 14:04:04 +10009044 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009045 PyErr_Format(PyExc_ValueError,
9046 "the environment variable is longer than %u characters",
9047 _MAX_ENV);
9048 goto error;
9049 }
9050
Larry Hastings2f936352014-08-05 14:04:04 +10009051 env = PyUnicode_AsUnicode(unicode);
9052 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009053 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009054 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009056 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009057 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009058
Larry Hastings2f936352014-08-05 14:04:04 +10009059 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009060 Py_RETURN_NONE;
9061
9062error:
Larry Hastings2f936352014-08-05 14:04:04 +10009063 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009064 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009065}
Larry Hastings2f936352014-08-05 14:04:04 +10009066#else /* MS_WINDOWS */
9067/*[clinic input]
9068os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009069
Larry Hastings2f936352014-08-05 14:04:04 +10009070 name: FSConverter
9071 value: FSConverter
9072 /
9073
9074Change or add an environment variable.
9075[clinic start generated code]*/
9076
Larry Hastings2f936352014-08-05 14:04:04 +10009077static PyObject *
9078os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009079/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009080{
9081 PyObject *bytes = NULL;
9082 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009083 const char *name_string = PyBytes_AsString(name);
9084 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009085
9086 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9087 if (bytes == NULL) {
9088 PyErr_NoMemory();
9089 return NULL;
9090 }
9091
9092 env = PyBytes_AS_STRING(bytes);
9093 if (putenv(env)) {
9094 Py_DECREF(bytes);
9095 return posix_error();
9096 }
9097
9098 posix_putenv_garbage_setitem(name, bytes);
9099 Py_RETURN_NONE;
9100}
9101#endif /* MS_WINDOWS */
9102#endif /* HAVE_PUTENV */
9103
9104
9105#ifdef HAVE_UNSETENV
9106/*[clinic input]
9107os.unsetenv
9108 name: FSConverter
9109 /
9110
9111Delete an environment variable.
9112[clinic start generated code]*/
9113
Larry Hastings2f936352014-08-05 14:04:04 +10009114static PyObject *
9115os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009116/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009117{
Victor Stinner984890f2011-11-24 13:53:38 +01009118#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009119 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009120#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009121
Victor Stinner984890f2011-11-24 13:53:38 +01009122#ifdef HAVE_BROKEN_UNSETENV
9123 unsetenv(PyBytes_AS_STRING(name));
9124#else
Victor Stinner65170952011-11-22 22:16:17 +01009125 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009126 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009127 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009128#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009129
Victor Stinner8c62be82010-05-06 00:08:46 +00009130 /* Remove the key from posix_putenv_garbage;
9131 * this will cause it to be collected. This has to
9132 * happen after the real unsetenv() call because the
9133 * old value was still accessible until then.
9134 */
Victor Stinner65170952011-11-22 22:16:17 +01009135 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009136 /* really not much we can do; just leak */
9137 PyErr_Clear();
9138 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009139 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009140}
Larry Hastings2f936352014-08-05 14:04:04 +10009141#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009142
Larry Hastings2f936352014-08-05 14:04:04 +10009143
9144/*[clinic input]
9145os.strerror
9146
9147 code: int
9148 /
9149
9150Translate an error code to a message string.
9151[clinic start generated code]*/
9152
Larry Hastings2f936352014-08-05 14:04:04 +10009153static PyObject *
9154os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009155/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009156{
9157 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009158 if (message == NULL) {
9159 PyErr_SetString(PyExc_ValueError,
9160 "strerror() argument out of range");
9161 return NULL;
9162 }
Victor Stinner1b579672011-12-17 05:47:23 +01009163 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009164}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009165
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009166
Guido van Rossumc9641791998-08-04 15:26:23 +00009167#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009168#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009169/*[clinic input]
9170os.WCOREDUMP -> bool
9171
9172 status: int
9173 /
9174
9175Return True if the process returning status was dumped to a core file.
9176[clinic start generated code]*/
9177
Larry Hastings2f936352014-08-05 14:04:04 +10009178static int
9179os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009180/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009181{
9182 WAIT_TYPE wait_status;
9183 WAIT_STATUS_INT(wait_status) = status;
9184 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009185}
9186#endif /* WCOREDUMP */
9187
Larry Hastings2f936352014-08-05 14:04:04 +10009188
Fred Drake106c1a02002-04-23 15:58:02 +00009189#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009190/*[clinic input]
9191os.WIFCONTINUED -> bool
9192
9193 status: int
9194
9195Return True if a particular process was continued from a job control stop.
9196
9197Return True if the process returning status was continued from a
9198job control stop.
9199[clinic start generated code]*/
9200
Larry Hastings2f936352014-08-05 14:04:04 +10009201static int
9202os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009203/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009204{
9205 WAIT_TYPE wait_status;
9206 WAIT_STATUS_INT(wait_status) = status;
9207 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009208}
9209#endif /* WIFCONTINUED */
9210
Larry Hastings2f936352014-08-05 14:04:04 +10009211
Guido van Rossumc9641791998-08-04 15:26:23 +00009212#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009213/*[clinic input]
9214os.WIFSTOPPED -> bool
9215
9216 status: int
9217
9218Return True if the process returning status was stopped.
9219[clinic start generated code]*/
9220
Larry Hastings2f936352014-08-05 14:04:04 +10009221static int
9222os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009223/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009224{
9225 WAIT_TYPE wait_status;
9226 WAIT_STATUS_INT(wait_status) = status;
9227 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009228}
9229#endif /* WIFSTOPPED */
9230
Larry Hastings2f936352014-08-05 14:04:04 +10009231
Guido van Rossumc9641791998-08-04 15:26:23 +00009232#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009233/*[clinic input]
9234os.WIFSIGNALED -> bool
9235
9236 status: int
9237
9238Return True if the process returning status was terminated by a signal.
9239[clinic start generated code]*/
9240
Larry Hastings2f936352014-08-05 14:04:04 +10009241static int
9242os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009243/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009244{
9245 WAIT_TYPE wait_status;
9246 WAIT_STATUS_INT(wait_status) = status;
9247 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009248}
9249#endif /* WIFSIGNALED */
9250
Larry Hastings2f936352014-08-05 14:04:04 +10009251
Guido van Rossumc9641791998-08-04 15:26:23 +00009252#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009253/*[clinic input]
9254os.WIFEXITED -> bool
9255
9256 status: int
9257
9258Return True if the process returning status exited via the exit() system call.
9259[clinic start generated code]*/
9260
Larry Hastings2f936352014-08-05 14:04:04 +10009261static int
9262os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009263/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009264{
9265 WAIT_TYPE wait_status;
9266 WAIT_STATUS_INT(wait_status) = status;
9267 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009268}
9269#endif /* WIFEXITED */
9270
Larry Hastings2f936352014-08-05 14:04:04 +10009271
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009272#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009273/*[clinic input]
9274os.WEXITSTATUS -> int
9275
9276 status: int
9277
9278Return the process return code from status.
9279[clinic start generated code]*/
9280
Larry Hastings2f936352014-08-05 14:04:04 +10009281static int
9282os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009283/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009284{
9285 WAIT_TYPE wait_status;
9286 WAIT_STATUS_INT(wait_status) = status;
9287 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009288}
9289#endif /* WEXITSTATUS */
9290
Larry Hastings2f936352014-08-05 14:04:04 +10009291
Guido van Rossumc9641791998-08-04 15:26:23 +00009292#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009293/*[clinic input]
9294os.WTERMSIG -> int
9295
9296 status: int
9297
9298Return the signal that terminated the process that provided the status value.
9299[clinic start generated code]*/
9300
Larry Hastings2f936352014-08-05 14:04:04 +10009301static int
9302os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009303/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009304{
9305 WAIT_TYPE wait_status;
9306 WAIT_STATUS_INT(wait_status) = status;
9307 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009308}
9309#endif /* WTERMSIG */
9310
Larry Hastings2f936352014-08-05 14:04:04 +10009311
Guido van Rossumc9641791998-08-04 15:26:23 +00009312#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009313/*[clinic input]
9314os.WSTOPSIG -> int
9315
9316 status: int
9317
9318Return the signal that stopped the process that provided the status value.
9319[clinic start generated code]*/
9320
Larry Hastings2f936352014-08-05 14:04:04 +10009321static int
9322os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009323/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009324{
9325 WAIT_TYPE wait_status;
9326 WAIT_STATUS_INT(wait_status) = status;
9327 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009328}
9329#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009330#endif /* HAVE_SYS_WAIT_H */
9331
9332
Thomas Wouters477c8d52006-05-27 19:21:47 +00009333#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009334#ifdef _SCO_DS
9335/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9336 needed definitions in sys/statvfs.h */
9337#define _SVID3
9338#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009339#include <sys/statvfs.h>
9340
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009341static PyObject*
9342_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009343 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9344 if (v == NULL)
9345 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009346
9347#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009348 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9349 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9350 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9351 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9352 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9353 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9354 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9355 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9356 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9357 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009358#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9360 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9361 PyStructSequence_SET_ITEM(v, 2,
9362 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9363 PyStructSequence_SET_ITEM(v, 3,
9364 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9365 PyStructSequence_SET_ITEM(v, 4,
9366 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9367 PyStructSequence_SET_ITEM(v, 5,
9368 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9369 PyStructSequence_SET_ITEM(v, 6,
9370 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9371 PyStructSequence_SET_ITEM(v, 7,
9372 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9373 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9374 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009375#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009376 if (PyErr_Occurred()) {
9377 Py_DECREF(v);
9378 return NULL;
9379 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009380
Victor Stinner8c62be82010-05-06 00:08:46 +00009381 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009382}
9383
Larry Hastings2f936352014-08-05 14:04:04 +10009384
9385/*[clinic input]
9386os.fstatvfs
9387 fd: int
9388 /
9389
9390Perform an fstatvfs system call on the given fd.
9391
9392Equivalent to statvfs(fd).
9393[clinic start generated code]*/
9394
Larry Hastings2f936352014-08-05 14:04:04 +10009395static PyObject *
9396os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009397/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009398{
9399 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009400 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009401 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009402
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009403 do {
9404 Py_BEGIN_ALLOW_THREADS
9405 result = fstatvfs(fd, &st);
9406 Py_END_ALLOW_THREADS
9407 } while (result != 0 && errno == EINTR &&
9408 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009409 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009410 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009411
Victor Stinner8c62be82010-05-06 00:08:46 +00009412 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009413}
Larry Hastings2f936352014-08-05 14:04:04 +10009414#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009415
9416
Thomas Wouters477c8d52006-05-27 19:21:47 +00009417#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009418#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009419/*[clinic input]
9420os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009421
Larry Hastings2f936352014-08-05 14:04:04 +10009422 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9423
9424Perform a statvfs system call on the given path.
9425
9426path may always be specified as a string.
9427On some platforms, path may also be specified as an open file descriptor.
9428 If this functionality is unavailable, using it raises an exception.
9429[clinic start generated code]*/
9430
Larry Hastings2f936352014-08-05 14:04:04 +10009431static PyObject *
9432os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009433/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009434{
9435 int result;
9436 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009437
9438 Py_BEGIN_ALLOW_THREADS
9439#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009440 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009441#ifdef __APPLE__
9442 /* handle weak-linking on Mac OS X 10.3 */
9443 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009444 fd_specified("statvfs", path->fd);
9445 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009446 }
9447#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009448 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009449 }
9450 else
9451#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009452 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009453 Py_END_ALLOW_THREADS
9454
9455 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009456 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009457 }
9458
Larry Hastings2f936352014-08-05 14:04:04 +10009459 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009460}
Larry Hastings2f936352014-08-05 14:04:04 +10009461#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9462
Guido van Rossum94f6f721999-01-06 18:42:14 +00009463
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009464#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009465/*[clinic input]
9466os._getdiskusage
9467
9468 path: Py_UNICODE
9469
9470Return disk usage statistics about the given path as a (total, free) tuple.
9471[clinic start generated code]*/
9472
Larry Hastings2f936352014-08-05 14:04:04 +10009473static PyObject *
9474os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009475/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009476{
9477 BOOL retval;
9478 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009479
9480 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009481 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009482 Py_END_ALLOW_THREADS
9483 if (retval == 0)
9484 return PyErr_SetFromWindowsErr(0);
9485
9486 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9487}
Larry Hastings2f936352014-08-05 14:04:04 +10009488#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009489
9490
Fred Drakec9680921999-12-13 16:37:25 +00009491/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9492 * It maps strings representing configuration variable names to
9493 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009494 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009495 * rarely-used constants. There are three separate tables that use
9496 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009497 *
9498 * This code is always included, even if none of the interfaces that
9499 * need it are included. The #if hackery needed to avoid it would be
9500 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009501 */
9502struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009503 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009504 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009505};
9506
Fred Drake12c6e2d1999-12-14 21:25:03 +00009507static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009508conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009509 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009510{
Christian Heimes217cfd12007-12-02 14:31:20 +00009511 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009512 int value = _PyLong_AsInt(arg);
9513 if (value == -1 && PyErr_Occurred())
9514 return 0;
9515 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009516 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009517 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009518 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009519 /* look up the value in the table using a binary search */
9520 size_t lo = 0;
9521 size_t mid;
9522 size_t hi = tablesize;
9523 int cmp;
9524 const char *confname;
9525 if (!PyUnicode_Check(arg)) {
9526 PyErr_SetString(PyExc_TypeError,
9527 "configuration names must be strings or integers");
9528 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009530 confname = _PyUnicode_AsString(arg);
9531 if (confname == NULL)
9532 return 0;
9533 while (lo < hi) {
9534 mid = (lo + hi) / 2;
9535 cmp = strcmp(confname, table[mid].name);
9536 if (cmp < 0)
9537 hi = mid;
9538 else if (cmp > 0)
9539 lo = mid + 1;
9540 else {
9541 *valuep = table[mid].value;
9542 return 1;
9543 }
9544 }
9545 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9546 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009548}
9549
9550
9551#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9552static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009553#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009555#endif
9556#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009558#endif
Fred Drakec9680921999-12-13 16:37:25 +00009559#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009604#ifdef _PC_ACL_ENABLED
9605 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9606#endif
9607#ifdef _PC_MIN_HOLE_SIZE
9608 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9609#endif
9610#ifdef _PC_ALLOC_SIZE_MIN
9611 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9612#endif
9613#ifdef _PC_REC_INCR_XFER_SIZE
9614 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9615#endif
9616#ifdef _PC_REC_MAX_XFER_SIZE
9617 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9618#endif
9619#ifdef _PC_REC_MIN_XFER_SIZE
9620 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9621#endif
9622#ifdef _PC_REC_XFER_ALIGN
9623 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9624#endif
9625#ifdef _PC_SYMLINK_MAX
9626 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9627#endif
9628#ifdef _PC_XATTR_ENABLED
9629 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9630#endif
9631#ifdef _PC_XATTR_EXISTS
9632 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9633#endif
9634#ifdef _PC_TIMESTAMP_RESOLUTION
9635 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9636#endif
Fred Drakec9680921999-12-13 16:37:25 +00009637};
9638
Fred Drakec9680921999-12-13 16:37:25 +00009639static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009640conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009641{
9642 return conv_confname(arg, valuep, posix_constants_pathconf,
9643 sizeof(posix_constants_pathconf)
9644 / sizeof(struct constdef));
9645}
9646#endif
9647
Larry Hastings2f936352014-08-05 14:04:04 +10009648
Fred Drakec9680921999-12-13 16:37:25 +00009649#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009650/*[clinic input]
9651os.fpathconf -> long
9652
9653 fd: int
9654 name: path_confname
9655 /
9656
9657Return the configuration limit name for the file descriptor fd.
9658
9659If there is no limit, return -1.
9660[clinic start generated code]*/
9661
Larry Hastings2f936352014-08-05 14:04:04 +10009662static long
9663os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009664/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009665{
9666 long limit;
9667
9668 errno = 0;
9669 limit = fpathconf(fd, name);
9670 if (limit == -1 && errno != 0)
9671 posix_error();
9672
9673 return limit;
9674}
9675#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009676
9677
9678#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009679/*[clinic input]
9680os.pathconf -> long
9681 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9682 name: path_confname
9683
9684Return the configuration limit name for the file or directory path.
9685
9686If there is no limit, return -1.
9687On some platforms, path may also be specified as an open file descriptor.
9688 If this functionality is unavailable, using it raises an exception.
9689[clinic start generated code]*/
9690
Larry Hastings2f936352014-08-05 14:04:04 +10009691static long
9692os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009693/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009694{
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009696
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009698#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009699 if (path->fd != -1)
9700 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009701 else
9702#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009703 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 if (limit == -1 && errno != 0) {
9705 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009706 /* could be a path or name problem */
9707 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009708 else
Larry Hastings2f936352014-08-05 14:04:04 +10009709 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 }
Larry Hastings2f936352014-08-05 14:04:04 +10009711
9712 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009713}
Larry Hastings2f936352014-08-05 14:04:04 +10009714#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009715
9716#ifdef HAVE_CONFSTR
9717static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009718#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009720#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009721#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009723#endif
9724#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009726#endif
Fred Draked86ed291999-12-15 15:34:33 +00009727#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009729#endif
9730#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009732#endif
9733#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009735#endif
9736#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009738#endif
Fred Drakec9680921999-12-13 16:37:25 +00009739#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
Fred Draked86ed291999-12-15 15:34:33 +00009763#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009765#endif
Fred Drakec9680921999-12-13 16:37:25 +00009766#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
Fred Draked86ed291999-12-15 15:34:33 +00009769#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009771#endif
9772#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009774#endif
9775#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009777#endif
9778#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009780#endif
Fred Drakec9680921999-12-13 16:37:25 +00009781#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
Fred Draked86ed291999-12-15 15:34:33 +00009829#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009831#endif
9832#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009834#endif
9835#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009837#endif
9838#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
9841#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
9844#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009846#endif
9847#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009849#endif
9850#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009852#endif
9853#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009855#endif
9856#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009858#endif
9859#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009861#endif
9862#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009864#endif
9865#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009867#endif
Fred Drakec9680921999-12-13 16:37:25 +00009868};
9869
9870static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009871conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009872{
9873 return conv_confname(arg, valuep, posix_constants_confstr,
9874 sizeof(posix_constants_confstr)
9875 / sizeof(struct constdef));
9876}
9877
Larry Hastings2f936352014-08-05 14:04:04 +10009878
9879/*[clinic input]
9880os.confstr
9881
9882 name: confstr_confname
9883 /
9884
9885Return a string-valued system configuration variable.
9886[clinic start generated code]*/
9887
Larry Hastings2f936352014-08-05 14:04:04 +10009888static PyObject *
9889os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009890/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009891{
9892 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009893 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009894 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009895
Victor Stinnercb043522010-09-10 23:49:04 +00009896 errno = 0;
9897 len = confstr(name, buffer, sizeof(buffer));
9898 if (len == 0) {
9899 if (errno) {
9900 posix_error();
9901 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009902 }
9903 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009904 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009905 }
9906 }
Victor Stinnercb043522010-09-10 23:49:04 +00009907
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009908 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009909 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009910 char *buf = PyMem_Malloc(len);
9911 if (buf == NULL)
9912 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009913 len2 = confstr(name, buf, len);
9914 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009915 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009916 PyMem_Free(buf);
9917 }
9918 else
9919 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009920 return result;
9921}
Larry Hastings2f936352014-08-05 14:04:04 +10009922#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009923
9924
9925#ifdef HAVE_SYSCONF
9926static struct constdef posix_constants_sysconf[] = {
9927#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
Fred Draked86ed291999-12-15 15:34:33 +00009957#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009959#endif
9960#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009962#endif
Fred Drakec9680921999-12-13 16:37:25 +00009963#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
Fred Drakec9680921999-12-13 16:37:25 +00009966#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
Fred Draked86ed291999-12-15 15:34:33 +00009981#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009983#endif
Fred Drakec9680921999-12-13 16:37:25 +00009984#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
Fred Draked86ed291999-12-15 15:34:33 +00009999#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010001#endif
Fred Drakec9680921999-12-13 16:37:25 +000010002#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
Fred Draked86ed291999-12-15 15:34:33 +000010071#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010073#endif
Fred Drakec9680921999-12-13 16:37:25 +000010074#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
Fred Draked86ed291999-12-15 15:34:33 +000010083#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010085#endif
Fred Drakec9680921999-12-13 16:37:25 +000010086#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
Fred Draked86ed291999-12-15 15:34:33 +000010089#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010091#endif
10092#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010094#endif
Fred Drakec9680921999-12-13 16:37:25 +000010095#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
Fred Draked86ed291999-12-15 15:34:33 +000010107#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010109#endif
Fred Drakec9680921999-12-13 16:37:25 +000010110#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
Fred Draked86ed291999-12-15 15:34:33 +000010131#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010133#endif
Fred Drakec9680921999-12-13 16:37:25 +000010134#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
Fred Draked86ed291999-12-15 15:34:33 +000010140#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010142#endif
Fred Drakec9680921999-12-13 16:37:25 +000010143#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
Fred Draked86ed291999-12-15 15:34:33 +000010170#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010172#endif
10173#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010175#endif
Fred Drakec9680921999-12-13 16:37:25 +000010176#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
Fred Draked86ed291999-12-15 15:34:33 +000010281#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010283#endif
Fred Drakec9680921999-12-13 16:37:25 +000010284#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010400#endif
10401#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010403#endif
10404#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010406#endif
10407#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010409#endif
10410#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010412#endif
10413#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010415#endif
10416#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010418#endif
10419};
10420
10421static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010422conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010423{
10424 return conv_confname(arg, valuep, posix_constants_sysconf,
10425 sizeof(posix_constants_sysconf)
10426 / sizeof(struct constdef));
10427}
10428
Larry Hastings2f936352014-08-05 14:04:04 +100010429
10430/*[clinic input]
10431os.sysconf -> long
10432 name: sysconf_confname
10433 /
10434
10435Return an integer-valued system configuration variable.
10436[clinic start generated code]*/
10437
Larry Hastings2f936352014-08-05 14:04:04 +100010438static long
10439os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010440/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010441{
10442 long value;
10443
10444 errno = 0;
10445 value = sysconf(name);
10446 if (value == -1 && errno != 0)
10447 posix_error();
10448 return value;
10449}
10450#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010451
10452
Fred Drakebec628d1999-12-15 18:31:10 +000010453/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010454 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010455 * the exported dictionaries that are used to publish information about the
10456 * names available on the host platform.
10457 *
10458 * Sorting the table at runtime ensures that the table is properly ordered
10459 * when used, even for platforms we're not able to test on. It also makes
10460 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010461 */
Fred Drakebec628d1999-12-15 18:31:10 +000010462
10463static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010464cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010465{
10466 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010468 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010470
10471 return strcmp(c1->name, c2->name);
10472}
10473
10474static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010475setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010476 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010477{
Fred Drakebec628d1999-12-15 18:31:10 +000010478 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010479 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010480
10481 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10482 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010483 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010484 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010485
Barry Warsaw3155db32000-04-13 15:20:40 +000010486 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010487 PyObject *o = PyLong_FromLong(table[i].value);
10488 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10489 Py_XDECREF(o);
10490 Py_DECREF(d);
10491 return -1;
10492 }
10493 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010494 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010495 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010496}
10497
Fred Drakebec628d1999-12-15 18:31:10 +000010498/* Return -1 on failure, 0 on success. */
10499static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010500setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010501{
10502#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010503 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010504 sizeof(posix_constants_pathconf)
10505 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010506 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010507 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010508#endif
10509#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010510 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010511 sizeof(posix_constants_confstr)
10512 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010513 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010514 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010515#endif
10516#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010517 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010518 sizeof(posix_constants_sysconf)
10519 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010520 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010521 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010522#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010523 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010524}
Fred Draked86ed291999-12-15 15:34:33 +000010525
10526
Larry Hastings2f936352014-08-05 14:04:04 +100010527/*[clinic input]
10528os.abort
10529
10530Abort the interpreter immediately.
10531
10532This function 'dumps core' or otherwise fails in the hardest way possible
10533on the hosting operating system. This function never returns.
10534[clinic start generated code]*/
10535
Larry Hastings2f936352014-08-05 14:04:04 +100010536static PyObject *
10537os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010538/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010539{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010540 abort();
10541 /*NOTREACHED*/
10542 Py_FatalError("abort() called from Python code didn't abort!");
10543 return NULL;
10544}
Fred Drakebec628d1999-12-15 18:31:10 +000010545
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010546#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010547/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010548PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010549"startfile(filepath [, operation])\n\
10550\n\
10551Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010552\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010553When \"operation\" is not specified or \"open\", this acts like\n\
10554double-clicking the file in Explorer, or giving the file name as an\n\
10555argument to the DOS \"start\" command: the file is opened with whatever\n\
10556application (if any) its extension is associated.\n\
10557When another \"operation\" is given, it specifies what should be done with\n\
10558the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010559\n\
10560startfile returns as soon as the associated application is launched.\n\
10561There is no option to wait for the application to close, and no way\n\
10562to retrieve the application's exit status.\n\
10563\n\
10564The filepath is relative to the current directory. If you want to use\n\
10565an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010566the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010567
Steve Dower7d0e0c92015-01-24 08:18:24 -080010568/* Grab ShellExecute dynamically from shell32 */
10569static int has_ShellExecute = -1;
10570static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10571 LPCSTR, INT);
10572static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10573 LPCWSTR, INT);
10574static int
10575check_ShellExecute()
10576{
10577 HINSTANCE hShell32;
10578
10579 /* only recheck */
10580 if (-1 == has_ShellExecute) {
10581 Py_BEGIN_ALLOW_THREADS
10582 hShell32 = LoadLibraryW(L"SHELL32");
10583 Py_END_ALLOW_THREADS
10584 if (hShell32) {
10585 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10586 "ShellExecuteA");
10587 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10588 "ShellExecuteW");
10589 has_ShellExecute = Py_ShellExecuteA &&
10590 Py_ShellExecuteW;
10591 } else {
10592 has_ShellExecute = 0;
10593 }
10594 }
10595 return has_ShellExecute;
10596}
10597
10598
Tim Petersf58a7aa2000-09-22 10:05:54 +000010599static PyObject *
10600win32_startfile(PyObject *self, PyObject *args)
10601{
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 PyObject *ofilepath;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010603 const char *filepath;
10604 const char *operation = NULL;
10605 const wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010607
Victor Stinnereb5657a2011-09-30 01:44:27 +020010608 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010609
10610 if(!check_ShellExecute()) {
10611 /* If the OS doesn't have ShellExecute, return a
10612 NotImplementedError. */
10613 return PyErr_Format(PyExc_NotImplementedError,
10614 "startfile not available on this platform");
10615 }
10616
Victor Stinner8c62be82010-05-06 00:08:46 +000010617 if (!PyArg_ParseTuple(args, "U|s:startfile",
10618 &unipath, &operation)) {
10619 PyErr_Clear();
10620 goto normal;
10621 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010622
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010624 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010626 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 PyErr_Clear();
10628 operation = NULL;
10629 goto normal;
10630 }
10631 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010632
Victor Stinnereb5657a2011-09-30 01:44:27 +020010633 wpath = PyUnicode_AsUnicode(unipath);
10634 if (wpath == NULL)
10635 goto normal;
10636 if (uoperation) {
10637 woperation = PyUnicode_AsUnicode(uoperation);
10638 if (woperation == NULL)
10639 goto normal;
10640 }
10641 else
10642 woperation = NULL;
10643
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010645 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10646 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010647 Py_END_ALLOW_THREADS
10648
Victor Stinnereb5657a2011-09-30 01:44:27 +020010649 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010651 win32_error_object("startfile", unipath);
10652 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 }
10654 Py_INCREF(Py_None);
10655 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010656
10657normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010658 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10659 PyUnicode_FSConverter, &ofilepath,
10660 &operation))
10661 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010662 if (win32_warn_bytes_api()) {
10663 Py_DECREF(ofilepath);
10664 return NULL;
10665 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 filepath = PyBytes_AsString(ofilepath);
10667 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010668 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10669 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010670 Py_END_ALLOW_THREADS
10671 if (rc <= (HINSTANCE)32) {
10672 PyObject *errval = win32_error("startfile", filepath);
10673 Py_DECREF(ofilepath);
10674 return errval;
10675 }
10676 Py_DECREF(ofilepath);
10677 Py_INCREF(Py_None);
10678 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010679}
Larry Hastings2f936352014-08-05 14:04:04 +100010680#endif /* MS_WINDOWS */
10681
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010682
Martin v. Löwis438b5342002-12-27 10:16:42 +000010683#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010684/*[clinic input]
10685os.getloadavg
10686
10687Return average recent system load information.
10688
10689Return the number of processes in the system run queue averaged over
10690the last 1, 5, and 15 minutes as a tuple of three floats.
10691Raises OSError if the load average was unobtainable.
10692[clinic start generated code]*/
10693
Larry Hastings2f936352014-08-05 14:04:04 +100010694static PyObject *
10695os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010696/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010697{
10698 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010699 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010700 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10701 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010702 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010703 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010704}
Larry Hastings2f936352014-08-05 14:04:04 +100010705#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010706
Larry Hastings2f936352014-08-05 14:04:04 +100010707
10708/*[clinic input]
10709os.device_encoding
10710 fd: int
10711
10712Return a string describing the encoding of a terminal's file descriptor.
10713
10714The file descriptor must be attached to a terminal.
10715If the device is not a terminal, return None.
10716[clinic start generated code]*/
10717
Larry Hastings2f936352014-08-05 14:04:04 +100010718static PyObject *
10719os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010720/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010721{
Brett Cannonefb00c02012-02-29 18:31:31 -050010722 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010723}
10724
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010725
Larry Hastings2f936352014-08-05 14:04:04 +100010726#ifdef HAVE_SETRESUID
10727/*[clinic input]
10728os.setresuid
10729
10730 ruid: uid_t
10731 euid: uid_t
10732 suid: uid_t
10733 /
10734
10735Set the current process's real, effective, and saved user ids.
10736[clinic start generated code]*/
10737
Larry Hastings2f936352014-08-05 14:04:04 +100010738static PyObject *
10739os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010740/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010741{
Victor Stinner8c62be82010-05-06 00:08:46 +000010742 if (setresuid(ruid, euid, suid) < 0)
10743 return posix_error();
10744 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010745}
Larry Hastings2f936352014-08-05 14:04:04 +100010746#endif /* HAVE_SETRESUID */
10747
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010748
10749#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010750/*[clinic input]
10751os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010752
Larry Hastings2f936352014-08-05 14:04:04 +100010753 rgid: gid_t
10754 egid: gid_t
10755 sgid: gid_t
10756 /
10757
10758Set the current process's real, effective, and saved group ids.
10759[clinic start generated code]*/
10760
Larry Hastings2f936352014-08-05 14:04:04 +100010761static PyObject *
10762os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010763/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010764{
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 if (setresgid(rgid, egid, sgid) < 0)
10766 return posix_error();
10767 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010768}
Larry Hastings2f936352014-08-05 14:04:04 +100010769#endif /* HAVE_SETRESGID */
10770
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010771
10772#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010773/*[clinic input]
10774os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010775
Larry Hastings2f936352014-08-05 14:04:04 +100010776Return a tuple of the current process's real, effective, and saved user ids.
10777[clinic start generated code]*/
10778
Larry Hastings2f936352014-08-05 14:04:04 +100010779static PyObject *
10780os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010781/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010782{
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 if (getresuid(&ruid, &euid, &suid) < 0)
10785 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010786 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10787 _PyLong_FromUid(euid),
10788 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010789}
Larry Hastings2f936352014-08-05 14:04:04 +100010790#endif /* HAVE_GETRESUID */
10791
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010792
10793#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010794/*[clinic input]
10795os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010796
Larry Hastings2f936352014-08-05 14:04:04 +100010797Return a tuple of the current process's real, effective, and saved group ids.
10798[clinic start generated code]*/
10799
Larry Hastings2f936352014-08-05 14:04:04 +100010800static PyObject *
10801os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010802/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010803{
10804 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010805 if (getresgid(&rgid, &egid, &sgid) < 0)
10806 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010807 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10808 _PyLong_FromGid(egid),
10809 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010810}
Larry Hastings2f936352014-08-05 14:04:04 +100010811#endif /* HAVE_GETRESGID */
10812
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010813
Benjamin Peterson9428d532011-09-14 11:45:52 -040010814#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010815/*[clinic input]
10816os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010817
Larry Hastings2f936352014-08-05 14:04:04 +100010818 path: path_t(allow_fd=True)
10819 attribute: path_t
10820 *
10821 follow_symlinks: bool = True
10822
10823Return the value of extended attribute attribute on path.
10824
10825path may be either a string or an open file descriptor.
10826If follow_symlinks is False, and the last element of the path is a symbolic
10827 link, getxattr will examine the symbolic link itself instead of the file
10828 the link points to.
10829
10830[clinic start generated code]*/
10831
Larry Hastings2f936352014-08-05 14:04:04 +100010832static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010833os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10834 int follow_symlinks)
10835/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010836{
10837 Py_ssize_t i;
10838 PyObject *buffer = NULL;
10839
10840 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10841 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010842
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 for (i = 0; ; i++) {
10844 void *ptr;
10845 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010846 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010847 Py_ssize_t buffer_size = buffer_sizes[i];
10848 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010849 path_error(path);
10850 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010851 }
10852 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10853 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010854 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010855 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010856
Larry Hastings9cf065c2012-06-22 16:30:09 -070010857 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010858 if (path->fd >= 0)
10859 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010861 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010862 else
Larry Hastings2f936352014-08-05 14:04:04 +100010863 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010865
Larry Hastings9cf065c2012-06-22 16:30:09 -070010866 if (result < 0) {
10867 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010868 if (errno == ERANGE)
10869 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010870 path_error(path);
10871 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010872 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010873
Larry Hastings9cf065c2012-06-22 16:30:09 -070010874 if (result != buffer_size) {
10875 /* Can only shrink. */
10876 _PyBytes_Resize(&buffer, result);
10877 }
10878 break;
10879 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010880
Larry Hastings9cf065c2012-06-22 16:30:09 -070010881 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010882}
10883
Larry Hastings2f936352014-08-05 14:04:04 +100010884
10885/*[clinic input]
10886os.setxattr
10887
10888 path: path_t(allow_fd=True)
10889 attribute: path_t
10890 value: Py_buffer
10891 flags: int = 0
10892 *
10893 follow_symlinks: bool = True
10894
10895Set extended attribute attribute on path to value.
10896
10897path may be either a string or an open file descriptor.
10898If follow_symlinks is False, and the last element of the path is a symbolic
10899 link, setxattr will modify the symbolic link itself instead of the file
10900 the link points to.
10901
10902[clinic start generated code]*/
10903
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010905os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10906 Py_buffer *value, int flags, int follow_symlinks)
10907/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908{
Larry Hastings2f936352014-08-05 14:04:04 +100010909 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910
Larry Hastings2f936352014-08-05 14:04:04 +100010911 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010912 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010913
Benjamin Peterson799bd802011-08-31 22:15:17 -040010914 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010915 if (path->fd > -1)
10916 result = fsetxattr(path->fd, attribute->narrow,
10917 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010918 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010919 result = setxattr(path->narrow, attribute->narrow,
10920 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010921 else
Larry Hastings2f936352014-08-05 14:04:04 +100010922 result = lsetxattr(path->narrow, attribute->narrow,
10923 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010924 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010925
Larry Hastings9cf065c2012-06-22 16:30:09 -070010926 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010927 path_error(path);
10928 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010929 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010930
Larry Hastings2f936352014-08-05 14:04:04 +100010931 Py_RETURN_NONE;
10932}
10933
10934
10935/*[clinic input]
10936os.removexattr
10937
10938 path: path_t(allow_fd=True)
10939 attribute: path_t
10940 *
10941 follow_symlinks: bool = True
10942
10943Remove extended attribute attribute on path.
10944
10945path may be either a string or an open file descriptor.
10946If follow_symlinks is False, and the last element of the path is a symbolic
10947 link, removexattr will modify the symbolic link itself instead of the file
10948 the link points to.
10949
10950[clinic start generated code]*/
10951
Larry Hastings2f936352014-08-05 14:04:04 +100010952static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010953os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10954 int follow_symlinks)
10955/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010956{
10957 ssize_t result;
10958
10959 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10960 return NULL;
10961
10962 Py_BEGIN_ALLOW_THREADS;
10963 if (path->fd > -1)
10964 result = fremovexattr(path->fd, attribute->narrow);
10965 else if (follow_symlinks)
10966 result = removexattr(path->narrow, attribute->narrow);
10967 else
10968 result = lremovexattr(path->narrow, attribute->narrow);
10969 Py_END_ALLOW_THREADS;
10970
10971 if (result) {
10972 return path_error(path);
10973 }
10974
10975 Py_RETURN_NONE;
10976}
10977
10978
10979/*[clinic input]
10980os.listxattr
10981
10982 path: path_t(allow_fd=True, nullable=True) = None
10983 *
10984 follow_symlinks: bool = True
10985
10986Return a list of extended attributes on path.
10987
10988path may be either None, a string, or an open file descriptor.
10989if path is None, listxattr will examine the current directory.
10990If follow_symlinks is False, and the last element of the path is a symbolic
10991 link, listxattr will examine the symbolic link itself instead of the file
10992 the link points to.
10993[clinic start generated code]*/
10994
Larry Hastings2f936352014-08-05 14:04:04 +100010995static PyObject *
10996os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010997/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010998{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 Py_ssize_t i;
11000 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011001 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011002 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011003
Larry Hastings2f936352014-08-05 14:04:04 +100011004 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011006
Larry Hastings2f936352014-08-05 14:04:04 +100011007 name = path->narrow ? path->narrow : ".";
11008
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011010 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011012 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 Py_ssize_t buffer_size = buffer_sizes[i];
11014 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011015 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011016 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011017 break;
11018 }
11019 buffer = PyMem_MALLOC(buffer_size);
11020 if (!buffer) {
11021 PyErr_NoMemory();
11022 break;
11023 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011024
Larry Hastings9cf065c2012-06-22 16:30:09 -070011025 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011026 if (path->fd > -1)
11027 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011028 else if (follow_symlinks)
11029 length = listxattr(name, buffer, buffer_size);
11030 else
11031 length = llistxattr(name, buffer, buffer_size);
11032 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011033
Larry Hastings9cf065c2012-06-22 16:30:09 -070011034 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011035 if (errno == ERANGE) {
11036 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011037 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011038 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011039 }
Larry Hastings2f936352014-08-05 14:04:04 +100011040 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011041 break;
11042 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011043
Larry Hastings9cf065c2012-06-22 16:30:09 -070011044 result = PyList_New(0);
11045 if (!result) {
11046 goto exit;
11047 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011048
Larry Hastings9cf065c2012-06-22 16:30:09 -070011049 end = buffer + length;
11050 for (trace = start = buffer; trace != end; trace++) {
11051 if (!*trace) {
11052 int error;
11053 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11054 trace - start);
11055 if (!attribute) {
11056 Py_DECREF(result);
11057 result = NULL;
11058 goto exit;
11059 }
11060 error = PyList_Append(result, attribute);
11061 Py_DECREF(attribute);
11062 if (error) {
11063 Py_DECREF(result);
11064 result = NULL;
11065 goto exit;
11066 }
11067 start = trace + 1;
11068 }
11069 }
11070 break;
11071 }
11072exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011073 if (buffer)
11074 PyMem_FREE(buffer);
11075 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011076}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011077#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011078
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011079
Larry Hastings2f936352014-08-05 14:04:04 +100011080/*[clinic input]
11081os.urandom
11082
11083 size: Py_ssize_t
11084 /
11085
11086Return a bytes object containing random bytes suitable for cryptographic use.
11087[clinic start generated code]*/
11088
Larry Hastings2f936352014-08-05 14:04:04 +100011089static PyObject *
11090os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011091/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011092{
11093 PyObject *bytes;
11094 int result;
11095
Georg Brandl2fb477c2012-02-21 00:33:36 +010011096 if (size < 0)
11097 return PyErr_Format(PyExc_ValueError,
11098 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011099 bytes = PyBytes_FromStringAndSize(NULL, size);
11100 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011101 return NULL;
11102
Larry Hastings2f936352014-08-05 14:04:04 +100011103 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11104 PyBytes_GET_SIZE(bytes));
11105 if (result == -1) {
11106 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011107 return NULL;
11108 }
Larry Hastings2f936352014-08-05 14:04:04 +100011109 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011110}
11111
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011112/* Terminal size querying */
11113
11114static PyTypeObject TerminalSizeType;
11115
11116PyDoc_STRVAR(TerminalSize_docstring,
11117 "A tuple of (columns, lines) for holding terminal window size");
11118
11119static PyStructSequence_Field TerminalSize_fields[] = {
11120 {"columns", "width of the terminal window in characters"},
11121 {"lines", "height of the terminal window in characters"},
11122 {NULL, NULL}
11123};
11124
11125static PyStructSequence_Desc TerminalSize_desc = {
11126 "os.terminal_size",
11127 TerminalSize_docstring,
11128 TerminalSize_fields,
11129 2,
11130};
11131
11132#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011133/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011134PyDoc_STRVAR(termsize__doc__,
11135 "Return the size of the terminal window as (columns, lines).\n" \
11136 "\n" \
11137 "The optional argument fd (default standard output) specifies\n" \
11138 "which file descriptor should be queried.\n" \
11139 "\n" \
11140 "If the file descriptor is not connected to a terminal, an OSError\n" \
11141 "is thrown.\n" \
11142 "\n" \
11143 "This function will only be defined if an implementation is\n" \
11144 "available for this system.\n" \
11145 "\n" \
11146 "shutil.get_terminal_size is the high-level function which should \n" \
11147 "normally be used, os.get_terminal_size is the low-level implementation.");
11148
11149static PyObject*
11150get_terminal_size(PyObject *self, PyObject *args)
11151{
11152 int columns, lines;
11153 PyObject *termsize;
11154
11155 int fd = fileno(stdout);
11156 /* Under some conditions stdout may not be connected and
11157 * fileno(stdout) may point to an invalid file descriptor. For example
11158 * GUI apps don't have valid standard streams by default.
11159 *
11160 * If this happens, and the optional fd argument is not present,
11161 * the ioctl below will fail returning EBADF. This is what we want.
11162 */
11163
11164 if (!PyArg_ParseTuple(args, "|i", &fd))
11165 return NULL;
11166
11167#ifdef TERMSIZE_USE_IOCTL
11168 {
11169 struct winsize w;
11170 if (ioctl(fd, TIOCGWINSZ, &w))
11171 return PyErr_SetFromErrno(PyExc_OSError);
11172 columns = w.ws_col;
11173 lines = w.ws_row;
11174 }
11175#endif /* TERMSIZE_USE_IOCTL */
11176
11177#ifdef TERMSIZE_USE_CONIO
11178 {
11179 DWORD nhandle;
11180 HANDLE handle;
11181 CONSOLE_SCREEN_BUFFER_INFO csbi;
11182 switch (fd) {
11183 case 0: nhandle = STD_INPUT_HANDLE;
11184 break;
11185 case 1: nhandle = STD_OUTPUT_HANDLE;
11186 break;
11187 case 2: nhandle = STD_ERROR_HANDLE;
11188 break;
11189 default:
11190 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11191 }
11192 handle = GetStdHandle(nhandle);
11193 if (handle == NULL)
11194 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11195 if (handle == INVALID_HANDLE_VALUE)
11196 return PyErr_SetFromWindowsErr(0);
11197
11198 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11199 return PyErr_SetFromWindowsErr(0);
11200
11201 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11202 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11203 }
11204#endif /* TERMSIZE_USE_CONIO */
11205
11206 termsize = PyStructSequence_New(&TerminalSizeType);
11207 if (termsize == NULL)
11208 return NULL;
11209 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11210 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11211 if (PyErr_Occurred()) {
11212 Py_DECREF(termsize);
11213 return NULL;
11214 }
11215 return termsize;
11216}
11217#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11218
Larry Hastings2f936352014-08-05 14:04:04 +100011219
11220/*[clinic input]
11221os.cpu_count
11222
Charles-François Natali80d62e62015-08-13 20:37:08 +010011223Return the number of CPUs in the system; return None if indeterminable.
11224
11225This number is not equivalent to the number of CPUs the current process can
11226use. The number of usable CPUs can be obtained with
11227``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011228[clinic start generated code]*/
11229
Larry Hastings2f936352014-08-05 14:04:04 +100011230static PyObject *
11231os_cpu_count_impl(PyModuleDef *module)
Charles-François Natali80d62e62015-08-13 20:37:08 +010011232/*[clinic end generated code: output=c59ee7f6bce832b8 input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011233{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011234 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011235#ifdef MS_WINDOWS
11236 SYSTEM_INFO sysinfo;
11237 GetSystemInfo(&sysinfo);
11238 ncpu = sysinfo.dwNumberOfProcessors;
11239#elif defined(__hpux)
11240 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11241#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11242 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011243#elif defined(__DragonFly__) || \
11244 defined(__OpenBSD__) || \
11245 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011246 defined(__NetBSD__) || \
11247 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011248 int mib[2];
11249 size_t len = sizeof(ncpu);
11250 mib[0] = CTL_HW;
11251 mib[1] = HW_NCPU;
11252 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11253 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011254#endif
11255 if (ncpu >= 1)
11256 return PyLong_FromLong(ncpu);
11257 else
11258 Py_RETURN_NONE;
11259}
11260
Victor Stinnerdaf45552013-08-28 00:53:59 +020011261
Larry Hastings2f936352014-08-05 14:04:04 +100011262/*[clinic input]
11263os.get_inheritable -> bool
11264
11265 fd: int
11266 /
11267
11268Get the close-on-exe flag of the specified file descriptor.
11269[clinic start generated code]*/
11270
Larry Hastings2f936352014-08-05 14:04:04 +100011271static int
11272os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011273/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011274{
Steve Dower8fc89802015-04-12 00:26:27 -040011275 int return_value;
11276 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011277 posix_error();
11278 return -1;
11279 }
11280
Steve Dower8fc89802015-04-12 00:26:27 -040011281 _Py_BEGIN_SUPPRESS_IPH
11282 return_value = _Py_get_inheritable(fd);
11283 _Py_END_SUPPRESS_IPH
11284 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011285}
11286
11287
11288/*[clinic input]
11289os.set_inheritable
11290 fd: int
11291 inheritable: int
11292 /
11293
11294Set the inheritable flag of the specified file descriptor.
11295[clinic start generated code]*/
11296
Larry Hastings2f936352014-08-05 14:04:04 +100011297static PyObject *
11298os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011299/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011300{
Steve Dower8fc89802015-04-12 00:26:27 -040011301 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011302 if (!_PyVerify_fd(fd))
11303 return posix_error();
11304
Steve Dower8fc89802015-04-12 00:26:27 -040011305 _Py_BEGIN_SUPPRESS_IPH
11306 result = _Py_set_inheritable(fd, inheritable, NULL);
11307 _Py_END_SUPPRESS_IPH
11308 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011309 return NULL;
11310 Py_RETURN_NONE;
11311}
11312
11313
11314#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011315/*[clinic input]
11316os.get_handle_inheritable -> bool
11317 handle: Py_intptr_t
11318 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011319
Larry Hastings2f936352014-08-05 14:04:04 +100011320Get the close-on-exe flag of the specified file descriptor.
11321[clinic start generated code]*/
11322
Larry Hastings2f936352014-08-05 14:04:04 +100011323static int
11324os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011325/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011326{
11327 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011328
11329 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11330 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011331 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011332 }
11333
Larry Hastings2f936352014-08-05 14:04:04 +100011334 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011335}
11336
Victor Stinnerdaf45552013-08-28 00:53:59 +020011337
Larry Hastings2f936352014-08-05 14:04:04 +100011338/*[clinic input]
11339os.set_handle_inheritable
11340 handle: Py_intptr_t
11341 inheritable: bool
11342 /
11343
11344Set the inheritable flag of the specified handle.
11345[clinic start generated code]*/
11346
Larry Hastings2f936352014-08-05 14:04:04 +100011347static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040011348os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle,
11349 int inheritable)
11350/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011351{
11352 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011353 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11354 PyErr_SetFromWindowsErr(0);
11355 return NULL;
11356 }
11357 Py_RETURN_NONE;
11358}
Larry Hastings2f936352014-08-05 14:04:04 +100011359#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011360
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011361#ifndef MS_WINDOWS
11362PyDoc_STRVAR(get_blocking__doc__,
11363 "get_blocking(fd) -> bool\n" \
11364 "\n" \
11365 "Get the blocking mode of the file descriptor:\n" \
11366 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11367
11368static PyObject*
11369posix_get_blocking(PyObject *self, PyObject *args)
11370{
11371 int fd;
11372 int blocking;
11373
11374 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11375 return NULL;
11376
11377 if (!_PyVerify_fd(fd))
11378 return posix_error();
11379
Steve Dower8fc89802015-04-12 00:26:27 -040011380 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011381 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011382 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011383 if (blocking < 0)
11384 return NULL;
11385 return PyBool_FromLong(blocking);
11386}
11387
11388PyDoc_STRVAR(set_blocking__doc__,
11389 "set_blocking(fd, blocking)\n" \
11390 "\n" \
11391 "Set the blocking mode of the specified file descriptor.\n" \
11392 "Set the O_NONBLOCK flag if blocking is False,\n" \
11393 "clear the O_NONBLOCK flag otherwise.");
11394
11395static PyObject*
11396posix_set_blocking(PyObject *self, PyObject *args)
11397{
Steve Dower8fc89802015-04-12 00:26:27 -040011398 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011399
11400 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11401 return NULL;
11402
11403 if (!_PyVerify_fd(fd))
11404 return posix_error();
11405
Steve Dower8fc89802015-04-12 00:26:27 -040011406 _Py_BEGIN_SUPPRESS_IPH
11407 result = _Py_set_blocking(fd, blocking);
11408 _Py_END_SUPPRESS_IPH
11409 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011410 return NULL;
11411 Py_RETURN_NONE;
11412}
11413#endif /* !MS_WINDOWS */
11414
11415
Victor Stinner6036e442015-03-08 01:58:04 +010011416PyDoc_STRVAR(posix_scandir__doc__,
11417"scandir(path='.') -> iterator of DirEntry objects for given path");
11418
11419static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11420
11421typedef struct {
11422 PyObject_HEAD
11423 PyObject *name;
11424 PyObject *path;
11425 PyObject *stat;
11426 PyObject *lstat;
11427#ifdef MS_WINDOWS
11428 struct _Py_stat_struct win32_lstat;
11429 __int64 win32_file_index;
11430 int got_file_index;
11431#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011432#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011433 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011434#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011435 ino_t d_ino;
11436#endif
11437} DirEntry;
11438
11439static void
11440DirEntry_dealloc(DirEntry *entry)
11441{
11442 Py_XDECREF(entry->name);
11443 Py_XDECREF(entry->path);
11444 Py_XDECREF(entry->stat);
11445 Py_XDECREF(entry->lstat);
11446 Py_TYPE(entry)->tp_free((PyObject *)entry);
11447}
11448
11449/* Forward reference */
11450static int
11451DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11452
11453/* Set exception and return -1 on error, 0 for False, 1 for True */
11454static int
11455DirEntry_is_symlink(DirEntry *self)
11456{
11457#ifdef MS_WINDOWS
11458 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011459#elif defined(HAVE_DIRENT_D_TYPE)
11460 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011461 if (self->d_type != DT_UNKNOWN)
11462 return self->d_type == DT_LNK;
11463 else
11464 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011465#else
11466 /* POSIX without d_type */
11467 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011468#endif
11469}
11470
11471static PyObject *
11472DirEntry_py_is_symlink(DirEntry *self)
11473{
11474 int result;
11475
11476 result = DirEntry_is_symlink(self);
11477 if (result == -1)
11478 return NULL;
11479 return PyBool_FromLong(result);
11480}
11481
11482static PyObject *
11483DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11484{
11485 int result;
11486 struct _Py_stat_struct st;
11487
11488#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011489 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011490
11491 path = PyUnicode_AsUnicode(self->path);
11492 if (!path)
11493 return NULL;
11494
11495 if (follow_symlinks)
11496 result = win32_stat_w(path, &st);
11497 else
11498 result = win32_lstat_w(path, &st);
11499
11500 if (result != 0) {
11501 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11502 0, self->path);
11503 }
11504#else /* POSIX */
11505 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011506 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011507
11508 if (!PyUnicode_FSConverter(self->path, &bytes))
11509 return NULL;
11510 path = PyBytes_AS_STRING(bytes);
11511
11512 if (follow_symlinks)
11513 result = STAT(path, &st);
11514 else
11515 result = LSTAT(path, &st);
11516 Py_DECREF(bytes);
11517
11518 if (result != 0)
11519 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11520#endif
11521
11522 return _pystat_fromstructstat(&st);
11523}
11524
11525static PyObject *
11526DirEntry_get_lstat(DirEntry *self)
11527{
11528 if (!self->lstat) {
11529#ifdef MS_WINDOWS
11530 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11531#else /* POSIX */
11532 self->lstat = DirEntry_fetch_stat(self, 0);
11533#endif
11534 }
11535 Py_XINCREF(self->lstat);
11536 return self->lstat;
11537}
11538
11539static PyObject *
11540DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11541{
11542 if (!follow_symlinks)
11543 return DirEntry_get_lstat(self);
11544
11545 if (!self->stat) {
11546 int result = DirEntry_is_symlink(self);
11547 if (result == -1)
11548 return NULL;
11549 else if (result)
11550 self->stat = DirEntry_fetch_stat(self, 1);
11551 else
11552 self->stat = DirEntry_get_lstat(self);
11553 }
11554
11555 Py_XINCREF(self->stat);
11556 return self->stat;
11557}
11558
11559static PyObject *
11560DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11561{
11562 int follow_symlinks = 1;
11563
11564 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11565 follow_symlinks_keywords, &follow_symlinks))
11566 return NULL;
11567
11568 return DirEntry_get_stat(self, follow_symlinks);
11569}
11570
11571/* Set exception and return -1 on error, 0 for False, 1 for True */
11572static int
11573DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11574{
11575 PyObject *stat = NULL;
11576 PyObject *st_mode = NULL;
11577 long mode;
11578 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011579#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011580 int is_symlink;
11581 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011582#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011583#ifdef MS_WINDOWS
11584 unsigned long dir_bits;
11585#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011586 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011587
11588#ifdef MS_WINDOWS
11589 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11590 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011591#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011592 is_symlink = self->d_type == DT_LNK;
11593 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11594#endif
11595
Victor Stinner35a97c02015-03-08 02:59:09 +010011596#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011597 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011598#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011599 stat = DirEntry_get_stat(self, follow_symlinks);
11600 if (!stat) {
11601 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11602 /* If file doesn't exist (anymore), then return False
11603 (i.e., say it's not a file/directory) */
11604 PyErr_Clear();
11605 return 0;
11606 }
11607 goto error;
11608 }
11609 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11610 if (!st_mode)
11611 goto error;
11612
11613 mode = PyLong_AsLong(st_mode);
11614 if (mode == -1 && PyErr_Occurred())
11615 goto error;
11616 Py_CLEAR(st_mode);
11617 Py_CLEAR(stat);
11618 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011619#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011620 }
11621 else if (is_symlink) {
11622 assert(mode_bits != S_IFLNK);
11623 result = 0;
11624 }
11625 else {
11626 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11627#ifdef MS_WINDOWS
11628 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11629 if (mode_bits == S_IFDIR)
11630 result = dir_bits != 0;
11631 else
11632 result = dir_bits == 0;
11633#else /* POSIX */
11634 if (mode_bits == S_IFDIR)
11635 result = self->d_type == DT_DIR;
11636 else
11637 result = self->d_type == DT_REG;
11638#endif
11639 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011640#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011641
11642 return result;
11643
11644error:
11645 Py_XDECREF(st_mode);
11646 Py_XDECREF(stat);
11647 return -1;
11648}
11649
11650static PyObject *
11651DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11652{
11653 int result;
11654
11655 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11656 if (result == -1)
11657 return NULL;
11658 return PyBool_FromLong(result);
11659}
11660
11661static PyObject *
11662DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11663{
11664 int follow_symlinks = 1;
11665
11666 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11667 follow_symlinks_keywords, &follow_symlinks))
11668 return NULL;
11669
11670 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11671}
11672
11673static PyObject *
11674DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11675{
11676 int follow_symlinks = 1;
11677
11678 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11679 follow_symlinks_keywords, &follow_symlinks))
11680 return NULL;
11681
11682 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11683}
11684
11685static PyObject *
11686DirEntry_inode(DirEntry *self)
11687{
11688#ifdef MS_WINDOWS
11689 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011690 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011691 struct _Py_stat_struct stat;
11692
11693 path = PyUnicode_AsUnicode(self->path);
11694 if (!path)
11695 return NULL;
11696
11697 if (win32_lstat_w(path, &stat) != 0) {
11698 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11699 0, self->path);
11700 }
11701
11702 self->win32_file_index = stat.st_ino;
11703 self->got_file_index = 1;
11704 }
11705 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11706#else /* POSIX */
11707#ifdef HAVE_LARGEFILE_SUPPORT
11708 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11709#else
11710 return PyLong_FromLong((long)self->d_ino);
11711#endif
11712#endif
11713}
11714
11715static PyObject *
11716DirEntry_repr(DirEntry *self)
11717{
11718 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11719}
11720
Brett Cannon96881cd2016-06-10 14:37:21 -070011721static PyObject *
11722DirEntry_fspath(DirEntry *self)
11723{
11724 Py_INCREF(self->path);
11725 return self->path;
11726}
11727
Victor Stinner6036e442015-03-08 01:58:04 +010011728static PyMemberDef DirEntry_members[] = {
11729 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11730 "the entry's base filename, relative to scandir() \"path\" argument"},
11731 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11732 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11733 {NULL}
11734};
11735
11736static PyMethodDef DirEntry_methods[] = {
11737 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11738 "return True if the entry is a directory; cached per entry"
11739 },
11740 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11741 "return True if the entry is a file; cached per entry"
11742 },
11743 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11744 "return True if the entry is a symbolic link; cached per entry"
11745 },
11746 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11747 "return stat_result object for the entry; cached per entry"
11748 },
11749 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11750 "return inode of the entry; cached per entry",
11751 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011752 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11753 "returns the path for the entry",
11754 },
Victor Stinner6036e442015-03-08 01:58:04 +010011755 {NULL}
11756};
11757
Benjamin Peterson5646de42015-04-12 17:56:34 -040011758static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011759 PyVarObject_HEAD_INIT(NULL, 0)
11760 MODNAME ".DirEntry", /* tp_name */
11761 sizeof(DirEntry), /* tp_basicsize */
11762 0, /* tp_itemsize */
11763 /* methods */
11764 (destructor)DirEntry_dealloc, /* tp_dealloc */
11765 0, /* tp_print */
11766 0, /* tp_getattr */
11767 0, /* tp_setattr */
11768 0, /* tp_compare */
11769 (reprfunc)DirEntry_repr, /* tp_repr */
11770 0, /* tp_as_number */
11771 0, /* tp_as_sequence */
11772 0, /* tp_as_mapping */
11773 0, /* tp_hash */
11774 0, /* tp_call */
11775 0, /* tp_str */
11776 0, /* tp_getattro */
11777 0, /* tp_setattro */
11778 0, /* tp_as_buffer */
11779 Py_TPFLAGS_DEFAULT, /* tp_flags */
11780 0, /* tp_doc */
11781 0, /* tp_traverse */
11782 0, /* tp_clear */
11783 0, /* tp_richcompare */
11784 0, /* tp_weaklistoffset */
11785 0, /* tp_iter */
11786 0, /* tp_iternext */
11787 DirEntry_methods, /* tp_methods */
11788 DirEntry_members, /* tp_members */
11789};
11790
11791#ifdef MS_WINDOWS
11792
11793static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011794join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011795{
11796 Py_ssize_t path_len;
11797 Py_ssize_t size;
11798 wchar_t *result;
11799 wchar_t ch;
11800
11801 if (!path_wide) { /* Default arg: "." */
11802 path_wide = L".";
11803 path_len = 1;
11804 }
11805 else {
11806 path_len = wcslen(path_wide);
11807 }
11808
11809 /* The +1's are for the path separator and the NUL */
11810 size = path_len + 1 + wcslen(filename) + 1;
11811 result = PyMem_New(wchar_t, size);
11812 if (!result) {
11813 PyErr_NoMemory();
11814 return NULL;
11815 }
11816 wcscpy(result, path_wide);
11817 if (path_len > 0) {
11818 ch = result[path_len - 1];
11819 if (ch != SEP && ch != ALTSEP && ch != L':')
11820 result[path_len++] = SEP;
11821 wcscpy(result + path_len, filename);
11822 }
11823 return result;
11824}
11825
11826static PyObject *
11827DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11828{
11829 DirEntry *entry;
11830 BY_HANDLE_FILE_INFORMATION file_info;
11831 ULONG reparse_tag;
11832 wchar_t *joined_path;
11833
11834 entry = PyObject_New(DirEntry, &DirEntryType);
11835 if (!entry)
11836 return NULL;
11837 entry->name = NULL;
11838 entry->path = NULL;
11839 entry->stat = NULL;
11840 entry->lstat = NULL;
11841 entry->got_file_index = 0;
11842
11843 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11844 if (!entry->name)
11845 goto error;
11846
11847 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11848 if (!joined_path)
11849 goto error;
11850
11851 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11852 PyMem_Free(joined_path);
11853 if (!entry->path)
11854 goto error;
11855
11856 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11857 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11858
11859 return (PyObject *)entry;
11860
11861error:
11862 Py_DECREF(entry);
11863 return NULL;
11864}
11865
11866#else /* POSIX */
11867
11868static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011869join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011870{
11871 Py_ssize_t path_len;
11872 Py_ssize_t size;
11873 char *result;
11874
11875 if (!path_narrow) { /* Default arg: "." */
11876 path_narrow = ".";
11877 path_len = 1;
11878 }
11879 else {
11880 path_len = strlen(path_narrow);
11881 }
11882
11883 if (filename_len == -1)
11884 filename_len = strlen(filename);
11885
11886 /* The +1's are for the path separator and the NUL */
11887 size = path_len + 1 + filename_len + 1;
11888 result = PyMem_New(char, size);
11889 if (!result) {
11890 PyErr_NoMemory();
11891 return NULL;
11892 }
11893 strcpy(result, path_narrow);
11894 if (path_len > 0 && result[path_len - 1] != '/')
11895 result[path_len++] = '/';
11896 strcpy(result + path_len, filename);
11897 return result;
11898}
11899
11900static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011901DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011902 ino_t d_ino
11903#ifdef HAVE_DIRENT_D_TYPE
11904 , unsigned char d_type
11905#endif
11906 )
Victor Stinner6036e442015-03-08 01:58:04 +010011907{
11908 DirEntry *entry;
11909 char *joined_path;
11910
11911 entry = PyObject_New(DirEntry, &DirEntryType);
11912 if (!entry)
11913 return NULL;
11914 entry->name = NULL;
11915 entry->path = NULL;
11916 entry->stat = NULL;
11917 entry->lstat = NULL;
11918
11919 joined_path = join_path_filename(path->narrow, name, name_len);
11920 if (!joined_path)
11921 goto error;
11922
11923 if (!path->narrow || !PyBytes_Check(path->object)) {
11924 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11925 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11926 }
11927 else {
11928 entry->name = PyBytes_FromStringAndSize(name, name_len);
11929 entry->path = PyBytes_FromString(joined_path);
11930 }
11931 PyMem_Free(joined_path);
11932 if (!entry->name || !entry->path)
11933 goto error;
11934
Victor Stinner35a97c02015-03-08 02:59:09 +010011935#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011936 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011937#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011938 entry->d_ino = d_ino;
11939
11940 return (PyObject *)entry;
11941
11942error:
11943 Py_XDECREF(entry);
11944 return NULL;
11945}
11946
11947#endif
11948
11949
11950typedef struct {
11951 PyObject_HEAD
11952 path_t path;
11953#ifdef MS_WINDOWS
11954 HANDLE handle;
11955 WIN32_FIND_DATAW file_data;
11956 int first_time;
11957#else /* POSIX */
11958 DIR *dirp;
11959#endif
11960} ScandirIterator;
11961
11962#ifdef MS_WINDOWS
11963
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011964static int
11965ScandirIterator_is_closed(ScandirIterator *iterator)
11966{
11967 return iterator->handle == INVALID_HANDLE_VALUE;
11968}
11969
Victor Stinner6036e442015-03-08 01:58:04 +010011970static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011971ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011972{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011973 HANDLE handle = iterator->handle;
11974
11975 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011976 return;
11977
Victor Stinner6036e442015-03-08 01:58:04 +010011978 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011979 Py_BEGIN_ALLOW_THREADS
11980 FindClose(handle);
11981 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011982}
11983
11984static PyObject *
11985ScandirIterator_iternext(ScandirIterator *iterator)
11986{
11987 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11988 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011989 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011990
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011991 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011992 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011993 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011994
11995 while (1) {
11996 if (!iterator->first_time) {
11997 Py_BEGIN_ALLOW_THREADS
11998 success = FindNextFileW(iterator->handle, file_data);
11999 Py_END_ALLOW_THREADS
12000 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012001 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012002 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012003 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012004 break;
12005 }
12006 }
12007 iterator->first_time = 0;
12008
12009 /* Skip over . and .. */
12010 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012011 wcscmp(file_data->cFileName, L"..") != 0) {
12012 entry = DirEntry_from_find_data(&iterator->path, file_data);
12013 if (!entry)
12014 break;
12015 return entry;
12016 }
Victor Stinner6036e442015-03-08 01:58:04 +010012017
12018 /* Loop till we get a non-dot directory or finish iterating */
12019 }
12020
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012021 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012022 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012023 return NULL;
12024}
12025
12026#else /* POSIX */
12027
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012028static int
12029ScandirIterator_is_closed(ScandirIterator *iterator)
12030{
12031 return !iterator->dirp;
12032}
12033
Victor Stinner6036e442015-03-08 01:58:04 +010012034static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012035ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012036{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012037 DIR *dirp = iterator->dirp;
12038
12039 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012040 return;
12041
Victor Stinner6036e442015-03-08 01:58:04 +010012042 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012043 Py_BEGIN_ALLOW_THREADS
12044 closedir(dirp);
12045 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012046 return;
12047}
12048
12049static PyObject *
12050ScandirIterator_iternext(ScandirIterator *iterator)
12051{
12052 struct dirent *direntp;
12053 Py_ssize_t name_len;
12054 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012055 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012056
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012057 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012058 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012059 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012060
12061 while (1) {
12062 errno = 0;
12063 Py_BEGIN_ALLOW_THREADS
12064 direntp = readdir(iterator->dirp);
12065 Py_END_ALLOW_THREADS
12066
12067 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012068 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012069 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012070 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012071 break;
12072 }
12073
12074 /* Skip over . and .. */
12075 name_len = NAMLEN(direntp);
12076 is_dot = direntp->d_name[0] == '.' &&
12077 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12078 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012079 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012080 name_len, direntp->d_ino
12081#ifdef HAVE_DIRENT_D_TYPE
12082 , direntp->d_type
12083#endif
12084 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012085 if (!entry)
12086 break;
12087 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012088 }
12089
12090 /* Loop till we get a non-dot directory or finish iterating */
12091 }
12092
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012093 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012094 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012095 return NULL;
12096}
12097
12098#endif
12099
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012100static PyObject *
12101ScandirIterator_close(ScandirIterator *self, PyObject *args)
12102{
12103 ScandirIterator_closedir(self);
12104 Py_RETURN_NONE;
12105}
12106
12107static PyObject *
12108ScandirIterator_enter(PyObject *self, PyObject *args)
12109{
12110 Py_INCREF(self);
12111 return self;
12112}
12113
12114static PyObject *
12115ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12116{
12117 ScandirIterator_closedir(self);
12118 Py_RETURN_NONE;
12119}
12120
Victor Stinner6036e442015-03-08 01:58:04 +010012121static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012122ScandirIterator_finalize(ScandirIterator *iterator)
12123{
12124 PyObject *error_type, *error_value, *error_traceback;
12125
12126 /* Save the current exception, if any. */
12127 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12128
12129 if (!ScandirIterator_is_closed(iterator)) {
12130 ScandirIterator_closedir(iterator);
12131
12132 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12133 "unclosed scandir iterator %R", iterator)) {
12134 /* Spurious errors can appear at shutdown */
12135 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12136 PyErr_WriteUnraisable((PyObject *) iterator);
12137 }
12138 }
12139 }
12140
12141 Py_CLEAR(iterator->path.object);
12142 path_cleanup(&iterator->path);
12143
12144 /* Restore the saved exception. */
12145 PyErr_Restore(error_type, error_value, error_traceback);
12146}
12147
12148static void
Victor Stinner6036e442015-03-08 01:58:04 +010012149ScandirIterator_dealloc(ScandirIterator *iterator)
12150{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012151 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12152 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012153
Victor Stinner6036e442015-03-08 01:58:04 +010012154 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12155}
12156
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012157static PyMethodDef ScandirIterator_methods[] = {
12158 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12159 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12160 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12161 {NULL}
12162};
12163
Benjamin Peterson5646de42015-04-12 17:56:34 -040012164static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012165 PyVarObject_HEAD_INIT(NULL, 0)
12166 MODNAME ".ScandirIterator", /* tp_name */
12167 sizeof(ScandirIterator), /* tp_basicsize */
12168 0, /* tp_itemsize */
12169 /* methods */
12170 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12171 0, /* tp_print */
12172 0, /* tp_getattr */
12173 0, /* tp_setattr */
12174 0, /* tp_compare */
12175 0, /* tp_repr */
12176 0, /* tp_as_number */
12177 0, /* tp_as_sequence */
12178 0, /* tp_as_mapping */
12179 0, /* tp_hash */
12180 0, /* tp_call */
12181 0, /* tp_str */
12182 0, /* tp_getattro */
12183 0, /* tp_setattro */
12184 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012185 Py_TPFLAGS_DEFAULT
12186 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012187 0, /* tp_doc */
12188 0, /* tp_traverse */
12189 0, /* tp_clear */
12190 0, /* tp_richcompare */
12191 0, /* tp_weaklistoffset */
12192 PyObject_SelfIter, /* tp_iter */
12193 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012194 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012195 0, /* tp_members */
12196 0, /* tp_getset */
12197 0, /* tp_base */
12198 0, /* tp_dict */
12199 0, /* tp_descr_get */
12200 0, /* tp_descr_set */
12201 0, /* tp_dictoffset */
12202 0, /* tp_init */
12203 0, /* tp_alloc */
12204 0, /* tp_new */
12205 0, /* tp_free */
12206 0, /* tp_is_gc */
12207 0, /* tp_bases */
12208 0, /* tp_mro */
12209 0, /* tp_cache */
12210 0, /* tp_subclasses */
12211 0, /* tp_weaklist */
12212 0, /* tp_del */
12213 0, /* tp_version_tag */
12214 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012215};
12216
12217static PyObject *
12218posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12219{
12220 ScandirIterator *iterator;
12221 static char *keywords[] = {"path", NULL};
12222#ifdef MS_WINDOWS
12223 wchar_t *path_strW;
12224#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012225 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010012226#endif
12227
12228 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12229 if (!iterator)
12230 return NULL;
12231 memset(&iterator->path, 0, sizeof(path_t));
12232 iterator->path.function_name = "scandir";
12233 iterator->path.nullable = 1;
12234
12235#ifdef MS_WINDOWS
12236 iterator->handle = INVALID_HANDLE_VALUE;
12237#else
12238 iterator->dirp = NULL;
12239#endif
12240
12241 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12242 path_converter, &iterator->path))
12243 goto error;
12244
12245 /* path_converter doesn't keep path.object around, so do it
12246 manually for the lifetime of the iterator here (the refcount
12247 is decremented in ScandirIterator_dealloc)
12248 */
12249 Py_XINCREF(iterator->path.object);
12250
12251#ifdef MS_WINDOWS
12252 if (iterator->path.narrow) {
12253 PyErr_SetString(PyExc_TypeError,
12254 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12255 goto error;
12256 }
12257 iterator->first_time = 1;
12258
12259 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12260 if (!path_strW)
12261 goto error;
12262
12263 Py_BEGIN_ALLOW_THREADS
12264 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12265 Py_END_ALLOW_THREADS
12266
12267 PyMem_Free(path_strW);
12268
12269 if (iterator->handle == INVALID_HANDLE_VALUE) {
12270 path_error(&iterator->path);
12271 goto error;
12272 }
12273#else /* POSIX */
12274 if (iterator->path.narrow)
12275 path = iterator->path.narrow;
12276 else
12277 path = ".";
12278
12279 errno = 0;
12280 Py_BEGIN_ALLOW_THREADS
12281 iterator->dirp = opendir(path);
12282 Py_END_ALLOW_THREADS
12283
12284 if (!iterator->dirp) {
12285 path_error(&iterator->path);
12286 goto error;
12287 }
12288#endif
12289
12290 return (PyObject *)iterator;
12291
12292error:
12293 Py_DECREF(iterator);
12294 return NULL;
12295}
12296
Ethan Furman410ef8e2016-06-04 12:06:26 -070012297/*
12298 Return the file system path representation of the object.
12299
12300 If the object is str or bytes, then allow it to pass through with
12301 an incremented refcount. If the object defines __fspath__(), then
12302 return the result of that method. All other types raise a TypeError.
12303*/
12304PyObject *
12305PyOS_FSPath(PyObject *path)
12306{
12307 _Py_IDENTIFIER(__fspath__);
12308 PyObject *func = NULL;
12309 PyObject *path_repr = NULL;
12310
12311 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12312 Py_INCREF(path);
12313 return path;
12314 }
12315
12316 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12317 if (NULL == func) {
12318 return PyErr_Format(PyExc_TypeError,
12319 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012320 "not %.200s",
12321 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012322 }
12323
12324 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12325 Py_DECREF(func);
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012326 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12327 PyErr_Format(PyExc_TypeError,
12328 "expected %.200s.__fspath__() to return str or bytes, "
12329 "not %.200s", Py_TYPE(path)->tp_name,
12330 Py_TYPE(path_repr)->tp_name);
12331 Py_DECREF(path_repr);
12332 return NULL;
12333 }
12334
Ethan Furman410ef8e2016-06-04 12:06:26 -070012335 return path_repr;
12336}
12337
12338/*[clinic input]
12339os.fspath
12340
12341 path: object
12342
12343Return the file system path representation of the object.
12344
Brett Cannonb4f43e92016-06-09 14:32:08 -070012345If the object is str or bytes, then allow it to pass through as-is. If the
12346object defines __fspath__(), then return the result of that method. All other
12347types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012348[clinic start generated code]*/
12349
12350static PyObject *
12351os_fspath_impl(PyModuleDef *module, PyObject *path)
Brett Cannonb4f43e92016-06-09 14:32:08 -070012352/*[clinic end generated code: output=51ef0c2772c1932a input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012353{
12354 return PyOS_FSPath(path);
12355}
Victor Stinner6036e442015-03-08 01:58:04 +010012356
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012357#include "clinic/posixmodule.c.h"
12358
Larry Hastings7726ac92014-01-31 22:03:12 -080012359/*[clinic input]
12360dump buffer
12361[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012362/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012363
Larry Hastings31826802013-10-19 00:09:25 -070012364
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012365static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012366
12367 OS_STAT_METHODDEF
12368 OS_ACCESS_METHODDEF
12369 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012370 OS_CHDIR_METHODDEF
12371 OS_CHFLAGS_METHODDEF
12372 OS_CHMOD_METHODDEF
12373 OS_FCHMOD_METHODDEF
12374 OS_LCHMOD_METHODDEF
12375 OS_CHOWN_METHODDEF
12376 OS_FCHOWN_METHODDEF
12377 OS_LCHOWN_METHODDEF
12378 OS_LCHFLAGS_METHODDEF
12379 OS_CHROOT_METHODDEF
12380 OS_CTERMID_METHODDEF
12381 OS_GETCWD_METHODDEF
12382 OS_GETCWDB_METHODDEF
12383 OS_LINK_METHODDEF
12384 OS_LISTDIR_METHODDEF
12385 OS_LSTAT_METHODDEF
12386 OS_MKDIR_METHODDEF
12387 OS_NICE_METHODDEF
12388 OS_GETPRIORITY_METHODDEF
12389 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012390#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012391 {"readlink", (PyCFunction)posix_readlink,
12392 METH_VARARGS | METH_KEYWORDS,
12393 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012394#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012395#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012396 {"readlink", (PyCFunction)win_readlink,
12397 METH_VARARGS | METH_KEYWORDS,
12398 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012399#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012400 OS_RENAME_METHODDEF
12401 OS_REPLACE_METHODDEF
12402 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012403 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012404 OS_SYMLINK_METHODDEF
12405 OS_SYSTEM_METHODDEF
12406 OS_UMASK_METHODDEF
12407 OS_UNAME_METHODDEF
12408 OS_UNLINK_METHODDEF
12409 OS_REMOVE_METHODDEF
12410 OS_UTIME_METHODDEF
12411 OS_TIMES_METHODDEF
12412 OS__EXIT_METHODDEF
12413 OS_EXECV_METHODDEF
12414 OS_EXECVE_METHODDEF
12415 OS_SPAWNV_METHODDEF
12416 OS_SPAWNVE_METHODDEF
12417 OS_FORK1_METHODDEF
12418 OS_FORK_METHODDEF
12419 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12420 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12421 OS_SCHED_GETPARAM_METHODDEF
12422 OS_SCHED_GETSCHEDULER_METHODDEF
12423 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12424 OS_SCHED_SETPARAM_METHODDEF
12425 OS_SCHED_SETSCHEDULER_METHODDEF
12426 OS_SCHED_YIELD_METHODDEF
12427 OS_SCHED_SETAFFINITY_METHODDEF
12428 OS_SCHED_GETAFFINITY_METHODDEF
12429 OS_OPENPTY_METHODDEF
12430 OS_FORKPTY_METHODDEF
12431 OS_GETEGID_METHODDEF
12432 OS_GETEUID_METHODDEF
12433 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012434#ifdef HAVE_GETGROUPLIST
12435 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12436#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012437 OS_GETGROUPS_METHODDEF
12438 OS_GETPID_METHODDEF
12439 OS_GETPGRP_METHODDEF
12440 OS_GETPPID_METHODDEF
12441 OS_GETUID_METHODDEF
12442 OS_GETLOGIN_METHODDEF
12443 OS_KILL_METHODDEF
12444 OS_KILLPG_METHODDEF
12445 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012446#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012447 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012448#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012449 OS_SETUID_METHODDEF
12450 OS_SETEUID_METHODDEF
12451 OS_SETREUID_METHODDEF
12452 OS_SETGID_METHODDEF
12453 OS_SETEGID_METHODDEF
12454 OS_SETREGID_METHODDEF
12455 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012456#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012457 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012458#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012459 OS_GETPGID_METHODDEF
12460 OS_SETPGRP_METHODDEF
12461 OS_WAIT_METHODDEF
12462 OS_WAIT3_METHODDEF
12463 OS_WAIT4_METHODDEF
12464 OS_WAITID_METHODDEF
12465 OS_WAITPID_METHODDEF
12466 OS_GETSID_METHODDEF
12467 OS_SETSID_METHODDEF
12468 OS_SETPGID_METHODDEF
12469 OS_TCGETPGRP_METHODDEF
12470 OS_TCSETPGRP_METHODDEF
12471 OS_OPEN_METHODDEF
12472 OS_CLOSE_METHODDEF
12473 OS_CLOSERANGE_METHODDEF
12474 OS_DEVICE_ENCODING_METHODDEF
12475 OS_DUP_METHODDEF
12476 OS_DUP2_METHODDEF
12477 OS_LOCKF_METHODDEF
12478 OS_LSEEK_METHODDEF
12479 OS_READ_METHODDEF
12480 OS_READV_METHODDEF
12481 OS_PREAD_METHODDEF
12482 OS_WRITE_METHODDEF
12483 OS_WRITEV_METHODDEF
12484 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012485#ifdef HAVE_SENDFILE
12486 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12487 posix_sendfile__doc__},
12488#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012489 OS_FSTAT_METHODDEF
12490 OS_ISATTY_METHODDEF
12491 OS_PIPE_METHODDEF
12492 OS_PIPE2_METHODDEF
12493 OS_MKFIFO_METHODDEF
12494 OS_MKNOD_METHODDEF
12495 OS_MAJOR_METHODDEF
12496 OS_MINOR_METHODDEF
12497 OS_MAKEDEV_METHODDEF
12498 OS_FTRUNCATE_METHODDEF
12499 OS_TRUNCATE_METHODDEF
12500 OS_POSIX_FALLOCATE_METHODDEF
12501 OS_POSIX_FADVISE_METHODDEF
12502 OS_PUTENV_METHODDEF
12503 OS_UNSETENV_METHODDEF
12504 OS_STRERROR_METHODDEF
12505 OS_FCHDIR_METHODDEF
12506 OS_FSYNC_METHODDEF
12507 OS_SYNC_METHODDEF
12508 OS_FDATASYNC_METHODDEF
12509 OS_WCOREDUMP_METHODDEF
12510 OS_WIFCONTINUED_METHODDEF
12511 OS_WIFSTOPPED_METHODDEF
12512 OS_WIFSIGNALED_METHODDEF
12513 OS_WIFEXITED_METHODDEF
12514 OS_WEXITSTATUS_METHODDEF
12515 OS_WTERMSIG_METHODDEF
12516 OS_WSTOPSIG_METHODDEF
12517 OS_FSTATVFS_METHODDEF
12518 OS_STATVFS_METHODDEF
12519 OS_CONFSTR_METHODDEF
12520 OS_SYSCONF_METHODDEF
12521 OS_FPATHCONF_METHODDEF
12522 OS_PATHCONF_METHODDEF
12523 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012524 OS__GETFULLPATHNAME_METHODDEF
12525 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012526 OS__GETDISKUSAGE_METHODDEF
12527 OS__GETFINALPATHNAME_METHODDEF
12528 OS__GETVOLUMEPATHNAME_METHODDEF
12529 OS_GETLOADAVG_METHODDEF
12530 OS_URANDOM_METHODDEF
12531 OS_SETRESUID_METHODDEF
12532 OS_SETRESGID_METHODDEF
12533 OS_GETRESUID_METHODDEF
12534 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012535
Larry Hastings2f936352014-08-05 14:04:04 +100012536 OS_GETXATTR_METHODDEF
12537 OS_SETXATTR_METHODDEF
12538 OS_REMOVEXATTR_METHODDEF
12539 OS_LISTXATTR_METHODDEF
12540
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012541#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12542 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12543#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012544 OS_CPU_COUNT_METHODDEF
12545 OS_GET_INHERITABLE_METHODDEF
12546 OS_SET_INHERITABLE_METHODDEF
12547 OS_GET_HANDLE_INHERITABLE_METHODDEF
12548 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012549#ifndef MS_WINDOWS
12550 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12551 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12552#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012553 {"scandir", (PyCFunction)posix_scandir,
12554 METH_VARARGS | METH_KEYWORDS,
12555 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012556 OS_FSPATH_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012557 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012558};
12559
12560
Brian Curtin52173d42010-12-02 18:29:18 +000012561#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012562static int
Brian Curtin52173d42010-12-02 18:29:18 +000012563enable_symlink()
12564{
12565 HANDLE tok;
12566 TOKEN_PRIVILEGES tok_priv;
12567 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012568
12569 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012570 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012571
12572 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012573 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012574
12575 tok_priv.PrivilegeCount = 1;
12576 tok_priv.Privileges[0].Luid = luid;
12577 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12578
12579 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12580 sizeof(TOKEN_PRIVILEGES),
12581 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012582 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012583
Brian Curtin3b4499c2010-12-28 14:31:47 +000012584 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12585 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012586}
12587#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12588
Barry Warsaw4a342091996-12-19 23:50:02 +000012589static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012591{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012592#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012594#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012595#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012597#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012598#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012600#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012601#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012603#endif
Fred Drakec9680921999-12-13 16:37:25 +000012604#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012606#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012607#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012609#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012610#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012612#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012613#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012615#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012616#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012618#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012619#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012621#endif
12622#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012624#endif
12625#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012626 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012627#endif
12628#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012629 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012630#endif
12631#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012633#endif
12634#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012636#endif
12637#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012639#endif
12640#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012642#endif
12643#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012645#endif
12646#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012648#endif
12649#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012651#endif
12652#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012654#endif
12655#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012657#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012658#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012660#endif
12661#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012663#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012664#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012666#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012667#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012669#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012670#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012671#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012673#endif
12674#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012676#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012677#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012678#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012679 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012680#endif
12681#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012682 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012683#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012684#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012685 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012686#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012687#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012689#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012690#ifdef O_TMPFILE
12691 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12692#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012693#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012695#endif
12696#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012698#endif
12699#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012701#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012702#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012704#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012705#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012707#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012708
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012709
Jesus Cea94363612012-06-22 18:32:07 +020012710#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012712#endif
12713#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012715#endif
12716
Tim Peters5aa91602002-01-30 05:46:57 +000012717/* MS Windows */
12718#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012719 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012721#endif
12722#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012723 /* Optimize for short life (keep in memory). */
12724 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012726#endif
12727#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012728 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012730#endif
12731#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012732 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012733 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012734#endif
12735#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012736 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012738#endif
12739
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012740/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012741#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012742 /* Send a SIGIO signal whenever input or output
12743 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012745#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012746#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012747 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012748 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012749#endif
12750#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012751 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012753#endif
12754#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012755 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012757#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012758#ifdef O_NOLINKS
12759 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012761#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012762#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012763 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012765#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012766
Victor Stinner8c62be82010-05-06 00:08:46 +000012767 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012768#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012770#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012771#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012773#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012774#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012776#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012777#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012778 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012779#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012780#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012781 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012782#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012783#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012784 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012785#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012786#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012787 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012788#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012789#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012790 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012791#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012792#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012793 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012794#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012795#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012796 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012797#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012798#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012800#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012801#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012802 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012803#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012804#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012805 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012806#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012807#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012809#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012810#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012812#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012813#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012814 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012815#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012816#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012817 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012818#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012819
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012820 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012821#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012822 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012823#endif /* ST_RDONLY */
12824#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012825 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012826#endif /* ST_NOSUID */
12827
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012828 /* GNU extensions */
12829#ifdef ST_NODEV
12830 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12831#endif /* ST_NODEV */
12832#ifdef ST_NOEXEC
12833 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12834#endif /* ST_NOEXEC */
12835#ifdef ST_SYNCHRONOUS
12836 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12837#endif /* ST_SYNCHRONOUS */
12838#ifdef ST_MANDLOCK
12839 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12840#endif /* ST_MANDLOCK */
12841#ifdef ST_WRITE
12842 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12843#endif /* ST_WRITE */
12844#ifdef ST_APPEND
12845 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12846#endif /* ST_APPEND */
12847#ifdef ST_NOATIME
12848 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12849#endif /* ST_NOATIME */
12850#ifdef ST_NODIRATIME
12851 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12852#endif /* ST_NODIRATIME */
12853#ifdef ST_RELATIME
12854 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12855#endif /* ST_RELATIME */
12856
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012857 /* FreeBSD sendfile() constants */
12858#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012859 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012860#endif
12861#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012862 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012863#endif
12864#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012866#endif
12867
Ross Lagerwall7807c352011-03-17 20:20:30 +020012868 /* constants for posix_fadvise */
12869#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012870 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012871#endif
12872#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012873 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012874#endif
12875#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012876 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012877#endif
12878#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012879 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012880#endif
12881#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012882 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012883#endif
12884#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012885 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012886#endif
12887
12888 /* constants for waitid */
12889#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012890 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12891 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12892 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012893#endif
12894#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012895 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012896#endif
12897#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012898 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012899#endif
12900#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012901 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012902#endif
12903#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012904 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012905#endif
12906#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012907 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012908#endif
12909#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012910 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012911#endif
12912#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012913 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012914#endif
12915
12916 /* constants for lockf */
12917#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012918 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012919#endif
12920#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012921 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012922#endif
12923#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012924 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012925#endif
12926#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012928#endif
12929
Guido van Rossum246bc171999-02-01 23:54:31 +000012930#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012931 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12932 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12933 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12934 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12935 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012936#endif
12937
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012938#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012939 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12940 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12941 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012942#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012943 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012944#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012945#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012946 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012947#endif
12948#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012949 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012950#endif
12951#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012952 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012953#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012954#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012955 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012956#endif
12957#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012958 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012959#endif
12960#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012961 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012962#endif
12963#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012964 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012965#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012966#endif
12967
Benjamin Peterson9428d532011-09-14 11:45:52 -040012968#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12970 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12971 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012972#endif
12973
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012974#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012975 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012976#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012977#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012978 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012979#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012980#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012981 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012982#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012983#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012984 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012985#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012986#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012987 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012988#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012989#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012990 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012991#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012992#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012993 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012994#endif
12995
Victor Stinner8c62be82010-05-06 00:08:46 +000012996 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012997}
12998
12999
Martin v. Löwis1a214512008-06-11 05:26:20 +000013000static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 PyModuleDef_HEAD_INIT,
13002 MODNAME,
13003 posix__doc__,
13004 -1,
13005 posix_methods,
13006 NULL,
13007 NULL,
13008 NULL,
13009 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013010};
13011
13012
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013013static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013014
13015#ifdef HAVE_FACCESSAT
13016 "HAVE_FACCESSAT",
13017#endif
13018
13019#ifdef HAVE_FCHDIR
13020 "HAVE_FCHDIR",
13021#endif
13022
13023#ifdef HAVE_FCHMOD
13024 "HAVE_FCHMOD",
13025#endif
13026
13027#ifdef HAVE_FCHMODAT
13028 "HAVE_FCHMODAT",
13029#endif
13030
13031#ifdef HAVE_FCHOWN
13032 "HAVE_FCHOWN",
13033#endif
13034
Larry Hastings00964ed2013-08-12 13:49:30 -040013035#ifdef HAVE_FCHOWNAT
13036 "HAVE_FCHOWNAT",
13037#endif
13038
Larry Hastings9cf065c2012-06-22 16:30:09 -070013039#ifdef HAVE_FEXECVE
13040 "HAVE_FEXECVE",
13041#endif
13042
13043#ifdef HAVE_FDOPENDIR
13044 "HAVE_FDOPENDIR",
13045#endif
13046
Georg Brandl306336b2012-06-24 12:55:33 +020013047#ifdef HAVE_FPATHCONF
13048 "HAVE_FPATHCONF",
13049#endif
13050
Larry Hastings9cf065c2012-06-22 16:30:09 -070013051#ifdef HAVE_FSTATAT
13052 "HAVE_FSTATAT",
13053#endif
13054
13055#ifdef HAVE_FSTATVFS
13056 "HAVE_FSTATVFS",
13057#endif
13058
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013059#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013060 "HAVE_FTRUNCATE",
13061#endif
13062
Larry Hastings9cf065c2012-06-22 16:30:09 -070013063#ifdef HAVE_FUTIMENS
13064 "HAVE_FUTIMENS",
13065#endif
13066
13067#ifdef HAVE_FUTIMES
13068 "HAVE_FUTIMES",
13069#endif
13070
13071#ifdef HAVE_FUTIMESAT
13072 "HAVE_FUTIMESAT",
13073#endif
13074
13075#ifdef HAVE_LINKAT
13076 "HAVE_LINKAT",
13077#endif
13078
13079#ifdef HAVE_LCHFLAGS
13080 "HAVE_LCHFLAGS",
13081#endif
13082
13083#ifdef HAVE_LCHMOD
13084 "HAVE_LCHMOD",
13085#endif
13086
13087#ifdef HAVE_LCHOWN
13088 "HAVE_LCHOWN",
13089#endif
13090
13091#ifdef HAVE_LSTAT
13092 "HAVE_LSTAT",
13093#endif
13094
13095#ifdef HAVE_LUTIMES
13096 "HAVE_LUTIMES",
13097#endif
13098
13099#ifdef HAVE_MKDIRAT
13100 "HAVE_MKDIRAT",
13101#endif
13102
13103#ifdef HAVE_MKFIFOAT
13104 "HAVE_MKFIFOAT",
13105#endif
13106
13107#ifdef HAVE_MKNODAT
13108 "HAVE_MKNODAT",
13109#endif
13110
13111#ifdef HAVE_OPENAT
13112 "HAVE_OPENAT",
13113#endif
13114
13115#ifdef HAVE_READLINKAT
13116 "HAVE_READLINKAT",
13117#endif
13118
13119#ifdef HAVE_RENAMEAT
13120 "HAVE_RENAMEAT",
13121#endif
13122
13123#ifdef HAVE_SYMLINKAT
13124 "HAVE_SYMLINKAT",
13125#endif
13126
13127#ifdef HAVE_UNLINKAT
13128 "HAVE_UNLINKAT",
13129#endif
13130
13131#ifdef HAVE_UTIMENSAT
13132 "HAVE_UTIMENSAT",
13133#endif
13134
13135#ifdef MS_WINDOWS
13136 "MS_WINDOWS",
13137#endif
13138
13139 NULL
13140};
13141
13142
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013143PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013144INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013145{
Victor Stinner8c62be82010-05-06 00:08:46 +000013146 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013147 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013148 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013149
Brian Curtin52173d42010-12-02 18:29:18 +000013150#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013151 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013152#endif
13153
Victor Stinner8c62be82010-05-06 00:08:46 +000013154 m = PyModule_Create(&posixmodule);
13155 if (m == NULL)
13156 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013157
Victor Stinner8c62be82010-05-06 00:08:46 +000013158 /* Initialize environ dictionary */
13159 v = convertenviron();
13160 Py_XINCREF(v);
13161 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13162 return NULL;
13163 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013164
Victor Stinner8c62be82010-05-06 00:08:46 +000013165 if (all_ins(m))
13166 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013167
Victor Stinner8c62be82010-05-06 00:08:46 +000013168 if (setup_confname_tables(m))
13169 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013170
Victor Stinner8c62be82010-05-06 00:08:46 +000013171 Py_INCREF(PyExc_OSError);
13172 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013173
Guido van Rossumb3d39562000-01-31 18:41:26 +000013174#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013175 if (posix_putenv_garbage == NULL)
13176 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013177#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013178
Victor Stinner8c62be82010-05-06 00:08:46 +000013179 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013180#if defined(HAVE_WAITID) && !defined(__APPLE__)
13181 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013182 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13183 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013184#endif
13185
Christian Heimes25827622013-10-12 01:27:08 +020013186 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013187 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13188 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13189 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013190 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13191 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013192 structseq_new = StatResultType.tp_new;
13193 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013194
Christian Heimes25827622013-10-12 01:27:08 +020013195 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013196 if (PyStructSequence_InitType2(&StatVFSResultType,
13197 &statvfs_result_desc) < 0)
13198 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013199#ifdef NEED_TICKS_PER_SECOND
13200# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013201 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013202# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013203 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013204# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013205 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013206# endif
13207#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013208
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013209#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013211 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13212 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013213 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013214#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013215
13216 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013217 if (PyStructSequence_InitType2(&TerminalSizeType,
13218 &TerminalSize_desc) < 0)
13219 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013220
13221 /* initialize scandir types */
13222 if (PyType_Ready(&ScandirIteratorType) < 0)
13223 return NULL;
13224 if (PyType_Ready(&DirEntryType) < 0)
13225 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013226 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013227#if defined(HAVE_WAITID) && !defined(__APPLE__)
13228 Py_INCREF((PyObject*) &WaitidResultType);
13229 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13230#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013231 Py_INCREF((PyObject*) &StatResultType);
13232 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13233 Py_INCREF((PyObject*) &StatVFSResultType);
13234 PyModule_AddObject(m, "statvfs_result",
13235 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013236
13237#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013238 Py_INCREF(&SchedParamType);
13239 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013240#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013241
Larry Hastings605a62d2012-06-24 04:33:36 -070013242 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013243 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13244 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013245 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13246
13247 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013248 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13249 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013250 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13251
Thomas Wouters477c8d52006-05-27 19:21:47 +000013252#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013253 /*
13254 * Step 2 of weak-linking support on Mac OS X.
13255 *
13256 * The code below removes functions that are not available on the
13257 * currently active platform.
13258 *
13259 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013260 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013261 * OSX 10.4.
13262 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013263#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013264 if (fstatvfs == NULL) {
13265 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13266 return NULL;
13267 }
13268 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013269#endif /* HAVE_FSTATVFS */
13270
13271#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013272 if (statvfs == NULL) {
13273 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13274 return NULL;
13275 }
13276 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013277#endif /* HAVE_STATVFS */
13278
13279# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013280 if (lchown == NULL) {
13281 if (PyObject_DelAttrString(m, "lchown") == -1) {
13282 return NULL;
13283 }
13284 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013285#endif /* HAVE_LCHOWN */
13286
13287
13288#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013289
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013290 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013291 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13292
Larry Hastings6fe20b32012-04-19 15:07:49 -070013293 billion = PyLong_FromLong(1000000000);
13294 if (!billion)
13295 return NULL;
13296
Larry Hastings9cf065c2012-06-22 16:30:09 -070013297 /* suppress "function not used" warnings */
13298 {
13299 int ignored;
13300 fd_specified("", -1);
13301 follow_symlinks_specified("", 1);
13302 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13303 dir_fd_converter(Py_None, &ignored);
13304 dir_fd_unavailable(Py_None, &ignored);
13305 }
13306
13307 /*
13308 * provide list of locally available functions
13309 * so os.py can populate support_* lists
13310 */
13311 list = PyList_New(0);
13312 if (!list)
13313 return NULL;
13314 for (trace = have_functions; *trace; trace++) {
13315 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13316 if (!unicode)
13317 return NULL;
13318 if (PyList_Append(list, unicode))
13319 return NULL;
13320 Py_DECREF(unicode);
13321 }
13322 PyModule_AddObject(m, "_have_functions", list);
Brett Cannona32c4d02016-06-24 14:14:44 -070013323 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013324
13325 initialized = 1;
13326
Victor Stinner8c62be82010-05-06 00:08:46 +000013327 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013328}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013329
13330#ifdef __cplusplus
13331}
13332#endif