blob: 6adc7f44dbf42654976f52407b3578c6e5ed26e7 [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{
Martin Panter70214ad2016-08-04 02:38:59 +00001109 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1110 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_REPARSE_DATA_BUFFER *)target_buffer;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001111 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002493os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2494/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002495{
2496 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2497}
2498
Larry Hastings2f936352014-08-05 14:04:04 +10002499
2500/*[clinic input]
2501os.lstat
2502
2503 path : path_t
2504
2505 *
2506
2507 dir_fd : dir_fd(requires='fstatat') = None
2508
2509Perform a stat system call on the given path, without following symbolic links.
2510
2511Like stat(), but do not follow symbolic links.
2512Equivalent to stat(path, follow_symlinks=False).
2513[clinic start generated code]*/
2514
Larry Hastings2f936352014-08-05 14:04:04 +10002515static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002516os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2517/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002518{
2519 int follow_symlinks = 0;
2520 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2521}
Larry Hastings31826802013-10-19 00:09:25 -07002522
Larry Hastings2f936352014-08-05 14:04:04 +10002523
Larry Hastings61272b72014-01-07 12:41:53 -08002524/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002525os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002526
2527 path: path_t(allow_fd=True)
2528 Path to be tested; can be string, bytes, or open-file-descriptor int.
2529
2530 mode: int
2531 Operating-system mode bitfield. Can be F_OK to test existence,
2532 or the inclusive-OR of R_OK, W_OK, and X_OK.
2533
2534 *
2535
Larry Hastings2f936352014-08-05 14:04:04 +10002536 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002537 If not None, it should be a file descriptor open to a directory,
2538 and path should be relative; path will then be relative to that
2539 directory.
2540
2541 effective_ids: bool = False
2542 If True, access will use the effective uid/gid instead of
2543 the real uid/gid.
2544
2545 follow_symlinks: bool = True
2546 If False, and the last element of the path is a symbolic link,
2547 access will examine the symbolic link itself instead of the file
2548 the link points to.
2549
2550Use the real uid/gid to test for access to a path.
2551
2552{parameters}
2553dir_fd, effective_ids, and follow_symlinks may not be implemented
2554 on your platform. If they are unavailable, using them will raise a
2555 NotImplementedError.
2556
2557Note that most operations will use the effective uid/gid, therefore this
2558 routine can be used in a suid/sgid environment to test if the invoking user
2559 has the specified access to the path.
2560
Larry Hastings61272b72014-01-07 12:41:53 -08002561[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002562
Larry Hastings2f936352014-08-05 14:04:04 +10002563static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002564os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002565 int effective_ids, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002566/*[clinic end generated code: output=cf84158bc90b1a77 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002567{
Larry Hastings2f936352014-08-05 14:04:04 +10002568 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002569
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002570#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002571 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002572#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002573 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002574#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576#ifndef HAVE_FACCESSAT
2577 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002578 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002579
2580 if (effective_ids) {
2581 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002582 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002583 }
2584#endif
2585
2586#ifdef MS_WINDOWS
2587 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002588 if (path->wide != NULL)
2589 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002590 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002591 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002592 Py_END_ALLOW_THREADS
2593
2594 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002595 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596 * * we didn't get a -1, and
2597 * * write access wasn't requested,
2598 * * or the file isn't read-only,
2599 * * or it's a directory.
2600 * (Directories cannot be read-only on Windows.)
2601 */
Larry Hastings2f936352014-08-05 14:04:04 +10002602 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002603 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002605 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002606#else
2607
2608 Py_BEGIN_ALLOW_THREADS
2609#ifdef HAVE_FACCESSAT
2610 if ((dir_fd != DEFAULT_DIR_FD) ||
2611 effective_ids ||
2612 !follow_symlinks) {
2613 int flags = 0;
2614 if (!follow_symlinks)
2615 flags |= AT_SYMLINK_NOFOLLOW;
2616 if (effective_ids)
2617 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002618 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619 }
2620 else
2621#endif
Larry Hastings31826802013-10-19 00:09:25 -07002622 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002623 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002624 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002625#endif
2626
Larry Hastings9cf065c2012-06-22 16:30:09 -07002627 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002628}
2629
Guido van Rossumd371ff11999-01-25 16:12:23 +00002630#ifndef F_OK
2631#define F_OK 0
2632#endif
2633#ifndef R_OK
2634#define R_OK 4
2635#endif
2636#ifndef W_OK
2637#define W_OK 2
2638#endif
2639#ifndef X_OK
2640#define X_OK 1
2641#endif
2642
Larry Hastings31826802013-10-19 00:09:25 -07002643
Guido van Rossumd371ff11999-01-25 16:12:23 +00002644#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002645/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002646os.ttyname -> DecodeFSDefault
2647
2648 fd: int
2649 Integer file descriptor handle.
2650
2651 /
2652
2653Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002654[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002655
Larry Hastings31826802013-10-19 00:09:25 -07002656static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002657os_ttyname_impl(PyObject *module, int fd)
2658/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002659{
2660 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002661
Larry Hastings31826802013-10-19 00:09:25 -07002662 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002663 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002664 posix_error();
2665 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002666}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002667#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002668
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002669#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002670/*[clinic input]
2671os.ctermid
2672
2673Return the name of the controlling terminal for this process.
2674[clinic start generated code]*/
2675
Larry Hastings2f936352014-08-05 14:04:04 +10002676static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002677os_ctermid_impl(PyObject *module)
2678/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679{
Victor Stinner8c62be82010-05-06 00:08:46 +00002680 char *ret;
2681 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002682
Greg Wardb48bc172000-03-01 21:51:56 +00002683#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002684 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002685#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002686 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002687#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002688 if (ret == NULL)
2689 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002690 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002691}
Larry Hastings2f936352014-08-05 14:04:04 +10002692#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002693
Larry Hastings2f936352014-08-05 14:04:04 +10002694
2695/*[clinic input]
2696os.chdir
2697
2698 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2699
2700Change the current working directory to the specified path.
2701
2702path may always be specified as a string.
2703On some platforms, path may also be specified as an open file descriptor.
2704 If this functionality is unavailable, using it raises an exception.
2705[clinic start generated code]*/
2706
Larry Hastings2f936352014-08-05 14:04:04 +10002707static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002708os_chdir_impl(PyObject *module, path_t *path)
2709/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002710{
2711 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712
2713 Py_BEGIN_ALLOW_THREADS
2714#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002715 if (path->wide)
2716 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717 else
Larry Hastings2f936352014-08-05 14:04:04 +10002718 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002719 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002720#else
2721#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002722 if (path->fd != -1)
2723 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724 else
2725#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002726 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002727#endif
2728 Py_END_ALLOW_THREADS
2729
2730 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002731 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002732 }
2733
Larry Hastings2f936352014-08-05 14:04:04 +10002734 Py_RETURN_NONE;
2735}
2736
2737
2738#ifdef HAVE_FCHDIR
2739/*[clinic input]
2740os.fchdir
2741
2742 fd: fildes
2743
2744Change to the directory of the given file descriptor.
2745
2746fd must be opened on a directory, not a file.
2747Equivalent to os.chdir(fd).
2748
2749[clinic start generated code]*/
2750
Fred Drake4d1e64b2002-04-15 19:40:07 +00002751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002752os_fchdir_impl(PyObject *module, int fd)
2753/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002754{
Larry Hastings2f936352014-08-05 14:04:04 +10002755 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002756}
2757#endif /* HAVE_FCHDIR */
2758
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002759
Larry Hastings2f936352014-08-05 14:04:04 +10002760/*[clinic input]
2761os.chmod
2762
2763 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2764 Path to be modified. May always be specified as a str or bytes.
2765 On some platforms, path may also be specified as an open file descriptor.
2766 If this functionality is unavailable, using it raises an exception.
2767
2768 mode: int
2769 Operating-system mode bitfield.
2770
2771 *
2772
2773 dir_fd : dir_fd(requires='fchmodat') = None
2774 If not None, it should be a file descriptor open to a directory,
2775 and path should be relative; path will then be relative to that
2776 directory.
2777
2778 follow_symlinks: bool = True
2779 If False, and the last element of the path is a symbolic link,
2780 chmod will modify the symbolic link itself instead of the file
2781 the link points to.
2782
2783Change the access permissions of a file.
2784
2785It is an error to use dir_fd or follow_symlinks when specifying path as
2786 an open file descriptor.
2787dir_fd and follow_symlinks may not be implemented on your platform.
2788 If they are unavailable, using them will raise a NotImplementedError.
2789
2790[clinic start generated code]*/
2791
Larry Hastings2f936352014-08-05 14:04:04 +10002792static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002793os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002794 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002795/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002796{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002799#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002800 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002801#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002802
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803#ifdef HAVE_FCHMODAT
2804 int fchmodat_nofollow_unsupported = 0;
2805#endif
2806
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2808 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002809 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002810#endif
2811
2812#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002813 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002814 if (path->wide)
2815 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 else
Larry Hastings2f936352014-08-05 14:04:04 +10002817 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002818 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 result = 0;
2820 else {
2821 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002822 attr &= ~FILE_ATTRIBUTE_READONLY;
2823 else
2824 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002825 if (path->wide)
2826 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002827 else
Larry Hastings2f936352014-08-05 14:04:04 +10002828 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 }
2830 Py_END_ALLOW_THREADS
2831
2832 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002833 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002834 }
2835#else /* MS_WINDOWS */
2836 Py_BEGIN_ALLOW_THREADS
2837#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002838 if (path->fd != -1)
2839 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840 else
2841#endif
2842#ifdef HAVE_LCHMOD
2843 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002844 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002845 else
2846#endif
2847#ifdef HAVE_FCHMODAT
2848 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2849 /*
2850 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2851 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002852 * and then says it isn't implemented yet.
2853 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002854 *
2855 * Once it is supported, os.chmod will automatically
2856 * support dir_fd and follow_symlinks=False. (Hopefully.)
2857 * Until then, we need to be careful what exception we raise.
2858 */
Larry Hastings2f936352014-08-05 14:04:04 +10002859 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002860 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2861 /*
2862 * But wait! We can't throw the exception without allowing threads,
2863 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2864 */
2865 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002866 result &&
2867 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2868 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002869 }
2870 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002871#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002872 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002873 Py_END_ALLOW_THREADS
2874
2875 if (result) {
2876#ifdef HAVE_FCHMODAT
2877 if (fchmodat_nofollow_unsupported) {
2878 if (dir_fd != DEFAULT_DIR_FD)
2879 dir_fd_and_follow_symlinks_invalid("chmod",
2880 dir_fd, follow_symlinks);
2881 else
2882 follow_symlinks_specified("chmod", follow_symlinks);
2883 }
2884 else
2885#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002886 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002887 }
2888#endif
2889
Larry Hastings2f936352014-08-05 14:04:04 +10002890 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002891}
2892
Larry Hastings9cf065c2012-06-22 16:30:09 -07002893
Christian Heimes4e30a842007-11-30 22:12:06 +00002894#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002895/*[clinic input]
2896os.fchmod
2897
2898 fd: int
2899 mode: int
2900
2901Change the access permissions of the file given by file descriptor fd.
2902
2903Equivalent to os.chmod(fd, mode).
2904[clinic start generated code]*/
2905
Larry Hastings2f936352014-08-05 14:04:04 +10002906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002907os_fchmod_impl(PyObject *module, int fd, int mode)
2908/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002909{
2910 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002911 int async_err = 0;
2912
2913 do {
2914 Py_BEGIN_ALLOW_THREADS
2915 res = fchmod(fd, mode);
2916 Py_END_ALLOW_THREADS
2917 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2918 if (res != 0)
2919 return (!async_err) ? posix_error() : NULL;
2920
Victor Stinner8c62be82010-05-06 00:08:46 +00002921 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002922}
2923#endif /* HAVE_FCHMOD */
2924
Larry Hastings2f936352014-08-05 14:04:04 +10002925
Christian Heimes4e30a842007-11-30 22:12:06 +00002926#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002927/*[clinic input]
2928os.lchmod
2929
2930 path: path_t
2931 mode: int
2932
2933Change the access permissions of a file, without following symbolic links.
2934
2935If path is a symlink, this affects the link itself rather than the target.
2936Equivalent to chmod(path, mode, follow_symlinks=False)."
2937[clinic start generated code]*/
2938
Larry Hastings2f936352014-08-05 14:04:04 +10002939static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002940os_lchmod_impl(PyObject *module, path_t *path, int mode)
2941/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002942{
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002944 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002945 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002947 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002948 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002949 return NULL;
2950 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002951 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002952}
2953#endif /* HAVE_LCHMOD */
2954
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002955
Thomas Wouterscf297e42007-02-23 15:07:44 +00002956#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002957/*[clinic input]
2958os.chflags
2959
2960 path: path_t
2961 flags: unsigned_long(bitwise=True)
2962 follow_symlinks: bool=True
2963
2964Set file flags.
2965
2966If follow_symlinks is False, and the last element of the path is a symbolic
2967 link, chflags will change flags on the symbolic link itself instead of the
2968 file the link points to.
2969follow_symlinks may not be implemented on your platform. If it is
2970unavailable, using it will raise a NotImplementedError.
2971
2972[clinic start generated code]*/
2973
Larry Hastings2f936352014-08-05 14:04:04 +10002974static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002975os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002976 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002977/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002978{
2979 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980
2981#ifndef HAVE_LCHFLAGS
2982 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002983 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984#endif
2985
Victor Stinner8c62be82010-05-06 00:08:46 +00002986 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987#ifdef HAVE_LCHFLAGS
2988 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002989 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002990 else
2991#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002992 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002993 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
Larry Hastings2f936352014-08-05 14:04:04 +10002995 if (result)
2996 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002997
Larry Hastings2f936352014-08-05 14:04:04 +10002998 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002999}
3000#endif /* HAVE_CHFLAGS */
3001
Larry Hastings2f936352014-08-05 14:04:04 +10003002
Thomas Wouterscf297e42007-02-23 15:07:44 +00003003#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003004/*[clinic input]
3005os.lchflags
3006
3007 path: path_t
3008 flags: unsigned_long(bitwise=True)
3009
3010Set file flags.
3011
3012This function will not follow symbolic links.
3013Equivalent to chflags(path, flags, follow_symlinks=False).
3014[clinic start generated code]*/
3015
Larry Hastings2f936352014-08-05 14:04:04 +10003016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003017os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3018/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003019{
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003021 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003022 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003023 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003024 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003025 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003026 }
Victor Stinner292c8352012-10-30 02:17:38 +01003027 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003028}
3029#endif /* HAVE_LCHFLAGS */
3030
Larry Hastings2f936352014-08-05 14:04:04 +10003031
Martin v. Löwis244edc82001-10-04 22:44:26 +00003032#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003033/*[clinic input]
3034os.chroot
3035 path: path_t
3036
3037Change root directory to path.
3038
3039[clinic start generated code]*/
3040
Larry Hastings2f936352014-08-05 14:04:04 +10003041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003042os_chroot_impl(PyObject *module, path_t *path)
3043/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003044{
3045 int res;
3046 Py_BEGIN_ALLOW_THREADS
3047 res = chroot(path->narrow);
3048 Py_END_ALLOW_THREADS
3049 if (res < 0)
3050 return path_error(path);
3051 Py_RETURN_NONE;
3052}
3053#endif /* HAVE_CHROOT */
3054
Martin v. Löwis244edc82001-10-04 22:44:26 +00003055
Guido van Rossum21142a01999-01-08 21:05:37 +00003056#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003057/*[clinic input]
3058os.fsync
3059
3060 fd: fildes
3061
3062Force write of fd to disk.
3063[clinic start generated code]*/
3064
Larry Hastings2f936352014-08-05 14:04:04 +10003065static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003066os_fsync_impl(PyObject *module, int fd)
3067/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003068{
3069 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003070}
3071#endif /* HAVE_FSYNC */
3072
Larry Hastings2f936352014-08-05 14:04:04 +10003073
Ross Lagerwall7807c352011-03-17 20:20:30 +02003074#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003075/*[clinic input]
3076os.sync
3077
3078Force write of everything to disk.
3079[clinic start generated code]*/
3080
Larry Hastings2f936352014-08-05 14:04:04 +10003081static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003082os_sync_impl(PyObject *module)
3083/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003084{
3085 Py_BEGIN_ALLOW_THREADS
3086 sync();
3087 Py_END_ALLOW_THREADS
3088 Py_RETURN_NONE;
3089}
Larry Hastings2f936352014-08-05 14:04:04 +10003090#endif /* HAVE_SYNC */
3091
Ross Lagerwall7807c352011-03-17 20:20:30 +02003092
Guido van Rossum21142a01999-01-08 21:05:37 +00003093#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003094#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003095extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3096#endif
3097
Larry Hastings2f936352014-08-05 14:04:04 +10003098/*[clinic input]
3099os.fdatasync
3100
3101 fd: fildes
3102
3103Force write of fd to disk without forcing update of metadata.
3104[clinic start generated code]*/
3105
Larry Hastings2f936352014-08-05 14:04:04 +10003106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003107os_fdatasync_impl(PyObject *module, int fd)
3108/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003109{
3110 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003111}
3112#endif /* HAVE_FDATASYNC */
3113
3114
Fredrik Lundh10723342000-07-10 16:38:09 +00003115#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003116/*[clinic input]
3117os.chown
3118
3119 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3120 Path to be examined; can be string, bytes, or open-file-descriptor int.
3121
3122 uid: uid_t
3123
3124 gid: gid_t
3125
3126 *
3127
3128 dir_fd : dir_fd(requires='fchownat') = None
3129 If not None, it should be a file descriptor open to a directory,
3130 and path should be relative; path will then be relative to that
3131 directory.
3132
3133 follow_symlinks: bool = True
3134 If False, and the last element of the path is a symbolic link,
3135 stat will examine the symbolic link itself instead of the file
3136 the link points to.
3137
3138Change the owner and group id of path to the numeric uid and gid.\
3139
3140path may always be specified as a string.
3141On some platforms, path may also be specified as an open file descriptor.
3142 If this functionality is unavailable, using it raises an exception.
3143If dir_fd is not None, it should be a file descriptor open to a directory,
3144 and path should be relative; path will then be relative to that directory.
3145If follow_symlinks is False, and the last element of the path is a symbolic
3146 link, chown will modify the symbolic link itself instead of the file the
3147 link points to.
3148It is an error to use dir_fd or follow_symlinks when specifying path as
3149 an open file descriptor.
3150dir_fd and follow_symlinks may not be implemented on your platform.
3151 If they are unavailable, using them will raise a NotImplementedError.
3152
3153[clinic start generated code]*/
3154
Larry Hastings2f936352014-08-05 14:04:04 +10003155static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003156os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003157 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003158/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003159{
3160 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161
3162#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3163 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003164 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003165#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003166 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3167 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3168 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169
3170#ifdef __APPLE__
3171 /*
3172 * This is for Mac OS X 10.3, which doesn't have lchown.
3173 * (But we still have an lchown symbol because of weak-linking.)
3174 * It doesn't have fchownat either. So there's no possibility
3175 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003176 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177 if ((!follow_symlinks) && (lchown == NULL)) {
3178 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003179 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003180 }
3181#endif
3182
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003185 if (path->fd != -1)
3186 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 else
3188#endif
3189#ifdef HAVE_LCHOWN
3190 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003191 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192 else
3193#endif
3194#ifdef HAVE_FCHOWNAT
3195 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003196 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3198 else
3199#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003200 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003201 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202
Larry Hastings2f936352014-08-05 14:04:04 +10003203 if (result)
3204 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003205
Larry Hastings2f936352014-08-05 14:04:04 +10003206 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003207}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003208#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003209
Larry Hastings2f936352014-08-05 14:04:04 +10003210
Christian Heimes4e30a842007-11-30 22:12:06 +00003211#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003212/*[clinic input]
3213os.fchown
3214
3215 fd: int
3216 uid: uid_t
3217 gid: gid_t
3218
3219Change the owner and group id of the file specified by file descriptor.
3220
3221Equivalent to os.chown(fd, uid, gid).
3222
3223[clinic start generated code]*/
3224
Larry Hastings2f936352014-08-05 14:04:04 +10003225static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003226os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3227/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003228{
Victor Stinner8c62be82010-05-06 00:08:46 +00003229 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003230 int async_err = 0;
3231
3232 do {
3233 Py_BEGIN_ALLOW_THREADS
3234 res = fchown(fd, uid, gid);
3235 Py_END_ALLOW_THREADS
3236 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3237 if (res != 0)
3238 return (!async_err) ? posix_error() : NULL;
3239
Victor Stinner8c62be82010-05-06 00:08:46 +00003240 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003241}
3242#endif /* HAVE_FCHOWN */
3243
Larry Hastings2f936352014-08-05 14:04:04 +10003244
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003245#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003246/*[clinic input]
3247os.lchown
3248
3249 path : path_t
3250 uid: uid_t
3251 gid: gid_t
3252
3253Change the owner and group id of path to the numeric uid and gid.
3254
3255This function will not follow symbolic links.
3256Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3257[clinic start generated code]*/
3258
Larry Hastings2f936352014-08-05 14:04:04 +10003259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003260os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3261/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003262{
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003265 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003266 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003267 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003268 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003269 }
Larry Hastings2f936352014-08-05 14:04:04 +10003270 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003271}
3272#endif /* HAVE_LCHOWN */
3273
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003274
Barry Warsaw53699e91996-12-10 23:23:01 +00003275static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003276posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003277{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003278 char *buf, *tmpbuf;
3279 char *cwd;
3280 const size_t chunk = 1024;
3281 size_t buflen = 0;
3282 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003283
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003284#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003285 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003286 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 wchar_t *wbuf2 = wbuf;
3288 PyObject *resobj;
3289 DWORD len;
3290 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003291 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 /* If the buffer is large enough, len does not include the
3293 terminating \0. If the buffer is too small, len includes
3294 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003295 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003296 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003297 if (wbuf2)
3298 len = GetCurrentDirectoryW(len, wbuf2);
3299 }
3300 Py_END_ALLOW_THREADS
3301 if (!wbuf2) {
3302 PyErr_NoMemory();
3303 return NULL;
3304 }
3305 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003306 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003307 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003308 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003309 }
3310 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003311 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003312 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 return resobj;
3314 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003315
3316 if (win32_warn_bytes_api())
3317 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003318#endif
3319
Victor Stinner4403d7d2015-04-25 00:16:10 +02003320 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003321 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003322 do {
3323 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003324#ifdef MS_WINDOWS
3325 if (buflen > INT_MAX) {
3326 PyErr_NoMemory();
3327 break;
3328 }
3329#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003330 tmpbuf = PyMem_RawRealloc(buf, buflen);
3331 if (tmpbuf == NULL)
3332 break;
3333
3334 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003335#ifdef MS_WINDOWS
3336 cwd = getcwd(buf, (int)buflen);
3337#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003338 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003339#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003340 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003341 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003342
3343 if (cwd == NULL) {
3344 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003345 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003346 }
3347
Victor Stinner8c62be82010-05-06 00:08:46 +00003348 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003349 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3350 else
3351 obj = PyUnicode_DecodeFSDefault(buf);
3352 PyMem_RawFree(buf);
3353
3354 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003355}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003356
Larry Hastings2f936352014-08-05 14:04:04 +10003357
3358/*[clinic input]
3359os.getcwd
3360
3361Return a unicode string representing the current working directory.
3362[clinic start generated code]*/
3363
Larry Hastings2f936352014-08-05 14:04:04 +10003364static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003365os_getcwd_impl(PyObject *module)
3366/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003367{
3368 return posix_getcwd(0);
3369}
3370
Larry Hastings2f936352014-08-05 14:04:04 +10003371
3372/*[clinic input]
3373os.getcwdb
3374
3375Return a bytes string representing the current working directory.
3376[clinic start generated code]*/
3377
Larry Hastings2f936352014-08-05 14:04:04 +10003378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003379os_getcwdb_impl(PyObject *module)
3380/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003381{
3382 return posix_getcwd(1);
3383}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003384
Larry Hastings2f936352014-08-05 14:04:04 +10003385
Larry Hastings9cf065c2012-06-22 16:30:09 -07003386#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3387#define HAVE_LINK 1
3388#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003389
Guido van Rossumb6775db1994-08-01 11:34:53 +00003390#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003391/*[clinic input]
3392
3393os.link
3394
3395 src : path_t
3396 dst : path_t
3397 *
3398 src_dir_fd : dir_fd = None
3399 dst_dir_fd : dir_fd = None
3400 follow_symlinks: bool = True
3401
3402Create a hard link to a file.
3403
3404If either src_dir_fd or dst_dir_fd is not None, it should be a file
3405 descriptor open to a directory, and the respective path string (src or dst)
3406 should be relative; the path will then be relative to that directory.
3407If follow_symlinks is False, and the last element of src is a symbolic
3408 link, link will create a link to the symbolic link itself instead of the
3409 file the link points to.
3410src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3411 platform. If they are unavailable, using them will raise a
3412 NotImplementedError.
3413[clinic start generated code]*/
3414
Larry Hastings2f936352014-08-05 14:04:04 +10003415static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003416os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003417 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003418/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003419{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#ifdef MS_WINDOWS
3421 BOOL result;
3422#else
3423 int result;
3424#endif
3425
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426#ifndef HAVE_LINKAT
3427 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3428 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003429 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 }
3431#endif
3432
Larry Hastings2f936352014-08-05 14:04:04 +10003433 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 PyErr_SetString(PyExc_NotImplementedError,
3435 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003436 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003438
Brian Curtin1b9df392010-11-24 20:24:31 +00003439#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003441 if (src->wide)
3442 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 else
Larry Hastings2f936352014-08-05 14:04:04 +10003444 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003445 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003446
Larry Hastings2f936352014-08-05 14:04:04 +10003447 if (!result)
3448 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449#else
3450 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003451#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3453 (dst_dir_fd != DEFAULT_DIR_FD) ||
3454 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003455 result = linkat(src_dir_fd, src->narrow,
3456 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003457 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3458 else
3459#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003460 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003462
Larry Hastings2f936352014-08-05 14:04:04 +10003463 if (result)
3464 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465#endif
3466
Larry Hastings2f936352014-08-05 14:04:04 +10003467 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003468}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469#endif
3470
Brian Curtin1b9df392010-11-24 20:24:31 +00003471
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003472#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003473static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003475{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 PyObject *v;
3477 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3478 BOOL result;
3479 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003480 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003481 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003482 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484
Gregory P. Smith40a21602013-03-20 20:52:50 -07003485 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003486 WIN32_FIND_DATAW wFileData;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003487 const wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003488
Gregory P. Smith40a21602013-03-20 20:52:50 -07003489 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003490 po_wchars = L".";
3491 len = 1;
3492 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003493 po_wchars = path->wide;
3494 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003495 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003497 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 if (!wnamebuf) {
3499 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003500 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003501 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003502 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003503 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003504 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003505 if (wch != SEP && wch != ALTSEP && wch != L':')
3506 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003507 wcscpy(wnamebuf + len, L"*.*");
3508 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509 if ((list = PyList_New(0)) == NULL) {
3510 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003512 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003514 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 if (hFindFile == INVALID_HANDLE_VALUE) {
3516 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003517 if (error == ERROR_FILE_NOT_FOUND)
3518 goto exit;
3519 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003520 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003521 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 }
3523 do {
3524 /* Skip over . and .. */
3525 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3526 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 v = PyUnicode_FromWideChar(wFileData.cFileName,
3528 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003529 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 Py_DECREF(list);
3531 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003532 break;
3533 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 Py_DECREF(list);
3537 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 break;
3539 }
3540 Py_DECREF(v);
3541 }
3542 Py_BEGIN_ALLOW_THREADS
3543 result = FindNextFileW(hFindFile, &wFileData);
3544 Py_END_ALLOW_THREADS
3545 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3546 it got to the end of the directory. */
3547 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003548 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003549 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003550 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 }
3552 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003553
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003556 strcpy(namebuf, path->narrow);
3557 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 if (len > 0) {
3559 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003560 if (ch != '\\' && ch != '/' && ch != ':')
3561 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 strcpy(namebuf + len, "*.*");
3563 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003564
Larry Hastings9cf065c2012-06-22 16:30:09 -07003565 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003566 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003567
Antoine Pitroub73caab2010-08-09 23:39:31 +00003568 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003570 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 if (hFindFile == INVALID_HANDLE_VALUE) {
3572 int error = GetLastError();
3573 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 goto exit;
3575 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003576 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003577 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003578 }
3579 do {
3580 /* Skip over . and .. */
3581 if (strcmp(FileData.cFileName, ".") != 0 &&
3582 strcmp(FileData.cFileName, "..") != 0) {
3583 v = PyBytes_FromString(FileData.cFileName);
3584 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 Py_DECREF(list);
3586 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003587 break;
3588 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003591 Py_DECREF(list);
3592 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 break;
3594 }
3595 Py_DECREF(v);
3596 }
3597 Py_BEGIN_ALLOW_THREADS
3598 result = FindNextFile(hFindFile, &FileData);
3599 Py_END_ALLOW_THREADS
3600 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3601 it got to the end of the directory. */
3602 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003603 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003604 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003605 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 }
3607 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003608
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609exit:
3610 if (hFindFile != INVALID_HANDLE_VALUE) {
3611 if (FindClose(hFindFile) == FALSE) {
3612 if (list != NULL) {
3613 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003614 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003615 }
3616 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003617 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003618 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003619
Larry Hastings9cf065c2012-06-22 16:30:09 -07003620 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003621} /* end of _listdir_windows_no_opendir */
3622
3623#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3624
3625static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003626_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003627{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003628 PyObject *v;
3629 DIR *dirp = NULL;
3630 struct dirent *ep;
3631 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003632#ifdef HAVE_FDOPENDIR
3633 int fd = -1;
3634#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003635
Victor Stinner8c62be82010-05-06 00:08:46 +00003636 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003637#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003638 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003639 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003640 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003641 if (fd == -1)
3642 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003643
Larry Hastingsfdaea062012-06-25 04:42:23 -07003644 return_str = 1;
3645
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 Py_BEGIN_ALLOW_THREADS
3647 dirp = fdopendir(fd);
3648 Py_END_ALLOW_THREADS
3649 }
3650 else
3651#endif
3652 {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003653 const char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003654 if (path->narrow) {
3655 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003656 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003657 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003658 }
3659 else {
3660 name = ".";
3661 return_str = 1;
3662 }
3663
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664 Py_BEGIN_ALLOW_THREADS
3665 dirp = opendir(name);
3666 Py_END_ALLOW_THREADS
3667 }
3668
3669 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003670 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003671#ifdef HAVE_FDOPENDIR
3672 if (fd != -1) {
3673 Py_BEGIN_ALLOW_THREADS
3674 close(fd);
3675 Py_END_ALLOW_THREADS
3676 }
3677#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 goto exit;
3679 }
3680 if ((list = PyList_New(0)) == NULL) {
3681 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 }
3683 for (;;) {
3684 errno = 0;
3685 Py_BEGIN_ALLOW_THREADS
3686 ep = readdir(dirp);
3687 Py_END_ALLOW_THREADS
3688 if (ep == NULL) {
3689 if (errno == 0) {
3690 break;
3691 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003692 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003693 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003694 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003695 }
3696 }
3697 if (ep->d_name[0] == '.' &&
3698 (NAMLEN(ep) == 1 ||
3699 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3700 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003701 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003702 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3703 else
3704 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003705 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003707 break;
3708 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003709 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003710 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003712 break;
3713 }
3714 Py_DECREF(v);
3715 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717exit:
3718 if (dirp != NULL) {
3719 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003720#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003721 if (fd > -1)
3722 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003723#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003724 closedir(dirp);
3725 Py_END_ALLOW_THREADS
3726 }
3727
Larry Hastings9cf065c2012-06-22 16:30:09 -07003728 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003729} /* end of _posix_listdir */
3730#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003731
Larry Hastings2f936352014-08-05 14:04:04 +10003732
3733/*[clinic input]
3734os.listdir
3735
3736 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3737
3738Return a list containing the names of the files in the directory.
3739
3740path can be specified as either str or bytes. If path is bytes,
3741 the filenames returned will also be bytes; in all other circumstances
3742 the filenames returned will be str.
3743If path is None, uses the path='.'.
3744On some platforms, path may also be specified as an open file descriptor;\
3745 the file descriptor must refer to a directory.
3746 If this functionality is unavailable, using it raises NotImplementedError.
3747
3748The list is in arbitrary order. It does not include the special
3749entries '.' and '..' even if they are present in the directory.
3750
3751
3752[clinic start generated code]*/
3753
Larry Hastings2f936352014-08-05 14:04:04 +10003754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003755os_listdir_impl(PyObject *module, path_t *path)
3756/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003757{
3758#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3759 return _listdir_windows_no_opendir(path, NULL);
3760#else
3761 return _posix_listdir(path, NULL);
3762#endif
3763}
3764
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003765#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003766/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003767/*[clinic input]
3768os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003770 path: path_t
3771 /
3772
3773[clinic start generated code]*/
3774
3775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003776os__getfullpathname_impl(PyObject *module, path_t *path)
3777/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003778{
3779 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003780 {
Victor Stinner75875072013-11-24 19:23:25 +01003781 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003782 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 DWORD result;
3784 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003785
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003786 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003787 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003789 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003790 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003791 if (!woutbufp)
3792 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003793 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003794 }
3795 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003796 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003798 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003799 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003800 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003801 return v;
3802 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003803 else {
3804 char outbuf[MAX_PATH];
3805 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003806
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003807 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3808 outbuf, &temp)) {
3809 win32_error_object("GetFullPathName", path->object);
3810 return NULL;
3811 }
3812 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003813 }
Larry Hastings2f936352014-08-05 14:04:04 +10003814}
Brian Curtind40e6f72010-07-08 21:39:08 +00003815
Brian Curtind25aef52011-06-13 15:16:04 -05003816
Larry Hastings2f936352014-08-05 14:04:04 +10003817/*[clinic input]
3818os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003819
Larry Hastings2f936352014-08-05 14:04:04 +10003820 path: unicode
3821 /
3822
3823A helper function for samepath on windows.
3824[clinic start generated code]*/
3825
Larry Hastings2f936352014-08-05 14:04:04 +10003826static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003827os__getfinalpathname_impl(PyObject *module, PyObject *path)
3828/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003829{
3830 HANDLE hFile;
3831 int buf_size;
3832 wchar_t *target_path;
3833 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003834 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003835 const wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003836
Larry Hastings2f936352014-08-05 14:04:04 +10003837 path_wchar = PyUnicode_AsUnicode(path);
3838 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003839 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003840
Brian Curtind40e6f72010-07-08 21:39:08 +00003841 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003842 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003843 0, /* desired access */
3844 0, /* share mode */
3845 NULL, /* security attributes */
3846 OPEN_EXISTING,
3847 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3848 FILE_FLAG_BACKUP_SEMANTICS,
3849 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003850
Victor Stinnereb5657a2011-09-30 01:44:27 +02003851 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003852 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003853
3854 /* We have a good handle to the target, use it to determine the
3855 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003856 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003857
3858 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003859 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003860
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003861 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003862 if(!target_path)
3863 return PyErr_NoMemory();
3864
Steve Dower2ea51c92015-03-20 21:49:12 -07003865 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3866 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003867 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003868 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003869
3870 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003871 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003872
3873 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003874 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003875 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003876 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003877}
Brian Curtin62857742010-09-06 17:07:27 +00003878
Brian Curtin95d028f2011-06-09 09:10:38 -05003879PyDoc_STRVAR(posix__isdir__doc__,
3880"Return true if the pathname refers to an existing directory.");
3881
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003882/*[clinic input]
3883os._isdir
3884
3885 path: path_t
3886 /
3887
3888[clinic start generated code]*/
3889
Brian Curtin9c669cc2011-06-08 18:17:18 -05003890static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003891os__isdir_impl(PyObject *module, path_t *path)
3892/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003893{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003894 DWORD attributes;
3895
Steve Dowerb22a6772016-07-17 20:49:38 -07003896 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003897 if (!path->narrow)
3898 attributes = GetFileAttributesW(path->wide);
3899 else
3900 attributes = GetFileAttributesA(path->narrow);
Steve Dowerb22a6772016-07-17 20:49:38 -07003901 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003902
Brian Curtin9c669cc2011-06-08 18:17:18 -05003903 if (attributes == INVALID_FILE_ATTRIBUTES)
3904 Py_RETURN_FALSE;
3905
Brian Curtin9c669cc2011-06-08 18:17:18 -05003906 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3907 Py_RETURN_TRUE;
3908 else
3909 Py_RETURN_FALSE;
3910}
Tim Golden6b528062013-08-01 12:44:00 +01003911
Tim Golden6b528062013-08-01 12:44:00 +01003912
Larry Hastings2f936352014-08-05 14:04:04 +10003913/*[clinic input]
3914os._getvolumepathname
3915
3916 path: unicode
3917
3918A helper function for ismount on Win32.
3919[clinic start generated code]*/
3920
Larry Hastings2f936352014-08-05 14:04:04 +10003921static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003922os__getvolumepathname_impl(PyObject *module, PyObject *path)
3923/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003924{
3925 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003926 const wchar_t *path_wchar;
3927 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003928 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003929 BOOL ret;
3930
Larry Hastings2f936352014-08-05 14:04:04 +10003931 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3932 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003933 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003934 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003935
3936 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003937 buflen = Py_MAX(buflen, MAX_PATH);
3938
3939 if (buflen > DWORD_MAX) {
3940 PyErr_SetString(PyExc_OverflowError, "path too long");
3941 return NULL;
3942 }
3943
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003944 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003945 if (mountpath == NULL)
3946 return PyErr_NoMemory();
3947
3948 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003949 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003950 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003951 Py_END_ALLOW_THREADS
3952
3953 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003954 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003955 goto exit;
3956 }
3957 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3958
3959exit:
3960 PyMem_Free(mountpath);
3961 return result;
3962}
Tim Golden6b528062013-08-01 12:44:00 +01003963
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003964#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003965
Larry Hastings2f936352014-08-05 14:04:04 +10003966
3967/*[clinic input]
3968os.mkdir
3969
3970 path : path_t
3971
3972 mode: int = 0o777
3973
3974 *
3975
3976 dir_fd : dir_fd(requires='mkdirat') = None
3977
3978# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3979
3980Create a directory.
3981
3982If dir_fd is not None, it should be a file descriptor open to a directory,
3983 and path should be relative; path will then be relative to that directory.
3984dir_fd may not be implemented on your platform.
3985 If it is unavailable, using it will raise a NotImplementedError.
3986
3987The mode argument is ignored on Windows.
3988[clinic start generated code]*/
3989
Larry Hastings2f936352014-08-05 14:04:04 +10003990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003991os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3992/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003993{
3994 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003995
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003996#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003997 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003998 if (path->wide)
3999 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004000 else
Larry Hastings2f936352014-08-05 14:04:04 +10004001 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004002 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004003
Larry Hastings2f936352014-08-05 14:04:04 +10004004 if (!result)
4005 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004007 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004008#if HAVE_MKDIRAT
4009 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004010 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004011 else
4012#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004013#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004014 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004015#else
Larry Hastings2f936352014-08-05 14:04:04 +10004016 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004017#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004018 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004019 if (result < 0)
4020 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004021#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004022 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004023}
4024
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004025
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004026/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4027#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004028#include <sys/resource.h>
4029#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004030
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004031
4032#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004033/*[clinic input]
4034os.nice
4035
4036 increment: int
4037 /
4038
4039Add increment to the priority of process and return the new priority.
4040[clinic start generated code]*/
4041
Larry Hastings2f936352014-08-05 14:04:04 +10004042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004043os_nice_impl(PyObject *module, int increment)
4044/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004045{
4046 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004047
Victor Stinner8c62be82010-05-06 00:08:46 +00004048 /* There are two flavours of 'nice': one that returns the new
4049 priority (as required by almost all standards out there) and the
4050 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4051 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004052
Victor Stinner8c62be82010-05-06 00:08:46 +00004053 If we are of the nice family that returns the new priority, we
4054 need to clear errno before the call, and check if errno is filled
4055 before calling posix_error() on a returnvalue of -1, because the
4056 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004057
Victor Stinner8c62be82010-05-06 00:08:46 +00004058 errno = 0;
4059 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004060#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004061 if (value == 0)
4062 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004063#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004064 if (value == -1 && errno != 0)
4065 /* either nice() or getpriority() returned an error */
4066 return posix_error();
4067 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004068}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004069#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004070
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004071
4072#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004073/*[clinic input]
4074os.getpriority
4075
4076 which: int
4077 who: int
4078
4079Return program scheduling priority.
4080[clinic start generated code]*/
4081
Larry Hastings2f936352014-08-05 14:04:04 +10004082static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004083os_getpriority_impl(PyObject *module, int which, int who)
4084/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004085{
4086 int retval;
4087
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004088 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004089 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004090 if (errno != 0)
4091 return posix_error();
4092 return PyLong_FromLong((long)retval);
4093}
4094#endif /* HAVE_GETPRIORITY */
4095
4096
4097#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004098/*[clinic input]
4099os.setpriority
4100
4101 which: int
4102 who: int
4103 priority: int
4104
4105Set program scheduling priority.
4106[clinic start generated code]*/
4107
Larry Hastings2f936352014-08-05 14:04:04 +10004108static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004109os_setpriority_impl(PyObject *module, int which, int who, int priority)
4110/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004111{
4112 int retval;
4113
4114 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004115 if (retval == -1)
4116 return posix_error();
4117 Py_RETURN_NONE;
4118}
4119#endif /* HAVE_SETPRIORITY */
4120
4121
Barry Warsaw53699e91996-12-10 23:23:01 +00004122static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004123internal_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 +00004124{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004125 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004128#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004129 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004130 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004131#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004133#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4136 (dst_dir_fd != DEFAULT_DIR_FD);
4137#ifndef HAVE_RENAMEAT
4138 if (dir_fd_specified) {
4139 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004140 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141 }
4142#endif
4143
Larry Hastings2f936352014-08-05 14:04:04 +10004144 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145 PyErr_Format(PyExc_ValueError,
4146 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004147 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148 }
4149
4150#ifdef MS_WINDOWS
4151 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004152 if (src->wide)
4153 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154 else
Larry Hastings2f936352014-08-05 14:04:04 +10004155 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004156 Py_END_ALLOW_THREADS
4157
Larry Hastings2f936352014-08-05 14:04:04 +10004158 if (!result)
4159 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004160
4161#else
4162 Py_BEGIN_ALLOW_THREADS
4163#ifdef HAVE_RENAMEAT
4164 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004165 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004166 else
4167#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004168 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004169 Py_END_ALLOW_THREADS
4170
Larry Hastings2f936352014-08-05 14:04:04 +10004171 if (result)
4172 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004173#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004174 Py_RETURN_NONE;
4175}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004176
Larry Hastings2f936352014-08-05 14:04:04 +10004177
4178/*[clinic input]
4179os.rename
4180
4181 src : path_t
4182 dst : path_t
4183 *
4184 src_dir_fd : dir_fd = None
4185 dst_dir_fd : dir_fd = None
4186
4187Rename a file or directory.
4188
4189If either src_dir_fd or dst_dir_fd is not None, it should be a file
4190 descriptor open to a directory, and the respective path string (src or dst)
4191 should be relative; the path will then be relative to that directory.
4192src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4193 If they are unavailable, using them will raise a NotImplementedError.
4194[clinic start generated code]*/
4195
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004197os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004198 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004199/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004200{
Larry Hastings2f936352014-08-05 14:04:04 +10004201 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004202}
4203
Larry Hastings2f936352014-08-05 14:04:04 +10004204
4205/*[clinic input]
4206os.replace = os.rename
4207
4208Rename a file or directory, overwriting the destination.
4209
4210If either src_dir_fd or dst_dir_fd is not None, it should be a file
4211 descriptor open to a directory, and the respective path string (src or dst)
4212 should be relative; the path will then be relative to that directory.
4213src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4214 If they are unavailable, using them will raise a NotImplementedError."
4215[clinic start generated code]*/
4216
Larry Hastings2f936352014-08-05 14:04:04 +10004217static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004218os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4219 int dst_dir_fd)
4220/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004221{
4222 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4223}
4224
4225
4226/*[clinic input]
4227os.rmdir
4228
4229 path: path_t
4230 *
4231 dir_fd: dir_fd(requires='unlinkat') = None
4232
4233Remove a directory.
4234
4235If dir_fd is not None, it should be a file descriptor open to a directory,
4236 and path should be relative; path will then be relative to that directory.
4237dir_fd may not be implemented on your platform.
4238 If it is unavailable, using it will raise a NotImplementedError.
4239[clinic start generated code]*/
4240
Larry Hastings2f936352014-08-05 14:04:04 +10004241static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004242os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4243/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004244{
4245 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004246
4247 Py_BEGIN_ALLOW_THREADS
4248#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004249 if (path->wide)
4250 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004251 else
Larry Hastings2f936352014-08-05 14:04:04 +10004252 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004253 result = !result; /* Windows, success=1, UNIX, success=0 */
4254#else
4255#ifdef HAVE_UNLINKAT
4256 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004257 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004258 else
4259#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004260 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004261#endif
4262 Py_END_ALLOW_THREADS
4263
Larry Hastings2f936352014-08-05 14:04:04 +10004264 if (result)
4265 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004266
Larry Hastings2f936352014-08-05 14:04:04 +10004267 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004268}
4269
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004270
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004271#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004272#ifdef MS_WINDOWS
4273/*[clinic input]
4274os.system -> long
4275
4276 command: Py_UNICODE
4277
4278Execute the command in a subshell.
4279[clinic start generated code]*/
4280
Larry Hastings2f936352014-08-05 14:04:04 +10004281static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004282os_system_impl(PyObject *module, Py_UNICODE *command)
4283/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004284{
4285 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004287 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004288 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004289 return result;
4290}
4291#else /* MS_WINDOWS */
4292/*[clinic input]
4293os.system -> long
4294
4295 command: FSConverter
4296
4297Execute the command in a subshell.
4298[clinic start generated code]*/
4299
Larry Hastings2f936352014-08-05 14:04:04 +10004300static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004301os_system_impl(PyObject *module, PyObject *command)
4302/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004303{
4304 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004305 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004306 Py_BEGIN_ALLOW_THREADS
4307 result = system(bytes);
4308 Py_END_ALLOW_THREADS
4309 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004310}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004311#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004312#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004313
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004314
Larry Hastings2f936352014-08-05 14:04:04 +10004315/*[clinic input]
4316os.umask
4317
4318 mask: int
4319 /
4320
4321Set the current numeric umask and return the previous umask.
4322[clinic start generated code]*/
4323
Larry Hastings2f936352014-08-05 14:04:04 +10004324static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004325os_umask_impl(PyObject *module, int mask)
4326/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004327{
4328 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004329 if (i < 0)
4330 return posix_error();
4331 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004332}
4333
Brian Curtind40e6f72010-07-08 21:39:08 +00004334#ifdef MS_WINDOWS
4335
4336/* override the default DeleteFileW behavior so that directory
4337symlinks can be removed with this function, the same as with
4338Unix symlinks */
4339BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4340{
4341 WIN32_FILE_ATTRIBUTE_DATA info;
4342 WIN32_FIND_DATAW find_data;
4343 HANDLE find_data_handle;
4344 int is_directory = 0;
4345 int is_link = 0;
4346
4347 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4348 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004349
Brian Curtind40e6f72010-07-08 21:39:08 +00004350 /* Get WIN32_FIND_DATA structure for the path to determine if
4351 it is a symlink */
4352 if(is_directory &&
4353 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4354 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4355
4356 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004357 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4358 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4359 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4360 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004361 FindClose(find_data_handle);
4362 }
4363 }
4364 }
4365
4366 if (is_directory && is_link)
4367 return RemoveDirectoryW(lpFileName);
4368
4369 return DeleteFileW(lpFileName);
4370}
4371#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004372
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004373
Larry Hastings2f936352014-08-05 14:04:04 +10004374/*[clinic input]
4375os.unlink
4376
4377 path: path_t
4378 *
4379 dir_fd: dir_fd(requires='unlinkat')=None
4380
4381Remove a file (same as remove()).
4382
4383If dir_fd is not None, it should be a file descriptor open to a directory,
4384 and path should be relative; path will then be relative to that directory.
4385dir_fd may not be implemented on your platform.
4386 If it is unavailable, using it will raise a NotImplementedError.
4387
4388[clinic start generated code]*/
4389
Larry Hastings2f936352014-08-05 14:04:04 +10004390static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004391os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4392/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004393{
4394 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004395
4396 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004397 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004399 if (path->wide)
4400 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004401 else
Larry Hastings2f936352014-08-05 14:04:04 +10004402 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403 result = !result; /* Windows, success=1, UNIX, success=0 */
4404#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405#ifdef HAVE_UNLINKAT
4406 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004407 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004408 else
4409#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004410 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004411#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004412 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004413 Py_END_ALLOW_THREADS
4414
Larry Hastings2f936352014-08-05 14:04:04 +10004415 if (result)
4416 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004417
Larry Hastings2f936352014-08-05 14:04:04 +10004418 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004419}
4420
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004421
Larry Hastings2f936352014-08-05 14:04:04 +10004422/*[clinic input]
4423os.remove = os.unlink
4424
4425Remove a file (same as unlink()).
4426
4427If dir_fd is not None, it should be a file descriptor open to a directory,
4428 and path should be relative; path will then be relative to that directory.
4429dir_fd may not be implemented on your platform.
4430 If it is unavailable, using it will raise a NotImplementedError.
4431[clinic start generated code]*/
4432
Larry Hastings2f936352014-08-05 14:04:04 +10004433static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004434os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4435/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004436{
4437 return os_unlink_impl(module, path, dir_fd);
4438}
4439
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004440
Larry Hastings605a62d2012-06-24 04:33:36 -07004441static PyStructSequence_Field uname_result_fields[] = {
4442 {"sysname", "operating system name"},
4443 {"nodename", "name of machine on network (implementation-defined)"},
4444 {"release", "operating system release"},
4445 {"version", "operating system version"},
4446 {"machine", "hardware identifier"},
4447 {NULL}
4448};
4449
4450PyDoc_STRVAR(uname_result__doc__,
4451"uname_result: Result from os.uname().\n\n\
4452This object may be accessed either as a tuple of\n\
4453 (sysname, nodename, release, version, machine),\n\
4454or via the attributes sysname, nodename, release, version, and machine.\n\
4455\n\
4456See os.uname for more information.");
4457
4458static PyStructSequence_Desc uname_result_desc = {
4459 "uname_result", /* name */
4460 uname_result__doc__, /* doc */
4461 uname_result_fields,
4462 5
4463};
4464
4465static PyTypeObject UnameResultType;
4466
4467
4468#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004469/*[clinic input]
4470os.uname
4471
4472Return an object identifying the current operating system.
4473
4474The object behaves like a named tuple with the following fields:
4475 (sysname, nodename, release, version, machine)
4476
4477[clinic start generated code]*/
4478
Larry Hastings2f936352014-08-05 14:04:04 +10004479static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004480os_uname_impl(PyObject *module)
4481/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004482{
Victor Stinner8c62be82010-05-06 00:08:46 +00004483 struct utsname u;
4484 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004485 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004486
Victor Stinner8c62be82010-05-06 00:08:46 +00004487 Py_BEGIN_ALLOW_THREADS
4488 res = uname(&u);
4489 Py_END_ALLOW_THREADS
4490 if (res < 0)
4491 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004492
4493 value = PyStructSequence_New(&UnameResultType);
4494 if (value == NULL)
4495 return NULL;
4496
4497#define SET(i, field) \
4498 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004499 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004500 if (!o) { \
4501 Py_DECREF(value); \
4502 return NULL; \
4503 } \
4504 PyStructSequence_SET_ITEM(value, i, o); \
4505 } \
4506
4507 SET(0, u.sysname);
4508 SET(1, u.nodename);
4509 SET(2, u.release);
4510 SET(3, u.version);
4511 SET(4, u.machine);
4512
4513#undef SET
4514
4515 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004516}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004517#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004518
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004519
Larry Hastings9cf065c2012-06-22 16:30:09 -07004520
4521typedef struct {
4522 int now;
4523 time_t atime_s;
4524 long atime_ns;
4525 time_t mtime_s;
4526 long mtime_ns;
4527} utime_t;
4528
4529/*
Victor Stinner484df002014-10-09 13:52:31 +02004530 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 * they also intentionally leak the declaration of a pointer named "time"
4532 */
4533#define UTIME_TO_TIMESPEC \
4534 struct timespec ts[2]; \
4535 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004536 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537 time = NULL; \
4538 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004539 ts[0].tv_sec = ut->atime_s; \
4540 ts[0].tv_nsec = ut->atime_ns; \
4541 ts[1].tv_sec = ut->mtime_s; \
4542 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004543 time = ts; \
4544 } \
4545
4546#define UTIME_TO_TIMEVAL \
4547 struct timeval tv[2]; \
4548 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004549 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004550 time = NULL; \
4551 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004552 tv[0].tv_sec = ut->atime_s; \
4553 tv[0].tv_usec = ut->atime_ns / 1000; \
4554 tv[1].tv_sec = ut->mtime_s; \
4555 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 time = tv; \
4557 } \
4558
4559#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004560 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004562 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004563 time = NULL; \
4564 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004565 u.actime = ut->atime_s; \
4566 u.modtime = ut->mtime_s; \
4567 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004568 }
4569
4570#define UTIME_TO_TIME_T \
4571 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004572 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004573 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574 time = NULL; \
4575 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004576 timet[0] = ut->atime_s; \
4577 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004578 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579 } \
4580
4581
Victor Stinner528a9ab2015-09-03 21:30:26 +02004582#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004583
4584static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004585utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004586{
4587#ifdef HAVE_UTIMENSAT
4588 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4589 UTIME_TO_TIMESPEC;
4590 return utimensat(dir_fd, path, time, flags);
4591#elif defined(HAVE_FUTIMESAT)
4592 UTIME_TO_TIMEVAL;
4593 /*
4594 * follow_symlinks will never be false here;
4595 * we only allow !follow_symlinks and dir_fd together
4596 * if we have utimensat()
4597 */
4598 assert(follow_symlinks);
4599 return futimesat(dir_fd, path, time);
4600#endif
4601}
4602
Larry Hastings2f936352014-08-05 14:04:04 +10004603 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4604#else
4605 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606#endif
4607
Victor Stinner528a9ab2015-09-03 21:30:26 +02004608#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004609
4610static int
Victor Stinner484df002014-10-09 13:52:31 +02004611utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004612{
4613#ifdef HAVE_FUTIMENS
4614 UTIME_TO_TIMESPEC;
4615 return futimens(fd, time);
4616#else
4617 UTIME_TO_TIMEVAL;
4618 return futimes(fd, time);
4619#endif
4620}
4621
Larry Hastings2f936352014-08-05 14:04:04 +10004622 #define PATH_UTIME_HAVE_FD 1
4623#else
4624 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004625#endif
4626
Victor Stinner5ebae872015-09-22 01:29:33 +02004627#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4628# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4629#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630
Victor Stinner4552ced2015-09-21 22:37:15 +02004631#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632
4633static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004634utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004635{
4636#ifdef HAVE_UTIMENSAT
4637 UTIME_TO_TIMESPEC;
4638 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4639#else
4640 UTIME_TO_TIMEVAL;
4641 return lutimes(path, time);
4642#endif
4643}
4644
4645#endif
4646
4647#ifndef MS_WINDOWS
4648
4649static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004650utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004651{
4652#ifdef HAVE_UTIMENSAT
4653 UTIME_TO_TIMESPEC;
4654 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4655#elif defined(HAVE_UTIMES)
4656 UTIME_TO_TIMEVAL;
4657 return utimes(path, time);
4658#elif defined(HAVE_UTIME_H)
4659 UTIME_TO_UTIMBUF;
4660 return utime(path, time);
4661#else
4662 UTIME_TO_TIME_T;
4663 return utime(path, time);
4664#endif
4665}
4666
4667#endif
4668
Larry Hastings76ad59b2012-05-03 00:30:07 -07004669static int
4670split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4671{
4672 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004673 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004674 divmod = PyNumber_Divmod(py_long, billion);
4675 if (!divmod)
4676 goto exit;
4677 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4678 if ((*s == -1) && PyErr_Occurred())
4679 goto exit;
4680 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004681 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004682 goto exit;
4683
4684 result = 1;
4685exit:
4686 Py_XDECREF(divmod);
4687 return result;
4688}
4689
Larry Hastings2f936352014-08-05 14:04:04 +10004690
4691/*[clinic input]
4692os.utime
4693
4694 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4695 times: object = NULL
4696 *
4697 ns: object = NULL
4698 dir_fd: dir_fd(requires='futimensat') = None
4699 follow_symlinks: bool=True
4700
Martin Panter0ff89092015-09-09 01:56:53 +00004701# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004702
4703Set the access and modified time of path.
4704
4705path may always be specified as a string.
4706On some platforms, path may also be specified as an open file descriptor.
4707 If this functionality is unavailable, using it raises an exception.
4708
4709If times is not None, it must be a tuple (atime, mtime);
4710 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004711If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004712 atime_ns and mtime_ns should be expressed as integer nanoseconds
4713 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004714If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004715Specifying tuples for both times and ns is an error.
4716
4717If dir_fd is not None, it should be a file descriptor open to a directory,
4718 and path should be relative; path will then be relative to that directory.
4719If follow_symlinks is False, and the last element of the path is a symbolic
4720 link, utime will modify the symbolic link itself instead of the file the
4721 link points to.
4722It is an error to use dir_fd or follow_symlinks when specifying path
4723 as an open file descriptor.
4724dir_fd and follow_symlinks may not be available on your platform.
4725 If they are unavailable, using them will raise a NotImplementedError.
4726
4727[clinic start generated code]*/
4728
Larry Hastings2f936352014-08-05 14:04:04 +10004729static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004730os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4731 int dir_fd, int follow_symlinks)
4732/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004733{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734#ifdef MS_WINDOWS
4735 HANDLE hFile;
4736 FILETIME atime, mtime;
4737#else
4738 int result;
4739#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004740
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004742 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004743
Christian Heimesb3c87242013-08-01 00:08:16 +02004744 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004745
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 if (times && (times != Py_None) && ns) {
4747 PyErr_SetString(PyExc_ValueError,
4748 "utime: you may specify either 'times'"
4749 " or 'ns' but not both");
4750 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004751 }
4752
4753 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004754 time_t a_sec, m_sec;
4755 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004756 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 PyErr_SetString(PyExc_TypeError,
4758 "utime: 'times' must be either"
4759 " a tuple of two ints or None");
4760 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004763 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004764 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004765 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004766 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004767 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004768 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004769 utime.atime_s = a_sec;
4770 utime.atime_ns = a_nsec;
4771 utime.mtime_s = m_sec;
4772 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004773 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004775 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 PyErr_SetString(PyExc_TypeError,
4777 "utime: 'ns' must be a tuple of two ints");
4778 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004779 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004781 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004783 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784 &utime.mtime_s, &utime.mtime_ns)) {
4785 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004786 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 }
4788 else {
4789 /* times and ns are both None/unspecified. use "now". */
4790 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004791 }
4792
Victor Stinner4552ced2015-09-21 22:37:15 +02004793#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 if (follow_symlinks_specified("utime", follow_symlinks))
4795 goto exit;
4796#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004797
Larry Hastings2f936352014-08-05 14:04:04 +10004798 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4799 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4800 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004802
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803#if !defined(HAVE_UTIMENSAT)
4804 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004805 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 "utime: cannot use dir_fd and follow_symlinks "
4807 "together on this platform");
4808 goto exit;
4809 }
4810#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004811
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004812#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004814 if (path->wide)
4815 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 NULL, OPEN_EXISTING,
4817 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 else
Larry Hastings2f936352014-08-05 14:04:04 +10004819 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 NULL, OPEN_EXISTING,
4821 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004822 Py_END_ALLOW_THREADS
4823 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004824 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004825 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004826 }
4827
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004829 GetSystemTimeAsFileTime(&mtime);
4830 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004832 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004833 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4834 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004835 }
4836 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4837 /* Avoid putting the file name into the error here,
4838 as that may confuse the user into believing that
4839 something is wrong with the file, when it also
4840 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004841 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004843 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004844#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004846
Victor Stinner4552ced2015-09-21 22:37:15 +02004847#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004849 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004850 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004851#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852
Victor Stinner528a9ab2015-09-03 21:30:26 +02004853#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004855 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004856 else
4857#endif
4858
Victor Stinner528a9ab2015-09-03 21:30:26 +02004859#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004860 if (path->fd != -1)
4861 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862 else
4863#endif
4864
Larry Hastings2f936352014-08-05 14:04:04 +10004865 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004866
4867 Py_END_ALLOW_THREADS
4868
4869 if (result < 0) {
4870 /* see previous comment about not putting filename in error here */
4871 return_value = posix_error();
4872 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004874
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004875#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004876
4877 Py_INCREF(Py_None);
4878 return_value = Py_None;
4879
4880exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004881#ifdef MS_WINDOWS
4882 if (hFile != INVALID_HANDLE_VALUE)
4883 CloseHandle(hFile);
4884#endif
4885 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004886}
4887
Guido van Rossum3b066191991-06-04 19:40:25 +00004888/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004889
Larry Hastings2f936352014-08-05 14:04:04 +10004890
4891/*[clinic input]
4892os._exit
4893
4894 status: int
4895
4896Exit to the system with specified status, without normal exit processing.
4897[clinic start generated code]*/
4898
Larry Hastings2f936352014-08-05 14:04:04 +10004899static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004900os__exit_impl(PyObject *module, int status)
4901/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004902{
4903 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004904 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004905}
4906
Martin v. Löwis114619e2002-10-07 06:44:21 +00004907#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4908static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004909free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004910{
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 Py_ssize_t i;
4912 for (i = 0; i < count; i++)
4913 PyMem_Free(array[i]);
4914 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004915}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004916
Antoine Pitrou69f71142009-05-24 21:25:49 +00004917static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004918int fsconvert_strdup(PyObject *o, char**out)
4919{
Victor Stinner8c62be82010-05-06 00:08:46 +00004920 PyObject *bytes;
4921 Py_ssize_t size;
4922 if (!PyUnicode_FSConverter(o, &bytes))
4923 return 0;
4924 size = PyBytes_GET_SIZE(bytes);
4925 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004926 if (!*out) {
4927 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004929 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 memcpy(*out, PyBytes_AsString(bytes), size+1);
4931 Py_DECREF(bytes);
4932 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004933}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004934#endif
4935
Ross Lagerwall7807c352011-03-17 20:20:30 +02004936#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004937static char**
4938parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4939{
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 char **envlist;
4941 Py_ssize_t i, pos, envc;
4942 PyObject *keys=NULL, *vals=NULL;
4943 PyObject *key, *val, *key2, *val2;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004944 char *p;
4945 const char *k, *v;
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004947
Victor Stinner8c62be82010-05-06 00:08:46 +00004948 i = PyMapping_Size(env);
4949 if (i < 0)
4950 return NULL;
4951 envlist = PyMem_NEW(char *, i + 1);
4952 if (envlist == NULL) {
4953 PyErr_NoMemory();
4954 return NULL;
4955 }
4956 envc = 0;
4957 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004958 if (!keys)
4959 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004961 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 goto error;
4963 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4964 PyErr_Format(PyExc_TypeError,
4965 "env.keys() or env.values() is not a list");
4966 goto error;
4967 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 for (pos = 0; pos < i; pos++) {
4970 key = PyList_GetItem(keys, pos);
4971 val = PyList_GetItem(vals, pos);
4972 if (!key || !val)
4973 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004974
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 if (PyUnicode_FSConverter(key, &key2) == 0)
4976 goto error;
4977 if (PyUnicode_FSConverter(val, &val2) == 0) {
4978 Py_DECREF(key2);
4979 goto error;
4980 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004981
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 k = PyBytes_AsString(key2);
4983 v = PyBytes_AsString(val2);
4984 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 p = PyMem_NEW(char, len);
4987 if (p == NULL) {
4988 PyErr_NoMemory();
4989 Py_DECREF(key2);
4990 Py_DECREF(val2);
4991 goto error;
4992 }
4993 PyOS_snprintf(p, len, "%s=%s", k, v);
4994 envlist[envc++] = p;
4995 Py_DECREF(key2);
4996 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004997 }
4998 Py_DECREF(vals);
4999 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00005000
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 envlist[envc] = 0;
5002 *envc_ptr = envc;
5003 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005004
5005error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005006 Py_XDECREF(keys);
5007 Py_XDECREF(vals);
5008 while (--envc >= 0)
5009 PyMem_DEL(envlist[envc]);
5010 PyMem_DEL(envlist);
5011 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005012}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005013
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014static char**
5015parse_arglist(PyObject* argv, Py_ssize_t *argc)
5016{
5017 int i;
5018 char **argvlist = PyMem_NEW(char *, *argc+1);
5019 if (argvlist == NULL) {
5020 PyErr_NoMemory();
5021 return NULL;
5022 }
5023 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005024 PyObject* item = PySequence_ITEM(argv, i);
5025 if (item == NULL)
5026 goto fail;
5027 if (!fsconvert_strdup(item, &argvlist[i])) {
5028 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005029 goto fail;
5030 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005031 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005032 }
5033 argvlist[*argc] = NULL;
5034 return argvlist;
5035fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005036 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005037 free_string_array(argvlist, *argc);
5038 return NULL;
5039}
5040#endif
5041
Larry Hastings2f936352014-08-05 14:04:04 +10005042
Ross Lagerwall7807c352011-03-17 20:20:30 +02005043#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005044/*[clinic input]
5045os.execv
5046
5047 path: FSConverter
5048 Path of executable file.
5049 argv: object
5050 Tuple or list of strings.
5051 /
5052
5053Execute an executable path with arguments, replacing current process.
5054[clinic start generated code]*/
5055
Larry Hastings2f936352014-08-05 14:04:04 +10005056static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005057os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5058/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005059{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005060 const char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 char **argvlist;
5062 Py_ssize_t argc;
5063
5064 /* execv has two arguments: (path, argv), where
5065 argv is a list or tuple of strings. */
5066
Larry Hastings2f936352014-08-05 14:04:04 +10005067 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005068 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5069 PyErr_SetString(PyExc_TypeError,
5070 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071 return NULL;
5072 }
5073 argc = PySequence_Size(argv);
5074 if (argc < 1) {
5075 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 return NULL;
5077 }
5078
5079 argvlist = parse_arglist(argv, &argc);
5080 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005081 return NULL;
5082 }
5083
Larry Hastings2f936352014-08-05 14:04:04 +10005084 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005085
5086 /* If we get here it's definitely an error */
5087
5088 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005089 return posix_error();
5090}
5091
Larry Hastings2f936352014-08-05 14:04:04 +10005092
5093/*[clinic input]
5094os.execve
5095
5096 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5097 Path of executable file.
5098 argv: object
5099 Tuple or list of strings.
5100 env: object
5101 Dictionary of strings mapping to strings.
5102
5103Execute an executable path with arguments, replacing current process.
5104[clinic start generated code]*/
5105
Larry Hastings2f936352014-08-05 14:04:04 +10005106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005107os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5108/*[clinic end generated code: output=ff9fa8e4da8bde58 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005177os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5178/*[clinic end generated code: output=c427c0ce40f10638 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005254os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5255 PyObject *env)
5256/*[clinic end generated code: output=ebcfa5f7ba2f4219 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005345os_fork1_impl(PyObject *module)
5346/*[clinic end generated code: output=0de8e67ce2a310bc 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005382os_fork_impl(PyObject *module)
5383/*[clinic end generated code: output=3626c81f98985d49 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005420os_sched_get_priority_max_impl(PyObject *module, int policy)
5421/*[clinic end generated code: output=9e465c6e43130521 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005441os_sched_get_priority_min_impl(PyObject *module, int policy)
5442/*[clinic end generated code: output=7595c1138cc47a6d 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005464os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5465/*[clinic end generated code: output=dce4c0bd3f1b34c8 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005557os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005558 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005559/*[clinic end generated code: output=b0ac0a70d3b1d705 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005586os_sched_getparam_impl(PyObject *module, pid_t pid)
5587/*[clinic end generated code: output=b194e8708dcf2db8 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005621os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005622 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005623/*[clinic end generated code: output=8af013f78a32b591 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
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005644os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5645/*[clinic end generated code: output=7e2d935833ab47dc 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005664os_sched_yield_impl(PyObject *module)
5665/*[clinic end generated code: output=902323500f222cac 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005688os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5689/*[clinic end generated code: output=882d7dd9a229335b 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005784os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005785/*[clinic end generated code: output=f726f2c193c17a4f 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005880os_openpty_impl(PyObject *module)
5881/*[clinic end generated code: output=98841ce5ec9cef3c 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005982os_forkpty_impl(PyObject *module)
5983/*[clinic end generated code: output=60d0a5c7512e4087 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006018os_getegid_impl(PyObject *module)
6019/*[clinic end generated code: output=67d9be7ac68898a2 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006034os_geteuid_impl(PyObject *module)
6035/*[clinic end generated code: output=ea1b60f0d6abb66e 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006050os_getgid_impl(PyObject *module)
6051/*[clinic end generated code: output=4f28ebc9d3e5dfcf 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006065os_getpid_impl(PyObject *module)
6066/*[clinic end generated code: output=9ea6fdac01ed2b3c 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006157os_getgroups_impl(PyObject *module)
6158/*[clinic end generated code: output=42b0c17758561b56 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006312os_getpgid_impl(PyObject *module, pid_t pid)
6313/*[clinic end generated code: output=1db95a97be205d18 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006331os_getpgrp_impl(PyObject *module)
6332/*[clinic end generated code: output=c4fc381e51103cf3 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006351os_setpgrp_impl(PyObject *module)
6352/*[clinic end generated code: output=2554735b0a60f0a0 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006420os_getppid_impl(PyObject *module)
6421/*[clinic end generated code: output=43b2a946a8c603b4 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006440os_getlogin_impl(PyObject *module)
6441/*[clinic end generated code: output=a32e66a7e5715dac 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006483os_getuid_impl(PyObject *module)
6484/*[clinic end generated code: output=415c0b401ebed11a 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006507os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6508/*[clinic end generated code: output=8e346a6701c88568 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006568os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6569/*[clinic end generated code: output=6dbcd2f1fdf5fdba 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006596os_plock_impl(PyObject *module, int op)
6597/*[clinic end generated code: output=81424167033b168e 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006617os_setuid_impl(PyObject *module, uid_t uid)
6618/*[clinic end generated code: output=a0a41fd0d1ec555f 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. Kuchling8d2f2b22000-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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006638os_seteuid_impl(PyObject *module, uid_t euid)
6639/*[clinic end generated code: output=102e3ad98361519a 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. Kuchling8d2f2b22000-07-13 01:26:58 +00006644}
6645#endif /* HAVE_SETEUID */
6646
Larry Hastings2f936352014-08-05 14:04:04 +10006647
Andrew M. Kuchling8d2f2b22000-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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006659os_setegid_impl(PyObject *module, gid_t egid)
6660/*[clinic end generated code: output=4e4b825a6a10258d 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. Kuchling8d2f2b22000-07-13 01:26:58 +00006665}
6666#endif /* HAVE_SETEGID */
6667
Larry Hastings2f936352014-08-05 14:04:04 +10006668
Andrew M. Kuchling8d2f2b22000-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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006681os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6682/*[clinic end generated code: output=62d991210006530a 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. Kuchling8d2f2b22000-07-13 01:26:58 +00006690}
6691#endif /* HAVE_SETREUID */
6692
Larry Hastings2f936352014-08-05 14:04:04 +10006693
Andrew M. Kuchling8d2f2b22000-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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006706os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6707/*[clinic end generated code: output=aa803835cf5342f3 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. Kuchling8d2f2b22000-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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006726os_setgid_impl(PyObject *module, gid_t gid)
6727/*[clinic end generated code: output=bdccd7403f6ad8c3 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006747os_setgroups(PyObject *module, PyObject *groups)
6748/*[clinic end generated code: output=3fcb32aad58c5ecd 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006862os_wait3_impl(PyObject *module, int options)
6863/*[clinic end generated code: output=92c3224e6f28217a 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006899os_wait4_impl(PyObject *module, pid_t pid, int options)
6900/*[clinic end generated code: output=66195aa507b35f70 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006941os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6942/*[clinic end generated code: output=5d2e1c0bde61f4d8 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006996os_waitpid_impl(PyObject *module, pid_t pid, int options)
6997/*[clinic end generated code: output=5c37c06887a20270 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007031os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7032/*[clinic end generated code: output=15f1ce005a346b09 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007063os_wait_impl(PyObject *module)
7064/*[clinic end generated code: output=6bc419ac32fb364b 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
Martin Panter70214ad2016-08-04 02:38:59 +00007152 char target_buffer[_Py_MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7153 _Py_REPARSE_DATA_BUFFER *rdb = (_Py_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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007391os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007392 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007393/*[clinic end generated code: output=08ca9f3f3cf960f6 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007541os_times_impl(PyObject *module)
7542/*[clinic end generated code: output=35f640503557d32a 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007595os_getsid_impl(PyObject *module, pid_t pid)
7596/*[clinic end generated code: output=112deae56b306460 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007615os_setsid_impl(PyObject *module)
7616/*[clinic end generated code: output=e2ddedd517086d77 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007637os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7638/*[clinic end generated code: output=6461160319a43d6a 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007658os_tcgetpgrp_impl(PyObject *module, int fd)
7659/*[clinic end generated code: output=f865e88be86c272b 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 *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007681os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7682/*[clinic end generated code: output=f1821a381b9daa39 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
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007716os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7717/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007718{
7719 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007720 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007721
Victor Stinnerdaf45552013-08-28 00:53:59 +02007722#ifdef O_CLOEXEC
7723 int *atomic_flag_works = &_Py_open_cloexec_works;
7724#elif !defined(MS_WINDOWS)
7725 int *atomic_flag_works = NULL;
7726#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007727
Victor Stinnerdaf45552013-08-28 00:53:59 +02007728#ifdef MS_WINDOWS
7729 flags |= O_NOINHERIT;
7730#elif defined(O_CLOEXEC)
7731 flags |= O_CLOEXEC;
7732#endif
7733
Steve Dower8fc89802015-04-12 00:26:27 -04007734 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007735 do {
7736 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007737#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007738 if (path->wide)
7739 fd = _wopen(path->wide, flags, mode);
7740 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741#endif
7742#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007743 if (dir_fd != DEFAULT_DIR_FD)
7744 fd = openat(dir_fd, path->narrow, flags, mode);
7745 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007746#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007747 fd = open(path->narrow, flags, mode);
7748 Py_END_ALLOW_THREADS
7749 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007750 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007751
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007752 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007753 if (!async_err)
7754 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007755 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007756 }
7757
Victor Stinnerdaf45552013-08-28 00:53:59 +02007758#ifndef MS_WINDOWS
7759 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7760 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007761 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007762 }
7763#endif
7764
Larry Hastings2f936352014-08-05 14:04:04 +10007765 return fd;
7766}
7767
7768
7769/*[clinic input]
7770os.close
7771
7772 fd: int
7773
7774Close a file descriptor.
7775[clinic start generated code]*/
7776
Barry Warsaw53699e91996-12-10 23:23:01 +00007777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007778os_close_impl(PyObject *module, int fd)
7779/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007780{
Larry Hastings2f936352014-08-05 14:04:04 +10007781 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007782 if (!_PyVerify_fd(fd))
7783 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007784 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7785 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7786 * for more details.
7787 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007789 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007791 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007792 Py_END_ALLOW_THREADS
7793 if (res < 0)
7794 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007795 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007796}
7797
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007798
Larry Hastings2f936352014-08-05 14:04:04 +10007799/*[clinic input]
7800os.closerange
7801
7802 fd_low: int
7803 fd_high: int
7804 /
7805
7806Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7807[clinic start generated code]*/
7808
Larry Hastings2f936352014-08-05 14:04:04 +10007809static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007810os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7811/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007812{
7813 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007815 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007816 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 if (_PyVerify_fd(i))
7818 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007819 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007820 Py_END_ALLOW_THREADS
7821 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007822}
7823
7824
Larry Hastings2f936352014-08-05 14:04:04 +10007825/*[clinic input]
7826os.dup -> int
7827
7828 fd: int
7829 /
7830
7831Return a duplicate of a file descriptor.
7832[clinic start generated code]*/
7833
Larry Hastings2f936352014-08-05 14:04:04 +10007834static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007835os_dup_impl(PyObject *module, int fd)
7836/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007837{
7838 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007839}
7840
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007841
Larry Hastings2f936352014-08-05 14:04:04 +10007842/*[clinic input]
7843os.dup2
7844 fd: int
7845 fd2: int
7846 inheritable: bool=True
7847
7848Duplicate file descriptor.
7849[clinic start generated code]*/
7850
Larry Hastings2f936352014-08-05 14:04:04 +10007851static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007852os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7853/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007854{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007855 int res;
7856#if defined(HAVE_DUP3) && \
7857 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7858 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7859 int dup3_works = -1;
7860#endif
7861
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 if (!_PyVerify_fd_dup2(fd, fd2))
7863 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007864
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007865 /* dup2() can fail with EINTR if the target FD is already open, because it
7866 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7867 * upon close(), and therefore below.
7868 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007869#ifdef MS_WINDOWS
7870 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007871 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007873 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007874 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007875 if (res < 0)
7876 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007877
7878 /* Character files like console cannot be make non-inheritable */
7879 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7880 close(fd2);
7881 return NULL;
7882 }
7883
7884#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7885 Py_BEGIN_ALLOW_THREADS
7886 if (!inheritable)
7887 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7888 else
7889 res = dup2(fd, fd2);
7890 Py_END_ALLOW_THREADS
7891 if (res < 0)
7892 return posix_error();
7893
7894#else
7895
7896#ifdef HAVE_DUP3
7897 if (!inheritable && dup3_works != 0) {
7898 Py_BEGIN_ALLOW_THREADS
7899 res = dup3(fd, fd2, O_CLOEXEC);
7900 Py_END_ALLOW_THREADS
7901 if (res < 0) {
7902 if (dup3_works == -1)
7903 dup3_works = (errno != ENOSYS);
7904 if (dup3_works)
7905 return posix_error();
7906 }
7907 }
7908
7909 if (inheritable || dup3_works == 0)
7910 {
7911#endif
7912 Py_BEGIN_ALLOW_THREADS
7913 res = dup2(fd, fd2);
7914 Py_END_ALLOW_THREADS
7915 if (res < 0)
7916 return posix_error();
7917
7918 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7919 close(fd2);
7920 return NULL;
7921 }
7922#ifdef HAVE_DUP3
7923 }
7924#endif
7925
7926#endif
7927
Larry Hastings2f936352014-08-05 14:04:04 +10007928 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007929}
7930
Larry Hastings2f936352014-08-05 14:04:04 +10007931
Ross Lagerwall7807c352011-03-17 20:20:30 +02007932#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007933/*[clinic input]
7934os.lockf
7935
7936 fd: int
7937 An open file descriptor.
7938 command: int
7939 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7940 length: Py_off_t
7941 The number of bytes to lock, starting at the current position.
7942 /
7943
7944Apply, test or remove a POSIX lock on an open file descriptor.
7945
7946[clinic start generated code]*/
7947
Larry Hastings2f936352014-08-05 14:04:04 +10007948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007949os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7950/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007951{
7952 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007953
7954 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007955 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007956 Py_END_ALLOW_THREADS
7957
7958 if (res < 0)
7959 return posix_error();
7960
7961 Py_RETURN_NONE;
7962}
Larry Hastings2f936352014-08-05 14:04:04 +10007963#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007965
Larry Hastings2f936352014-08-05 14:04:04 +10007966/*[clinic input]
7967os.lseek -> Py_off_t
7968
7969 fd: int
7970 position: Py_off_t
7971 how: int
7972 /
7973
7974Set the position of a file descriptor. Return the new position.
7975
7976Return the new cursor position in number of bytes
7977relative to the beginning of the file.
7978[clinic start generated code]*/
7979
Larry Hastings2f936352014-08-05 14:04:04 +10007980static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007981os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7982/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007983{
7984 Py_off_t result;
7985
7986 if (!_PyVerify_fd(fd)) {
7987 posix_error();
7988 return -1;
7989 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007990#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7992 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007993 case 0: how = SEEK_SET; break;
7994 case 1: how = SEEK_CUR; break;
7995 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007997#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007998
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008000 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008001
Larry Hastings2f936352014-08-05 14:04:04 +10008002 if (!_PyVerify_fd(fd)) {
8003 posix_error();
8004 return -1;
8005 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008006 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008007 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008008#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008009 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008010#else
Larry Hastings2f936352014-08-05 14:04:04 +10008011 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008012#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008013 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008015 if (result < 0)
8016 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008017
Larry Hastings2f936352014-08-05 14:04:04 +10008018 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008019}
8020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008021
Larry Hastings2f936352014-08-05 14:04:04 +10008022/*[clinic input]
8023os.read
8024 fd: int
8025 length: Py_ssize_t
8026 /
8027
8028Read from a file descriptor. Returns a bytes object.
8029[clinic start generated code]*/
8030
Larry Hastings2f936352014-08-05 14:04:04 +10008031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008032os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8033/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008034{
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 Py_ssize_t n;
8036 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008037
8038 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 errno = EINVAL;
8040 return posix_error();
8041 }
Larry Hastings2f936352014-08-05 14:04:04 +10008042
8043#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008044 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008045 if (length > INT_MAX)
8046 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008047#endif
8048
8049 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 if (buffer == NULL)
8051 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008052
Victor Stinner66aab0c2015-03-19 22:53:20 +01008053 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8054 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008056 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008057 }
Larry Hastings2f936352014-08-05 14:04:04 +10008058
8059 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008061
Victor Stinner8c62be82010-05-06 00:08:46 +00008062 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008063}
8064
Ross Lagerwall7807c352011-03-17 20:20:30 +02008065#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8066 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008067static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008068iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8069{
8070 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008071 Py_ssize_t blen, total = 0;
8072
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073 *iov = PyMem_New(struct iovec, cnt);
8074 if (*iov == NULL) {
8075 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008076 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 *buf = PyMem_New(Py_buffer, cnt);
8080 if (*buf == NULL) {
8081 PyMem_Del(*iov);
8082 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008083 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 }
8085
8086 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008087 PyObject *item = PySequence_GetItem(seq, i);
8088 if (item == NULL)
8089 goto fail;
8090 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8091 Py_DECREF(item);
8092 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008093 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008094 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008096 blen = (*buf)[i].len;
8097 (*iov)[i].iov_len = blen;
8098 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008099 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008100 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008101
8102fail:
8103 PyMem_Del(*iov);
8104 for (j = 0; j < i; j++) {
8105 PyBuffer_Release(&(*buf)[j]);
8106 }
8107 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008108 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008109}
8110
8111static void
8112iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8113{
8114 int i;
8115 PyMem_Del(iov);
8116 for (i = 0; i < cnt; i++) {
8117 PyBuffer_Release(&buf[i]);
8118 }
8119 PyMem_Del(buf);
8120}
8121#endif
8122
Larry Hastings2f936352014-08-05 14:04:04 +10008123
Ross Lagerwall7807c352011-03-17 20:20:30 +02008124#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008125/*[clinic input]
8126os.readv -> Py_ssize_t
8127
8128 fd: int
8129 buffers: object
8130 /
8131
8132Read from a file descriptor fd into an iterable of buffers.
8133
8134The buffers should be mutable buffers accepting bytes.
8135readv will transfer data into each buffer until it is full
8136and then move on to the next buffer in the sequence to hold
8137the rest of the data.
8138
8139readv returns the total number of bytes read,
8140which may be less than the total capacity of all the buffers.
8141[clinic start generated code]*/
8142
Larry Hastings2f936352014-08-05 14:04:04 +10008143static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008144os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8145/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008146{
8147 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150 struct iovec *iov;
8151 Py_buffer *buf;
8152
Larry Hastings2f936352014-08-05 14:04:04 +10008153 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008154 PyErr_SetString(PyExc_TypeError,
8155 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008156 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008157 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008158
Larry Hastings2f936352014-08-05 14:04:04 +10008159 cnt = PySequence_Size(buffers);
8160
8161 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8162 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008163
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008164 do {
8165 Py_BEGIN_ALLOW_THREADS
8166 n = readv(fd, iov, cnt);
8167 Py_END_ALLOW_THREADS
8168 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169
8170 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008171 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008172 if (!async_err)
8173 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008174 return -1;
8175 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008176
Larry Hastings2f936352014-08-05 14:04:04 +10008177 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008178}
Larry Hastings2f936352014-08-05 14:04:04 +10008179#endif /* HAVE_READV */
8180
Ross Lagerwall7807c352011-03-17 20:20:30 +02008181
8182#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008183/*[clinic input]
8184# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8185os.pread
8186
8187 fd: int
8188 length: int
8189 offset: Py_off_t
8190 /
8191
8192Read a number of bytes from a file descriptor starting at a particular offset.
8193
8194Read length bytes from file descriptor fd, starting at offset bytes from
8195the beginning of the file. The file offset remains unchanged.
8196[clinic start generated code]*/
8197
Larry Hastings2f936352014-08-05 14:04:04 +10008198static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008199os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8200/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008201{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008202 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008203 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008204 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008205
Larry Hastings2f936352014-08-05 14:04:04 +10008206 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008207 errno = EINVAL;
8208 return posix_error();
8209 }
Larry Hastings2f936352014-08-05 14:04:04 +10008210 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008211 if (buffer == NULL)
8212 return NULL;
8213 if (!_PyVerify_fd(fd)) {
8214 Py_DECREF(buffer);
8215 return posix_error();
8216 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008217
8218 do {
8219 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008220 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008221 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008222 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008223 Py_END_ALLOW_THREADS
8224 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8225
Ross Lagerwall7807c352011-03-17 20:20:30 +02008226 if (n < 0) {
8227 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008228 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008229 }
Larry Hastings2f936352014-08-05 14:04:04 +10008230 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008231 _PyBytes_Resize(&buffer, n);
8232 return buffer;
8233}
Larry Hastings2f936352014-08-05 14:04:04 +10008234#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008235
Larry Hastings2f936352014-08-05 14:04:04 +10008236
8237/*[clinic input]
8238os.write -> Py_ssize_t
8239
8240 fd: int
8241 data: Py_buffer
8242 /
8243
8244Write a bytes object to a file descriptor.
8245[clinic start generated code]*/
8246
Larry Hastings2f936352014-08-05 14:04:04 +10008247static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008248os_write_impl(PyObject *module, int fd, Py_buffer *data)
8249/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008250{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008251 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008252}
8253
8254#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008256"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008257sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008258 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008259Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008260
Larry Hastings2f936352014-08-05 14:04:04 +10008261/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008262static PyObject *
8263posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8264{
8265 int in, out;
8266 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008267 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008268 off_t offset;
8269
8270#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8271#ifndef __APPLE__
8272 Py_ssize_t len;
8273#endif
8274 PyObject *headers = NULL, *trailers = NULL;
8275 Py_buffer *hbuf, *tbuf;
8276 off_t sbytes;
8277 struct sf_hdtr sf;
8278 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008279 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008280 static char *keywords[] = {"out", "in",
8281 "offset", "count",
8282 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008283
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008284 sf.headers = NULL;
8285 sf.trailers = NULL;
8286
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008287#ifdef __APPLE__
8288 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008289 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008290#else
8291 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008292 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008293#endif
8294 &headers, &trailers, &flags))
8295 return NULL;
8296 if (headers != NULL) {
8297 if (!PySequence_Check(headers)) {
8298 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008299 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008300 return NULL;
8301 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008302 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008303 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008304 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008305 (i = iov_setup(&(sf.headers), &hbuf,
8306 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008308#ifdef __APPLE__
8309 sbytes += i;
8310#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 }
8312 }
8313 if (trailers != NULL) {
8314 if (!PySequence_Check(trailers)) {
8315 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008316 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317 return NULL;
8318 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008319 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008321 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008322 (i = iov_setup(&(sf.trailers), &tbuf,
8323 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008324 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008325#ifdef __APPLE__
8326 sbytes += i;
8327#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008328 }
8329 }
8330
Steve Dower8fc89802015-04-12 00:26:27 -04008331 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008332 do {
8333 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008334#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008335 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008336#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008337 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008338#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008339 Py_END_ALLOW_THREADS
8340 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008341 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008342
8343 if (sf.headers != NULL)
8344 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8345 if (sf.trailers != NULL)
8346 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8347
8348 if (ret < 0) {
8349 if ((errno == EAGAIN) || (errno == EBUSY)) {
8350 if (sbytes != 0) {
8351 // some data has been sent
8352 goto done;
8353 }
8354 else {
8355 // no data has been sent; upper application is supposed
8356 // to retry on EAGAIN or EBUSY
8357 return posix_error();
8358 }
8359 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008360 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008361 }
8362 goto done;
8363
8364done:
8365 #if !defined(HAVE_LARGEFILE_SUPPORT)
8366 return Py_BuildValue("l", sbytes);
8367 #else
8368 return Py_BuildValue("L", sbytes);
8369 #endif
8370
8371#else
8372 Py_ssize_t count;
8373 PyObject *offobj;
8374 static char *keywords[] = {"out", "in",
8375 "offset", "count", NULL};
8376 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8377 keywords, &out, &in, &offobj, &count))
8378 return NULL;
8379#ifdef linux
8380 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008381 do {
8382 Py_BEGIN_ALLOW_THREADS
8383 ret = sendfile(out, in, NULL, count);
8384 Py_END_ALLOW_THREADS
8385 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008387 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008388 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008389 }
8390#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008391 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008392 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008393
8394 do {
8395 Py_BEGIN_ALLOW_THREADS
8396 ret = sendfile(out, in, &offset, count);
8397 Py_END_ALLOW_THREADS
8398 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008399 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008400 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008401 return Py_BuildValue("n", ret);
8402#endif
8403}
Larry Hastings2f936352014-08-05 14:04:04 +10008404#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008405
Larry Hastings2f936352014-08-05 14:04:04 +10008406
8407/*[clinic input]
8408os.fstat
8409
8410 fd : int
8411
8412Perform a stat system call on the given file descriptor.
8413
8414Like stat(), but for an open file descriptor.
8415Equivalent to os.stat(fd).
8416[clinic start generated code]*/
8417
Larry Hastings2f936352014-08-05 14:04:04 +10008418static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008419os_fstat_impl(PyObject *module, int fd)
8420/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008421{
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 STRUCT_STAT st;
8423 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008425
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008426 do {
8427 Py_BEGIN_ALLOW_THREADS
8428 res = FSTAT(fd, &st);
8429 Py_END_ALLOW_THREADS
8430 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008431 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008432#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008433 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008434#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008435 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008436#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008437 }
Tim Peters5aa91602002-01-30 05:46:57 +00008438
Victor Stinner4195b5c2012-02-08 23:03:19 +01008439 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008440}
8441
Larry Hastings2f936352014-08-05 14:04:04 +10008442
8443/*[clinic input]
8444os.isatty -> bool
8445 fd: int
8446 /
8447
8448Return True if the fd is connected to a terminal.
8449
8450Return True if the file descriptor is an open file descriptor
8451connected to the slave end of a terminal.
8452[clinic start generated code]*/
8453
Larry Hastings2f936352014-08-05 14:04:04 +10008454static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008455os_isatty_impl(PyObject *module, int fd)
8456/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008457{
Steve Dower8fc89802015-04-12 00:26:27 -04008458 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008459 if (!_PyVerify_fd(fd))
8460 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008461 _Py_BEGIN_SUPPRESS_IPH
8462 return_value = isatty(fd);
8463 _Py_END_SUPPRESS_IPH
8464 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008465}
8466
8467
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008468#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008469/*[clinic input]
8470os.pipe
8471
8472Create a pipe.
8473
8474Returns a tuple of two file descriptors:
8475 (read_fd, write_fd)
8476[clinic start generated code]*/
8477
Larry Hastings2f936352014-08-05 14:04:04 +10008478static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008479os_pipe_impl(PyObject *module)
8480/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008481{
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008483#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008485 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008486 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008487#else
8488 int res;
8489#endif
8490
8491#ifdef MS_WINDOWS
8492 attr.nLength = sizeof(attr);
8493 attr.lpSecurityDescriptor = NULL;
8494 attr.bInheritHandle = FALSE;
8495
8496 Py_BEGIN_ALLOW_THREADS
8497 ok = CreatePipe(&read, &write, &attr, 0);
8498 if (ok) {
8499 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8500 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8501 if (fds[0] == -1 || fds[1] == -1) {
8502 CloseHandle(read);
8503 CloseHandle(write);
8504 ok = 0;
8505 }
8506 }
8507 Py_END_ALLOW_THREADS
8508
Victor Stinner8c62be82010-05-06 00:08:46 +00008509 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008510 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008511#else
8512
8513#ifdef HAVE_PIPE2
8514 Py_BEGIN_ALLOW_THREADS
8515 res = pipe2(fds, O_CLOEXEC);
8516 Py_END_ALLOW_THREADS
8517
8518 if (res != 0 && errno == ENOSYS)
8519 {
8520#endif
8521 Py_BEGIN_ALLOW_THREADS
8522 res = pipe(fds);
8523 Py_END_ALLOW_THREADS
8524
8525 if (res == 0) {
8526 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8527 close(fds[0]);
8528 close(fds[1]);
8529 return NULL;
8530 }
8531 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8532 close(fds[0]);
8533 close(fds[1]);
8534 return NULL;
8535 }
8536 }
8537#ifdef HAVE_PIPE2
8538 }
8539#endif
8540
8541 if (res != 0)
8542 return PyErr_SetFromErrno(PyExc_OSError);
8543#endif /* !MS_WINDOWS */
8544 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008545}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008546#endif /* HAVE_PIPE */
8547
Larry Hastings2f936352014-08-05 14:04:04 +10008548
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008549#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008550/*[clinic input]
8551os.pipe2
8552
8553 flags: int
8554 /
8555
8556Create a pipe with flags set atomically.
8557
8558Returns a tuple of two file descriptors:
8559 (read_fd, write_fd)
8560
8561flags can be constructed by ORing together one or more of these values:
8562O_NONBLOCK, O_CLOEXEC.
8563[clinic start generated code]*/
8564
Larry Hastings2f936352014-08-05 14:04:04 +10008565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008566os_pipe2_impl(PyObject *module, int flags)
8567/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008568{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008569 int fds[2];
8570 int res;
8571
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008572 res = pipe2(fds, flags);
8573 if (res != 0)
8574 return posix_error();
8575 return Py_BuildValue("(ii)", fds[0], fds[1]);
8576}
8577#endif /* HAVE_PIPE2 */
8578
Larry Hastings2f936352014-08-05 14:04:04 +10008579
Ross Lagerwall7807c352011-03-17 20:20:30 +02008580#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008581/*[clinic input]
8582os.writev -> Py_ssize_t
8583 fd: int
8584 buffers: object
8585 /
8586
8587Iterate over buffers, and write the contents of each to a file descriptor.
8588
8589Returns the total number of bytes written.
8590buffers must be a sequence of bytes-like objects.
8591[clinic start generated code]*/
8592
Larry Hastings2f936352014-08-05 14:04:04 +10008593static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008594os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8595/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008596{
8597 int cnt;
8598 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008599 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008600 struct iovec *iov;
8601 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008602
8603 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008604 PyErr_SetString(PyExc_TypeError,
8605 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008606 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008607 }
Larry Hastings2f936352014-08-05 14:04:04 +10008608 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008609
Larry Hastings2f936352014-08-05 14:04:04 +10008610 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8611 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008612 }
8613
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008614 do {
8615 Py_BEGIN_ALLOW_THREADS
8616 result = writev(fd, iov, cnt);
8617 Py_END_ALLOW_THREADS
8618 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008619
8620 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008621 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008622 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008623
Georg Brandl306336b2012-06-24 12:55:33 +02008624 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008625}
Larry Hastings2f936352014-08-05 14:04:04 +10008626#endif /* HAVE_WRITEV */
8627
8628
8629#ifdef HAVE_PWRITE
8630/*[clinic input]
8631os.pwrite -> Py_ssize_t
8632
8633 fd: int
8634 buffer: Py_buffer
8635 offset: Py_off_t
8636 /
8637
8638Write bytes to a file descriptor starting at a particular offset.
8639
8640Write buffer to fd, starting at offset bytes from the beginning of
8641the file. Returns the number of bytes writte. Does not change the
8642current file offset.
8643[clinic start generated code]*/
8644
Larry Hastings2f936352014-08-05 14:04:04 +10008645static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008646os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8647/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008648{
8649 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008650 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008651
8652 if (!_PyVerify_fd(fd)) {
8653 posix_error();
8654 return -1;
8655 }
8656
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008657 do {
8658 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008659 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008660 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008661 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008662 Py_END_ALLOW_THREADS
8663 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008664
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008665 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008666 posix_error();
8667 return size;
8668}
8669#endif /* HAVE_PWRITE */
8670
8671
8672#ifdef HAVE_MKFIFO
8673/*[clinic input]
8674os.mkfifo
8675
8676 path: path_t
8677 mode: int=0o666
8678 *
8679 dir_fd: dir_fd(requires='mkfifoat')=None
8680
8681Create a "fifo" (a POSIX named pipe).
8682
8683If dir_fd is not None, it should be a file descriptor open to a directory,
8684 and path should be relative; path will then be relative to that directory.
8685dir_fd may not be implemented on your platform.
8686 If it is unavailable, using it will raise a NotImplementedError.
8687[clinic start generated code]*/
8688
Larry Hastings2f936352014-08-05 14:04:04 +10008689static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008690os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8691/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008692{
8693 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008694 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008695
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008696 do {
8697 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008698#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008699 if (dir_fd != DEFAULT_DIR_FD)
8700 result = mkfifoat(dir_fd, path->narrow, mode);
8701 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008702#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008703 result = mkfifo(path->narrow, mode);
8704 Py_END_ALLOW_THREADS
8705 } while (result != 0 && errno == EINTR &&
8706 !(async_err = PyErr_CheckSignals()));
8707 if (result != 0)
8708 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008709
8710 Py_RETURN_NONE;
8711}
8712#endif /* HAVE_MKFIFO */
8713
8714
8715#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8716/*[clinic input]
8717os.mknod
8718
8719 path: path_t
8720 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008721 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008722 *
8723 dir_fd: dir_fd(requires='mknodat')=None
8724
8725Create a node in the file system.
8726
8727Create a node in the file system (file, device special file or named pipe)
8728at path. mode specifies both the permissions to use and the
8729type of node to be created, being combined (bitwise OR) with one of
8730S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8731device defines the newly created device special file (probably using
8732os.makedev()). Otherwise device is ignored.
8733
8734If dir_fd is not None, it should be a file descriptor open to a directory,
8735 and path should be relative; path will then be relative to that directory.
8736dir_fd may not be implemented on your platform.
8737 If it is unavailable, using it will raise a NotImplementedError.
8738[clinic start generated code]*/
8739
Larry Hastings2f936352014-08-05 14:04:04 +10008740static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008741os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008742 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008743/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008744{
8745 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008747
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008748 do {
8749 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008750#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008751 if (dir_fd != DEFAULT_DIR_FD)
8752 result = mknodat(dir_fd, path->narrow, mode, device);
8753 else
Larry Hastings2f936352014-08-05 14:04:04 +10008754#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008755 result = mknod(path->narrow, mode, device);
8756 Py_END_ALLOW_THREADS
8757 } while (result != 0 && errno == EINTR &&
8758 !(async_err = PyErr_CheckSignals()));
8759 if (result != 0)
8760 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008761
8762 Py_RETURN_NONE;
8763}
8764#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8765
8766
8767#ifdef HAVE_DEVICE_MACROS
8768/*[clinic input]
8769os.major -> unsigned_int
8770
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008771 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008772 /
8773
8774Extracts a device major number from a raw device number.
8775[clinic start generated code]*/
8776
Larry Hastings2f936352014-08-05 14:04:04 +10008777static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008778os_major_impl(PyObject *module, dev_t device)
8779/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008780{
8781 return major(device);
8782}
8783
8784
8785/*[clinic input]
8786os.minor -> unsigned_int
8787
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008788 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008789 /
8790
8791Extracts a device minor number from a raw device number.
8792[clinic start generated code]*/
8793
Larry Hastings2f936352014-08-05 14:04:04 +10008794static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008795os_minor_impl(PyObject *module, dev_t device)
8796/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008797{
8798 return minor(device);
8799}
8800
8801
8802/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008803os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008804
8805 major: int
8806 minor: int
8807 /
8808
8809Composes a raw device number from the major and minor device numbers.
8810[clinic start generated code]*/
8811
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008812static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008813os_makedev_impl(PyObject *module, int major, int minor)
8814/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008815{
8816 return makedev(major, minor);
8817}
8818#endif /* HAVE_DEVICE_MACROS */
8819
8820
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008821#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008822/*[clinic input]
8823os.ftruncate
8824
8825 fd: int
8826 length: Py_off_t
8827 /
8828
8829Truncate a file, specified by file descriptor, to a specific length.
8830[clinic start generated code]*/
8831
Larry Hastings2f936352014-08-05 14:04:04 +10008832static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008833os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8834/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008835{
8836 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008837 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008838
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008839 if (!_PyVerify_fd(fd))
8840 return posix_error();
8841
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008842 do {
8843 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008844 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008845#ifdef MS_WINDOWS
8846 result = _chsize_s(fd, length);
8847#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008848 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008849#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008850 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008851 Py_END_ALLOW_THREADS
8852 } while (result != 0 && errno == EINTR &&
8853 !(async_err = PyErr_CheckSignals()));
8854 if (result != 0)
8855 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008856 Py_RETURN_NONE;
8857}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008858#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008859
8860
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008861#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008862/*[clinic input]
8863os.truncate
8864 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8865 length: Py_off_t
8866
8867Truncate a file, specified by path, to a specific length.
8868
8869On some platforms, path may also be specified as an open file descriptor.
8870 If this functionality is unavailable, using it raises an exception.
8871[clinic start generated code]*/
8872
Larry Hastings2f936352014-08-05 14:04:04 +10008873static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008874os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8875/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008876{
8877 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008878#ifdef MS_WINDOWS
8879 int fd;
8880#endif
8881
8882 if (path->fd != -1)
8883 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008884
8885 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008886 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008887#ifdef MS_WINDOWS
8888 if (path->wide)
8889 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008890 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008891 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008892 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008893 result = -1;
8894 else {
8895 result = _chsize_s(fd, length);
8896 close(fd);
8897 if (result < 0)
8898 errno = result;
8899 }
8900#else
8901 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008902#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008903 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008904 Py_END_ALLOW_THREADS
8905 if (result < 0)
8906 return path_error(path);
8907
8908 Py_RETURN_NONE;
8909}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008910#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008911
Ross Lagerwall7807c352011-03-17 20:20:30 +02008912
Victor Stinnerd6b17692014-09-30 12:20:05 +02008913/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8914 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8915 defined, which is the case in Python on AIX. AIX bug report:
8916 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8917#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8918# define POSIX_FADVISE_AIX_BUG
8919#endif
8920
Victor Stinnerec39e262014-09-30 12:35:58 +02008921
Victor Stinnerd6b17692014-09-30 12:20:05 +02008922#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008923/*[clinic input]
8924os.posix_fallocate
8925
8926 fd: int
8927 offset: Py_off_t
8928 length: Py_off_t
8929 /
8930
8931Ensure a file has allocated at least a particular number of bytes on disk.
8932
8933Ensure that the file specified by fd encompasses a range of bytes
8934starting at offset bytes from the beginning and continuing for length bytes.
8935[clinic start generated code]*/
8936
Larry Hastings2f936352014-08-05 14:04:04 +10008937static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008938os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008939 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008940/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008941{
8942 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008943 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008944
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008945 do {
8946 Py_BEGIN_ALLOW_THREADS
8947 result = posix_fallocate(fd, offset, length);
8948 Py_END_ALLOW_THREADS
8949 } while (result != 0 && errno == EINTR &&
8950 !(async_err = PyErr_CheckSignals()));
8951 if (result != 0)
8952 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008953 Py_RETURN_NONE;
8954}
Victor Stinnerec39e262014-09-30 12:35:58 +02008955#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008956
Ross Lagerwall7807c352011-03-17 20:20:30 +02008957
Victor Stinnerd6b17692014-09-30 12:20:05 +02008958#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008959/*[clinic input]
8960os.posix_fadvise
8961
8962 fd: int
8963 offset: Py_off_t
8964 length: Py_off_t
8965 advice: int
8966 /
8967
8968Announce an intention to access data in a specific pattern.
8969
8970Announce an intention to access data in a specific pattern, thus allowing
8971the kernel to make optimizations.
8972The advice applies to the region of the file specified by fd starting at
8973offset and continuing for length bytes.
8974advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8975POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8976POSIX_FADV_DONTNEED.
8977[clinic start generated code]*/
8978
Larry Hastings2f936352014-08-05 14:04:04 +10008979static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008980os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008981 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008982/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008983{
8984 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008986
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008987 do {
8988 Py_BEGIN_ALLOW_THREADS
8989 result = posix_fadvise(fd, offset, length, advice);
8990 Py_END_ALLOW_THREADS
8991 } while (result != 0 && errno == EINTR &&
8992 !(async_err = PyErr_CheckSignals()));
8993 if (result != 0)
8994 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008995 Py_RETURN_NONE;
8996}
Victor Stinnerec39e262014-09-30 12:35:58 +02008997#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008998
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008999#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009000
Fred Drake762e2061999-08-26 17:23:54 +00009001/* Save putenv() parameters as values here, so we can collect them when they
9002 * get re-set with another call for the same key. */
9003static PyObject *posix_putenv_garbage;
9004
Larry Hastings2f936352014-08-05 14:04:04 +10009005static void
9006posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009007{
Larry Hastings2f936352014-08-05 14:04:04 +10009008 /* Install the first arg and newstr in posix_putenv_garbage;
9009 * this will cause previous value to be collected. This has to
9010 * happen after the real putenv() call because the old value
9011 * was still accessible until then. */
9012 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9013 /* really not much we can do; just leak */
9014 PyErr_Clear();
9015 else
9016 Py_DECREF(value);
9017}
9018
9019
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009020#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009021/*[clinic input]
9022os.putenv
9023
9024 name: unicode
9025 value: unicode
9026 /
9027
9028Change or add an environment variable.
9029[clinic start generated code]*/
9030
Larry Hastings2f936352014-08-05 14:04:04 +10009031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009032os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9033/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009034{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009035 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10009036
9037 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9038 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009039 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009040 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009041 }
Larry Hastings2f936352014-08-05 14:04:04 +10009042 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009043 PyErr_Format(PyExc_ValueError,
9044 "the environment variable is longer than %u characters",
9045 _MAX_ENV);
9046 goto error;
9047 }
9048
Larry Hastings2f936352014-08-05 14:04:04 +10009049 env = PyUnicode_AsUnicode(unicode);
9050 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009051 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009052 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009054 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009055 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009056
Larry Hastings2f936352014-08-05 14:04:04 +10009057 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009058 Py_RETURN_NONE;
9059
9060error:
Larry Hastings2f936352014-08-05 14:04:04 +10009061 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009062 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009063}
Larry Hastings2f936352014-08-05 14:04:04 +10009064#else /* MS_WINDOWS */
9065/*[clinic input]
9066os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009067
Larry Hastings2f936352014-08-05 14:04:04 +10009068 name: FSConverter
9069 value: FSConverter
9070 /
9071
9072Change or add an environment variable.
9073[clinic start generated code]*/
9074
Larry Hastings2f936352014-08-05 14:04:04 +10009075static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009076os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9077/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009078{
9079 PyObject *bytes = NULL;
9080 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009081 const char *name_string = PyBytes_AsString(name);
9082 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009083
9084 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9085 if (bytes == NULL) {
9086 PyErr_NoMemory();
9087 return NULL;
9088 }
9089
9090 env = PyBytes_AS_STRING(bytes);
9091 if (putenv(env)) {
9092 Py_DECREF(bytes);
9093 return posix_error();
9094 }
9095
9096 posix_putenv_garbage_setitem(name, bytes);
9097 Py_RETURN_NONE;
9098}
9099#endif /* MS_WINDOWS */
9100#endif /* HAVE_PUTENV */
9101
9102
9103#ifdef HAVE_UNSETENV
9104/*[clinic input]
9105os.unsetenv
9106 name: FSConverter
9107 /
9108
9109Delete an environment variable.
9110[clinic start generated code]*/
9111
Larry Hastings2f936352014-08-05 14:04:04 +10009112static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009113os_unsetenv_impl(PyObject *module, PyObject *name)
9114/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009115{
Victor Stinner984890f2011-11-24 13:53:38 +01009116#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009117 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009118#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009119
Victor Stinner984890f2011-11-24 13:53:38 +01009120#ifdef HAVE_BROKEN_UNSETENV
9121 unsetenv(PyBytes_AS_STRING(name));
9122#else
Victor Stinner65170952011-11-22 22:16:17 +01009123 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009124 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009125 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009126#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009127
Victor Stinner8c62be82010-05-06 00:08:46 +00009128 /* Remove the key from posix_putenv_garbage;
9129 * this will cause it to be collected. This has to
9130 * happen after the real unsetenv() call because the
9131 * old value was still accessible until then.
9132 */
Victor Stinner65170952011-11-22 22:16:17 +01009133 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009134 /* really not much we can do; just leak */
9135 PyErr_Clear();
9136 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009137 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009138}
Larry Hastings2f936352014-08-05 14:04:04 +10009139#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009140
Larry Hastings2f936352014-08-05 14:04:04 +10009141
9142/*[clinic input]
9143os.strerror
9144
9145 code: int
9146 /
9147
9148Translate an error code to a message string.
9149[clinic start generated code]*/
9150
Larry Hastings2f936352014-08-05 14:04:04 +10009151static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009152os_strerror_impl(PyObject *module, int code)
9153/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009154{
9155 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009156 if (message == NULL) {
9157 PyErr_SetString(PyExc_ValueError,
9158 "strerror() argument out of range");
9159 return NULL;
9160 }
Victor Stinner1b579672011-12-17 05:47:23 +01009161 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009162}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009163
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009164
Guido van Rossumc9641791998-08-04 15:26:23 +00009165#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009166#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009167/*[clinic input]
9168os.WCOREDUMP -> bool
9169
9170 status: int
9171 /
9172
9173Return True if the process returning status was dumped to a core file.
9174[clinic start generated code]*/
9175
Larry Hastings2f936352014-08-05 14:04:04 +10009176static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009177os_WCOREDUMP_impl(PyObject *module, int status)
9178/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009179{
9180 WAIT_TYPE wait_status;
9181 WAIT_STATUS_INT(wait_status) = status;
9182 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009183}
9184#endif /* WCOREDUMP */
9185
Larry Hastings2f936352014-08-05 14:04:04 +10009186
Fred Drake106c1a02002-04-23 15:58:02 +00009187#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009188/*[clinic input]
9189os.WIFCONTINUED -> bool
9190
9191 status: int
9192
9193Return True if a particular process was continued from a job control stop.
9194
9195Return True if the process returning status was continued from a
9196job control stop.
9197[clinic start generated code]*/
9198
Larry Hastings2f936352014-08-05 14:04:04 +10009199static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009200os_WIFCONTINUED_impl(PyObject *module, int status)
9201/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009202{
9203 WAIT_TYPE wait_status;
9204 WAIT_STATUS_INT(wait_status) = status;
9205 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009206}
9207#endif /* WIFCONTINUED */
9208
Larry Hastings2f936352014-08-05 14:04:04 +10009209
Guido van Rossumc9641791998-08-04 15:26:23 +00009210#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009211/*[clinic input]
9212os.WIFSTOPPED -> bool
9213
9214 status: int
9215
9216Return True if the process returning status was stopped.
9217[clinic start generated code]*/
9218
Larry Hastings2f936352014-08-05 14:04:04 +10009219static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009220os_WIFSTOPPED_impl(PyObject *module, int status)
9221/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009222{
9223 WAIT_TYPE wait_status;
9224 WAIT_STATUS_INT(wait_status) = status;
9225 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009226}
9227#endif /* WIFSTOPPED */
9228
Larry Hastings2f936352014-08-05 14:04:04 +10009229
Guido van Rossumc9641791998-08-04 15:26:23 +00009230#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009231/*[clinic input]
9232os.WIFSIGNALED -> bool
9233
9234 status: int
9235
9236Return True if the process returning status was terminated by a signal.
9237[clinic start generated code]*/
9238
Larry Hastings2f936352014-08-05 14:04:04 +10009239static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009240os_WIFSIGNALED_impl(PyObject *module, int status)
9241/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009242{
9243 WAIT_TYPE wait_status;
9244 WAIT_STATUS_INT(wait_status) = status;
9245 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009246}
9247#endif /* WIFSIGNALED */
9248
Larry Hastings2f936352014-08-05 14:04:04 +10009249
Guido van Rossumc9641791998-08-04 15:26:23 +00009250#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009251/*[clinic input]
9252os.WIFEXITED -> bool
9253
9254 status: int
9255
9256Return True if the process returning status exited via the exit() system call.
9257[clinic start generated code]*/
9258
Larry Hastings2f936352014-08-05 14:04:04 +10009259static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009260os_WIFEXITED_impl(PyObject *module, int status)
9261/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009262{
9263 WAIT_TYPE wait_status;
9264 WAIT_STATUS_INT(wait_status) = status;
9265 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009266}
9267#endif /* WIFEXITED */
9268
Larry Hastings2f936352014-08-05 14:04:04 +10009269
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009270#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009271/*[clinic input]
9272os.WEXITSTATUS -> int
9273
9274 status: int
9275
9276Return the process return code from status.
9277[clinic start generated code]*/
9278
Larry Hastings2f936352014-08-05 14:04:04 +10009279static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009280os_WEXITSTATUS_impl(PyObject *module, int status)
9281/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009282{
9283 WAIT_TYPE wait_status;
9284 WAIT_STATUS_INT(wait_status) = status;
9285 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009286}
9287#endif /* WEXITSTATUS */
9288
Larry Hastings2f936352014-08-05 14:04:04 +10009289
Guido van Rossumc9641791998-08-04 15:26:23 +00009290#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009291/*[clinic input]
9292os.WTERMSIG -> int
9293
9294 status: int
9295
9296Return the signal that terminated the process that provided the status value.
9297[clinic start generated code]*/
9298
Larry Hastings2f936352014-08-05 14:04:04 +10009299static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009300os_WTERMSIG_impl(PyObject *module, int status)
9301/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009302{
9303 WAIT_TYPE wait_status;
9304 WAIT_STATUS_INT(wait_status) = status;
9305 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009306}
9307#endif /* WTERMSIG */
9308
Larry Hastings2f936352014-08-05 14:04:04 +10009309
Guido van Rossumc9641791998-08-04 15:26:23 +00009310#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009311/*[clinic input]
9312os.WSTOPSIG -> int
9313
9314 status: int
9315
9316Return the signal that stopped the process that provided the status value.
9317[clinic start generated code]*/
9318
Larry Hastings2f936352014-08-05 14:04:04 +10009319static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009320os_WSTOPSIG_impl(PyObject *module, int status)
9321/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009322{
9323 WAIT_TYPE wait_status;
9324 WAIT_STATUS_INT(wait_status) = status;
9325 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009326}
9327#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009328#endif /* HAVE_SYS_WAIT_H */
9329
9330
Thomas Wouters477c8d52006-05-27 19:21:47 +00009331#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009332#ifdef _SCO_DS
9333/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9334 needed definitions in sys/statvfs.h */
9335#define _SVID3
9336#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009337#include <sys/statvfs.h>
9338
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009339static PyObject*
9340_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009341 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9342 if (v == NULL)
9343 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009344
9345#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009346 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9347 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9348 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9349 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9350 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9351 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9352 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9353 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9354 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9355 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009356#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9358 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9359 PyStructSequence_SET_ITEM(v, 2,
9360 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9361 PyStructSequence_SET_ITEM(v, 3,
9362 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9363 PyStructSequence_SET_ITEM(v, 4,
9364 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9365 PyStructSequence_SET_ITEM(v, 5,
9366 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9367 PyStructSequence_SET_ITEM(v, 6,
9368 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9369 PyStructSequence_SET_ITEM(v, 7,
9370 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9371 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9372 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009373#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009374 if (PyErr_Occurred()) {
9375 Py_DECREF(v);
9376 return NULL;
9377 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009378
Victor Stinner8c62be82010-05-06 00:08:46 +00009379 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009380}
9381
Larry Hastings2f936352014-08-05 14:04:04 +10009382
9383/*[clinic input]
9384os.fstatvfs
9385 fd: int
9386 /
9387
9388Perform an fstatvfs system call on the given fd.
9389
9390Equivalent to statvfs(fd).
9391[clinic start generated code]*/
9392
Larry Hastings2f936352014-08-05 14:04:04 +10009393static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009394os_fstatvfs_impl(PyObject *module, int fd)
9395/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009396{
9397 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009398 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009399 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009400
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009401 do {
9402 Py_BEGIN_ALLOW_THREADS
9403 result = fstatvfs(fd, &st);
9404 Py_END_ALLOW_THREADS
9405 } while (result != 0 && errno == EINTR &&
9406 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009407 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009408 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009409
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009411}
Larry Hastings2f936352014-08-05 14:04:04 +10009412#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009413
9414
Thomas Wouters477c8d52006-05-27 19:21:47 +00009415#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009416#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009417/*[clinic input]
9418os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009419
Larry Hastings2f936352014-08-05 14:04:04 +10009420 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9421
9422Perform a statvfs system call on the given path.
9423
9424path may always be specified as a string.
9425On some platforms, path may also be specified as an open file descriptor.
9426 If this functionality is unavailable, using it raises an exception.
9427[clinic start generated code]*/
9428
Larry Hastings2f936352014-08-05 14:04:04 +10009429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009430os_statvfs_impl(PyObject *module, path_t *path)
9431/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009432{
9433 int result;
9434 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009435
9436 Py_BEGIN_ALLOW_THREADS
9437#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009438 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009439#ifdef __APPLE__
9440 /* handle weak-linking on Mac OS X 10.3 */
9441 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009442 fd_specified("statvfs", path->fd);
9443 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009444 }
9445#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009446 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009447 }
9448 else
9449#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009450 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009451 Py_END_ALLOW_THREADS
9452
9453 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009454 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009455 }
9456
Larry Hastings2f936352014-08-05 14:04:04 +10009457 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009458}
Larry Hastings2f936352014-08-05 14:04:04 +10009459#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9460
Guido van Rossum94f6f721999-01-06 18:42:14 +00009461
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009462#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009463/*[clinic input]
9464os._getdiskusage
9465
9466 path: Py_UNICODE
9467
9468Return disk usage statistics about the given path as a (total, free) tuple.
9469[clinic start generated code]*/
9470
Larry Hastings2f936352014-08-05 14:04:04 +10009471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009472os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9473/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009474{
9475 BOOL retval;
9476 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009477
9478 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009479 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009480 Py_END_ALLOW_THREADS
9481 if (retval == 0)
9482 return PyErr_SetFromWindowsErr(0);
9483
9484 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9485}
Larry Hastings2f936352014-08-05 14:04:04 +10009486#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009487
9488
Fred Drakec9680921999-12-13 16:37:25 +00009489/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9490 * It maps strings representing configuration variable names to
9491 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009492 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009493 * rarely-used constants. There are three separate tables that use
9494 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009495 *
9496 * This code is always included, even if none of the interfaces that
9497 * need it are included. The #if hackery needed to avoid it would be
9498 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009499 */
9500struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009501 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009502 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009503};
9504
Fred Drake12c6e2d1999-12-14 21:25:03 +00009505static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009506conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009507 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009508{
Christian Heimes217cfd12007-12-02 14:31:20 +00009509 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009510 int value = _PyLong_AsInt(arg);
9511 if (value == -1 && PyErr_Occurred())
9512 return 0;
9513 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009514 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009515 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009516 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009517 /* look up the value in the table using a binary search */
9518 size_t lo = 0;
9519 size_t mid;
9520 size_t hi = tablesize;
9521 int cmp;
9522 const char *confname;
9523 if (!PyUnicode_Check(arg)) {
9524 PyErr_SetString(PyExc_TypeError,
9525 "configuration names must be strings or integers");
9526 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009528 confname = _PyUnicode_AsString(arg);
9529 if (confname == NULL)
9530 return 0;
9531 while (lo < hi) {
9532 mid = (lo + hi) / 2;
9533 cmp = strcmp(confname, table[mid].name);
9534 if (cmp < 0)
9535 hi = mid;
9536 else if (cmp > 0)
9537 lo = mid + 1;
9538 else {
9539 *valuep = table[mid].value;
9540 return 1;
9541 }
9542 }
9543 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9544 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009546}
9547
9548
9549#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9550static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009551#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009553#endif
9554#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009556#endif
Fred Drakec9680921999-12-13 16:37:25 +00009557#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
9590#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009591 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009592#endif
9593#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009594 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009595#endif
9596#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009597 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009598#endif
9599#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009600 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009601#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009602#ifdef _PC_ACL_ENABLED
9603 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9604#endif
9605#ifdef _PC_MIN_HOLE_SIZE
9606 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9607#endif
9608#ifdef _PC_ALLOC_SIZE_MIN
9609 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9610#endif
9611#ifdef _PC_REC_INCR_XFER_SIZE
9612 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9613#endif
9614#ifdef _PC_REC_MAX_XFER_SIZE
9615 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9616#endif
9617#ifdef _PC_REC_MIN_XFER_SIZE
9618 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9619#endif
9620#ifdef _PC_REC_XFER_ALIGN
9621 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9622#endif
9623#ifdef _PC_SYMLINK_MAX
9624 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9625#endif
9626#ifdef _PC_XATTR_ENABLED
9627 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9628#endif
9629#ifdef _PC_XATTR_EXISTS
9630 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9631#endif
9632#ifdef _PC_TIMESTAMP_RESOLUTION
9633 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9634#endif
Fred Drakec9680921999-12-13 16:37:25 +00009635};
9636
Fred Drakec9680921999-12-13 16:37:25 +00009637static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009638conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009639{
9640 return conv_confname(arg, valuep, posix_constants_pathconf,
9641 sizeof(posix_constants_pathconf)
9642 / sizeof(struct constdef));
9643}
9644#endif
9645
Larry Hastings2f936352014-08-05 14:04:04 +10009646
Fred Drakec9680921999-12-13 16:37:25 +00009647#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009648/*[clinic input]
9649os.fpathconf -> long
9650
9651 fd: int
9652 name: path_confname
9653 /
9654
9655Return the configuration limit name for the file descriptor fd.
9656
9657If there is no limit, return -1.
9658[clinic start generated code]*/
9659
Larry Hastings2f936352014-08-05 14:04:04 +10009660static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009661os_fpathconf_impl(PyObject *module, int fd, int name)
9662/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009663{
9664 long limit;
9665
9666 errno = 0;
9667 limit = fpathconf(fd, name);
9668 if (limit == -1 && errno != 0)
9669 posix_error();
9670
9671 return limit;
9672}
9673#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009674
9675
9676#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009677/*[clinic input]
9678os.pathconf -> long
9679 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9680 name: path_confname
9681
9682Return the configuration limit name for the file or directory path.
9683
9684If there is no limit, return -1.
9685On some platforms, path may also be specified as an open file descriptor.
9686 If this functionality is unavailable, using it raises an exception.
9687[clinic start generated code]*/
9688
Larry Hastings2f936352014-08-05 14:04:04 +10009689static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009690os_pathconf_impl(PyObject *module, path_t *path, int name)
9691/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009692{
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009694
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009696#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009697 if (path->fd != -1)
9698 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009699 else
9700#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009701 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 if (limit == -1 && errno != 0) {
9703 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009704 /* could be a path or name problem */
9705 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009706 else
Larry Hastings2f936352014-08-05 14:04:04 +10009707 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 }
Larry Hastings2f936352014-08-05 14:04:04 +10009709
9710 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009711}
Larry Hastings2f936352014-08-05 14:04:04 +10009712#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009713
9714#ifdef HAVE_CONFSTR
9715static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009716#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009719#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009721#endif
9722#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009724#endif
Fred Draked86ed291999-12-15 15:34:33 +00009725#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009727#endif
9728#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009730#endif
9731#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009733#endif
9734#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009736#endif
Fred Drakec9680921999-12-13 16:37:25 +00009737#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
9749#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009751#endif
9752#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
9755#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009757#endif
9758#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009760#endif
Fred Draked86ed291999-12-15 15:34:33 +00009761#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
Fred Drakec9680921999-12-13 16:37:25 +00009764#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
Fred Draked86ed291999-12-15 15:34:33 +00009767#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009769#endif
9770#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009772#endif
9773#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009775#endif
9776#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009778#endif
Fred Drakec9680921999-12-13 16:37:25 +00009779#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
9815#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009817#endif
9818#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009820#endif
9821#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009823#endif
9824#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009826#endif
Fred Draked86ed291999-12-15 15:34:33 +00009827#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009829#endif
9830#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009832#endif
9833#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009835#endif
9836#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
9845#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
9848#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009850#endif
9851#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009853#endif
9854#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009855 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009856#endif
9857#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009858 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009859#endif
9860#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009861 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009862#endif
9863#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009864 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009865#endif
Fred Drakec9680921999-12-13 16:37:25 +00009866};
9867
9868static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009869conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009870{
9871 return conv_confname(arg, valuep, posix_constants_confstr,
9872 sizeof(posix_constants_confstr)
9873 / sizeof(struct constdef));
9874}
9875
Larry Hastings2f936352014-08-05 14:04:04 +10009876
9877/*[clinic input]
9878os.confstr
9879
9880 name: confstr_confname
9881 /
9882
9883Return a string-valued system configuration variable.
9884[clinic start generated code]*/
9885
Larry Hastings2f936352014-08-05 14:04:04 +10009886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009887os_confstr_impl(PyObject *module, int name)
9888/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009889{
9890 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009891 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009892 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009893
Victor Stinnercb043522010-09-10 23:49:04 +00009894 errno = 0;
9895 len = confstr(name, buffer, sizeof(buffer));
9896 if (len == 0) {
9897 if (errno) {
9898 posix_error();
9899 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009900 }
9901 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009902 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009903 }
9904 }
Victor Stinnercb043522010-09-10 23:49:04 +00009905
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009906 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009907 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009908 char *buf = PyMem_Malloc(len);
9909 if (buf == NULL)
9910 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009911 len2 = confstr(name, buf, len);
9912 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009913 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009914 PyMem_Free(buf);
9915 }
9916 else
9917 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009918 return result;
9919}
Larry Hastings2f936352014-08-05 14:04:04 +10009920#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009921
9922
9923#ifdef HAVE_SYSCONF
9924static struct constdef posix_constants_sysconf[] = {
9925#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
9943#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
9946#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
Fred Draked86ed291999-12-15 15:34:33 +00009955#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009957#endif
9958#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009960#endif
Fred Drakec9680921999-12-13 16:37:25 +00009961#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
Fred Drakec9680921999-12-13 16:37:25 +00009964#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
Fred Draked86ed291999-12-15 15:34:33 +00009979#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009981#endif
Fred Drakec9680921999-12-13 16:37:25 +00009982#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
Fred Draked86ed291999-12-15 15:34:33 +00009997#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009999#endif
Fred Drakec9680921999-12-13 16:37:25 +000010000#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
Fred Draked86ed291999-12-15 15:34:33 +000010069#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010071#endif
Fred Drakec9680921999-12-13 16:37:25 +000010072#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
10075#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
Fred Draked86ed291999-12-15 15:34:33 +000010081#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010083#endif
Fred Drakec9680921999-12-13 16:37:25 +000010084#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
Fred Draked86ed291999-12-15 15:34:33 +000010087#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010089#endif
10090#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010092#endif
Fred Drakec9680921999-12-13 16:37:25 +000010093#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
Fred Draked86ed291999-12-15 15:34:33 +000010105#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010107#endif
Fred Drakec9680921999-12-13 16:37:25 +000010108#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
10120#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
Fred Draked86ed291999-12-15 15:34:33 +000010129#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010131#endif
Fred Drakec9680921999-12-13 16:37:25 +000010132#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
Fred Draked86ed291999-12-15 15:34:33 +000010138#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010140#endif
Fred Drakec9680921999-12-13 16:37:25 +000010141#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
10156#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
Fred Draked86ed291999-12-15 15:34:33 +000010168#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010170#endif
10171#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010173#endif
Fred Drakec9680921999-12-13 16:37:25 +000010174#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
Fred Draked86ed291999-12-15 15:34:33 +000010279#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010281#endif
Fred Drakec9680921999-12-13 16:37:25 +000010282#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010406 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010407#endif
10408#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010409 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010410#endif
10411#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010412 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010413#endif
10414#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010415 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010416#endif
10417};
10418
10419static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010420conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010421{
10422 return conv_confname(arg, valuep, posix_constants_sysconf,
10423 sizeof(posix_constants_sysconf)
10424 / sizeof(struct constdef));
10425}
10426
Larry Hastings2f936352014-08-05 14:04:04 +100010427
10428/*[clinic input]
10429os.sysconf -> long
10430 name: sysconf_confname
10431 /
10432
10433Return an integer-valued system configuration variable.
10434[clinic start generated code]*/
10435
Larry Hastings2f936352014-08-05 14:04:04 +100010436static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010437os_sysconf_impl(PyObject *module, int name)
10438/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010439{
10440 long value;
10441
10442 errno = 0;
10443 value = sysconf(name);
10444 if (value == -1 && errno != 0)
10445 posix_error();
10446 return value;
10447}
10448#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010449
10450
Fred Drakebec628d1999-12-15 18:31:10 +000010451/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010452 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010453 * the exported dictionaries that are used to publish information about the
10454 * names available on the host platform.
10455 *
10456 * Sorting the table at runtime ensures that the table is properly ordered
10457 * when used, even for platforms we're not able to test on. It also makes
10458 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010459 */
Fred Drakebec628d1999-12-15 18:31:10 +000010460
10461static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010462cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010463{
10464 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010466 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010468
10469 return strcmp(c1->name, c2->name);
10470}
10471
10472static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010473setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010474 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010475{
Fred Drakebec628d1999-12-15 18:31:10 +000010476 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010477 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010478
10479 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10480 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010481 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010483
Barry Warsaw3155db32000-04-13 15:20:40 +000010484 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010485 PyObject *o = PyLong_FromLong(table[i].value);
10486 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10487 Py_XDECREF(o);
10488 Py_DECREF(d);
10489 return -1;
10490 }
10491 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010492 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010493 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010494}
10495
Fred Drakebec628d1999-12-15 18:31:10 +000010496/* Return -1 on failure, 0 on success. */
10497static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010498setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010499{
10500#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010501 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010502 sizeof(posix_constants_pathconf)
10503 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010504 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010505 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010506#endif
10507#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010508 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010509 sizeof(posix_constants_confstr)
10510 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010511 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010512 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010513#endif
10514#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010515 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010516 sizeof(posix_constants_sysconf)
10517 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010518 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010519 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010520#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010521 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010522}
Fred Draked86ed291999-12-15 15:34:33 +000010523
10524
Larry Hastings2f936352014-08-05 14:04:04 +100010525/*[clinic input]
10526os.abort
10527
10528Abort the interpreter immediately.
10529
10530This function 'dumps core' or otherwise fails in the hardest way possible
10531on the hosting operating system. This function never returns.
10532[clinic start generated code]*/
10533
Larry Hastings2f936352014-08-05 14:04:04 +100010534static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010535os_abort_impl(PyObject *module)
10536/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010537{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010538 abort();
10539 /*NOTREACHED*/
10540 Py_FatalError("abort() called from Python code didn't abort!");
10541 return NULL;
10542}
Fred Drakebec628d1999-12-15 18:31:10 +000010543
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010544#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010545/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010546PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010547"startfile(filepath [, operation])\n\
10548\n\
10549Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010550\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010551When \"operation\" is not specified or \"open\", this acts like\n\
10552double-clicking the file in Explorer, or giving the file name as an\n\
10553argument to the DOS \"start\" command: the file is opened with whatever\n\
10554application (if any) its extension is associated.\n\
10555When another \"operation\" is given, it specifies what should be done with\n\
10556the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010557\n\
10558startfile returns as soon as the associated application is launched.\n\
10559There is no option to wait for the application to close, and no way\n\
10560to retrieve the application's exit status.\n\
10561\n\
10562The filepath is relative to the current directory. If you want to use\n\
10563an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010564the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010565
Steve Dower7d0e0c92015-01-24 08:18:24 -080010566/* Grab ShellExecute dynamically from shell32 */
10567static int has_ShellExecute = -1;
10568static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10569 LPCSTR, INT);
10570static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10571 LPCWSTR, INT);
10572static int
10573check_ShellExecute()
10574{
10575 HINSTANCE hShell32;
10576
10577 /* only recheck */
10578 if (-1 == has_ShellExecute) {
10579 Py_BEGIN_ALLOW_THREADS
10580 hShell32 = LoadLibraryW(L"SHELL32");
10581 Py_END_ALLOW_THREADS
10582 if (hShell32) {
10583 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10584 "ShellExecuteA");
10585 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10586 "ShellExecuteW");
10587 has_ShellExecute = Py_ShellExecuteA &&
10588 Py_ShellExecuteW;
10589 } else {
10590 has_ShellExecute = 0;
10591 }
10592 }
10593 return has_ShellExecute;
10594}
10595
10596
Tim Petersf58a7aa2000-09-22 10:05:54 +000010597static PyObject *
10598win32_startfile(PyObject *self, PyObject *args)
10599{
Victor Stinner8c62be82010-05-06 00:08:46 +000010600 PyObject *ofilepath;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010601 const char *filepath;
10602 const char *operation = NULL;
10603 const wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010605
Victor Stinnereb5657a2011-09-30 01:44:27 +020010606 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010607
10608 if(!check_ShellExecute()) {
10609 /* If the OS doesn't have ShellExecute, return a
10610 NotImplementedError. */
10611 return PyErr_Format(PyExc_NotImplementedError,
10612 "startfile not available on this platform");
10613 }
10614
Victor Stinner8c62be82010-05-06 00:08:46 +000010615 if (!PyArg_ParseTuple(args, "U|s:startfile",
10616 &unipath, &operation)) {
10617 PyErr_Clear();
10618 goto normal;
10619 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010620
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010622 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010624 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 PyErr_Clear();
10626 operation = NULL;
10627 goto normal;
10628 }
10629 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010630
Victor Stinnereb5657a2011-09-30 01:44:27 +020010631 wpath = PyUnicode_AsUnicode(unipath);
10632 if (wpath == NULL)
10633 goto normal;
10634 if (uoperation) {
10635 woperation = PyUnicode_AsUnicode(uoperation);
10636 if (woperation == NULL)
10637 goto normal;
10638 }
10639 else
10640 woperation = NULL;
10641
Victor Stinner8c62be82010-05-06 00:08:46 +000010642 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010643 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10644 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 Py_END_ALLOW_THREADS
10646
Victor Stinnereb5657a2011-09-30 01:44:27 +020010647 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010649 win32_error_object("startfile", unipath);
10650 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010651 }
10652 Py_INCREF(Py_None);
10653 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010654
10655normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10657 PyUnicode_FSConverter, &ofilepath,
10658 &operation))
10659 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010660 if (win32_warn_bytes_api()) {
10661 Py_DECREF(ofilepath);
10662 return NULL;
10663 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 filepath = PyBytes_AsString(ofilepath);
10665 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010666 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10667 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010668 Py_END_ALLOW_THREADS
10669 if (rc <= (HINSTANCE)32) {
10670 PyObject *errval = win32_error("startfile", filepath);
10671 Py_DECREF(ofilepath);
10672 return errval;
10673 }
10674 Py_DECREF(ofilepath);
10675 Py_INCREF(Py_None);
10676 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010677}
Larry Hastings2f936352014-08-05 14:04:04 +100010678#endif /* MS_WINDOWS */
10679
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010680
Martin v. Löwis438b5342002-12-27 10:16:42 +000010681#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010682/*[clinic input]
10683os.getloadavg
10684
10685Return average recent system load information.
10686
10687Return the number of processes in the system run queue averaged over
10688the last 1, 5, and 15 minutes as a tuple of three floats.
10689Raises OSError if the load average was unobtainable.
10690[clinic start generated code]*/
10691
Larry Hastings2f936352014-08-05 14:04:04 +100010692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010693os_getloadavg_impl(PyObject *module)
10694/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010695{
10696 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010697 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010698 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10699 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010700 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010701 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010702}
Larry Hastings2f936352014-08-05 14:04:04 +100010703#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010704
Larry Hastings2f936352014-08-05 14:04:04 +100010705
10706/*[clinic input]
10707os.device_encoding
10708 fd: int
10709
10710Return a string describing the encoding of a terminal's file descriptor.
10711
10712The file descriptor must be attached to a terminal.
10713If the device is not a terminal, return None.
10714[clinic start generated code]*/
10715
Larry Hastings2f936352014-08-05 14:04:04 +100010716static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010717os_device_encoding_impl(PyObject *module, int fd)
10718/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010719{
Brett Cannonefb00c02012-02-29 18:31:31 -050010720 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010721}
10722
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010723
Larry Hastings2f936352014-08-05 14:04:04 +100010724#ifdef HAVE_SETRESUID
10725/*[clinic input]
10726os.setresuid
10727
10728 ruid: uid_t
10729 euid: uid_t
10730 suid: uid_t
10731 /
10732
10733Set the current process's real, effective, and saved user ids.
10734[clinic start generated code]*/
10735
Larry Hastings2f936352014-08-05 14:04:04 +100010736static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010737os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10738/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010739{
Victor Stinner8c62be82010-05-06 00:08:46 +000010740 if (setresuid(ruid, euid, suid) < 0)
10741 return posix_error();
10742 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010743}
Larry Hastings2f936352014-08-05 14:04:04 +100010744#endif /* HAVE_SETRESUID */
10745
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010746
10747#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010748/*[clinic input]
10749os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010750
Larry Hastings2f936352014-08-05 14:04:04 +100010751 rgid: gid_t
10752 egid: gid_t
10753 sgid: gid_t
10754 /
10755
10756Set the current process's real, effective, and saved group ids.
10757[clinic start generated code]*/
10758
Larry Hastings2f936352014-08-05 14:04:04 +100010759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010760os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10761/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010762{
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 if (setresgid(rgid, egid, sgid) < 0)
10764 return posix_error();
10765 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010766}
Larry Hastings2f936352014-08-05 14:04:04 +100010767#endif /* HAVE_SETRESGID */
10768
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010769
10770#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010771/*[clinic input]
10772os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010773
Larry Hastings2f936352014-08-05 14:04:04 +100010774Return a tuple of the current process's real, effective, and saved user ids.
10775[clinic start generated code]*/
10776
Larry Hastings2f936352014-08-05 14:04:04 +100010777static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010778os_getresuid_impl(PyObject *module)
10779/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010780{
Victor Stinner8c62be82010-05-06 00:08:46 +000010781 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010782 if (getresuid(&ruid, &euid, &suid) < 0)
10783 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010784 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10785 _PyLong_FromUid(euid),
10786 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010787}
Larry Hastings2f936352014-08-05 14:04:04 +100010788#endif /* HAVE_GETRESUID */
10789
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010790
10791#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010792/*[clinic input]
10793os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010794
Larry Hastings2f936352014-08-05 14:04:04 +100010795Return a tuple of the current process's real, effective, and saved group ids.
10796[clinic start generated code]*/
10797
Larry Hastings2f936352014-08-05 14:04:04 +100010798static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010799os_getresgid_impl(PyObject *module)
10800/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010801{
10802 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010803 if (getresgid(&rgid, &egid, &sgid) < 0)
10804 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010805 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10806 _PyLong_FromGid(egid),
10807 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010808}
Larry Hastings2f936352014-08-05 14:04:04 +100010809#endif /* HAVE_GETRESGID */
10810
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010811
Benjamin Peterson9428d532011-09-14 11:45:52 -040010812#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010813/*[clinic input]
10814os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010815
Larry Hastings2f936352014-08-05 14:04:04 +100010816 path: path_t(allow_fd=True)
10817 attribute: path_t
10818 *
10819 follow_symlinks: bool = True
10820
10821Return the value of extended attribute attribute on path.
10822
10823path may be either a string or an open file descriptor.
10824If follow_symlinks is False, and the last element of the path is a symbolic
10825 link, getxattr will examine the symbolic link itself instead of the file
10826 the link points to.
10827
10828[clinic start generated code]*/
10829
Larry Hastings2f936352014-08-05 14:04:04 +100010830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010831os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010832 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010833/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010834{
10835 Py_ssize_t i;
10836 PyObject *buffer = NULL;
10837
10838 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10839 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010840
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 for (i = 0; ; i++) {
10842 void *ptr;
10843 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010844 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010845 Py_ssize_t buffer_size = buffer_sizes[i];
10846 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010847 path_error(path);
10848 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010849 }
10850 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10851 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010852 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010854
Larry Hastings9cf065c2012-06-22 16:30:09 -070010855 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010856 if (path->fd >= 0)
10857 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010859 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 else
Larry Hastings2f936352014-08-05 14:04:04 +100010861 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010862 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010863
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 if (result < 0) {
10865 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010866 if (errno == ERANGE)
10867 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010868 path_error(path);
10869 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010871
Larry Hastings9cf065c2012-06-22 16:30:09 -070010872 if (result != buffer_size) {
10873 /* Can only shrink. */
10874 _PyBytes_Resize(&buffer, result);
10875 }
10876 break;
10877 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010878
Larry Hastings9cf065c2012-06-22 16:30:09 -070010879 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010880}
10881
Larry Hastings2f936352014-08-05 14:04:04 +100010882
10883/*[clinic input]
10884os.setxattr
10885
10886 path: path_t(allow_fd=True)
10887 attribute: path_t
10888 value: Py_buffer
10889 flags: int = 0
10890 *
10891 follow_symlinks: bool = True
10892
10893Set extended attribute attribute on path to value.
10894
10895path may be either a string or an open file descriptor.
10896If follow_symlinks is False, and the last element of the path is a symbolic
10897 link, setxattr will modify the symbolic link itself instead of the file
10898 the link points to.
10899
10900[clinic start generated code]*/
10901
Benjamin Peterson799bd802011-08-31 22:15:17 -040010902static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010903os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010904 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010905/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010906{
Larry Hastings2f936352014-08-05 14:04:04 +100010907 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908
Larry Hastings2f936352014-08-05 14:04:04 +100010909 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010911
Benjamin Peterson799bd802011-08-31 22:15:17 -040010912 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010913 if (path->fd > -1)
10914 result = fsetxattr(path->fd, attribute->narrow,
10915 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010916 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010917 result = setxattr(path->narrow, attribute->narrow,
10918 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010919 else
Larry Hastings2f936352014-08-05 14:04:04 +100010920 result = lsetxattr(path->narrow, attribute->narrow,
10921 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010922 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010923
Larry Hastings9cf065c2012-06-22 16:30:09 -070010924 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010925 path_error(path);
10926 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010927 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010928
Larry Hastings2f936352014-08-05 14:04:04 +100010929 Py_RETURN_NONE;
10930}
10931
10932
10933/*[clinic input]
10934os.removexattr
10935
10936 path: path_t(allow_fd=True)
10937 attribute: path_t
10938 *
10939 follow_symlinks: bool = True
10940
10941Remove extended attribute attribute on path.
10942
10943path may be either a string or an open file descriptor.
10944If follow_symlinks is False, and the last element of the path is a symbolic
10945 link, removexattr will modify the symbolic link itself instead of the file
10946 the link points to.
10947
10948[clinic start generated code]*/
10949
Larry Hastings2f936352014-08-05 14:04:04 +100010950static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010951os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010952 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010953/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010954{
10955 ssize_t result;
10956
10957 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10958 return NULL;
10959
10960 Py_BEGIN_ALLOW_THREADS;
10961 if (path->fd > -1)
10962 result = fremovexattr(path->fd, attribute->narrow);
10963 else if (follow_symlinks)
10964 result = removexattr(path->narrow, attribute->narrow);
10965 else
10966 result = lremovexattr(path->narrow, attribute->narrow);
10967 Py_END_ALLOW_THREADS;
10968
10969 if (result) {
10970 return path_error(path);
10971 }
10972
10973 Py_RETURN_NONE;
10974}
10975
10976
10977/*[clinic input]
10978os.listxattr
10979
10980 path: path_t(allow_fd=True, nullable=True) = None
10981 *
10982 follow_symlinks: bool = True
10983
10984Return a list of extended attributes on path.
10985
10986path may be either None, a string, or an open file descriptor.
10987if path is None, listxattr will examine the current directory.
10988If follow_symlinks is False, and the last element of the path is a symbolic
10989 link, listxattr will examine the symbolic link itself instead of the file
10990 the link points to.
10991[clinic start generated code]*/
10992
Larry Hastings2f936352014-08-05 14:04:04 +100010993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010994os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10995/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010996{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010997 Py_ssize_t i;
10998 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010999 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011000 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011001
Larry Hastings2f936352014-08-05 14:04:04 +100011002 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011004
Larry Hastings2f936352014-08-05 14:04:04 +100011005 name = path->narrow ? path->narrow : ".";
11006
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011008 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011010 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 Py_ssize_t buffer_size = buffer_sizes[i];
11012 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011013 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011014 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011015 break;
11016 }
11017 buffer = PyMem_MALLOC(buffer_size);
11018 if (!buffer) {
11019 PyErr_NoMemory();
11020 break;
11021 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011022
Larry Hastings9cf065c2012-06-22 16:30:09 -070011023 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011024 if (path->fd > -1)
11025 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011026 else if (follow_symlinks)
11027 length = listxattr(name, buffer, buffer_size);
11028 else
11029 length = llistxattr(name, buffer, buffer_size);
11030 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011031
Larry Hastings9cf065c2012-06-22 16:30:09 -070011032 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011033 if (errno == ERANGE) {
11034 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011035 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011036 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011037 }
Larry Hastings2f936352014-08-05 14:04:04 +100011038 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011039 break;
11040 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011041
Larry Hastings9cf065c2012-06-22 16:30:09 -070011042 result = PyList_New(0);
11043 if (!result) {
11044 goto exit;
11045 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011046
Larry Hastings9cf065c2012-06-22 16:30:09 -070011047 end = buffer + length;
11048 for (trace = start = buffer; trace != end; trace++) {
11049 if (!*trace) {
11050 int error;
11051 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11052 trace - start);
11053 if (!attribute) {
11054 Py_DECREF(result);
11055 result = NULL;
11056 goto exit;
11057 }
11058 error = PyList_Append(result, attribute);
11059 Py_DECREF(attribute);
11060 if (error) {
11061 Py_DECREF(result);
11062 result = NULL;
11063 goto exit;
11064 }
11065 start = trace + 1;
11066 }
11067 }
11068 break;
11069 }
11070exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011071 if (buffer)
11072 PyMem_FREE(buffer);
11073 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011074}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011075#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011076
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011077
Larry Hastings2f936352014-08-05 14:04:04 +100011078/*[clinic input]
11079os.urandom
11080
11081 size: Py_ssize_t
11082 /
11083
11084Return a bytes object containing random bytes suitable for cryptographic use.
11085[clinic start generated code]*/
11086
Larry Hastings2f936352014-08-05 14:04:04 +100011087static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011088os_urandom_impl(PyObject *module, Py_ssize_t size)
11089/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011090{
11091 PyObject *bytes;
11092 int result;
11093
Georg Brandl2fb477c2012-02-21 00:33:36 +010011094 if (size < 0)
11095 return PyErr_Format(PyExc_ValueError,
11096 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011097 bytes = PyBytes_FromStringAndSize(NULL, size);
11098 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011099 return NULL;
11100
Larry Hastings2f936352014-08-05 14:04:04 +100011101 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11102 PyBytes_GET_SIZE(bytes));
11103 if (result == -1) {
11104 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011105 return NULL;
11106 }
Larry Hastings2f936352014-08-05 14:04:04 +100011107 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011108}
11109
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011110/* Terminal size querying */
11111
11112static PyTypeObject TerminalSizeType;
11113
11114PyDoc_STRVAR(TerminalSize_docstring,
11115 "A tuple of (columns, lines) for holding terminal window size");
11116
11117static PyStructSequence_Field TerminalSize_fields[] = {
11118 {"columns", "width of the terminal window in characters"},
11119 {"lines", "height of the terminal window in characters"},
11120 {NULL, NULL}
11121};
11122
11123static PyStructSequence_Desc TerminalSize_desc = {
11124 "os.terminal_size",
11125 TerminalSize_docstring,
11126 TerminalSize_fields,
11127 2,
11128};
11129
11130#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011131/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011132PyDoc_STRVAR(termsize__doc__,
11133 "Return the size of the terminal window as (columns, lines).\n" \
11134 "\n" \
11135 "The optional argument fd (default standard output) specifies\n" \
11136 "which file descriptor should be queried.\n" \
11137 "\n" \
11138 "If the file descriptor is not connected to a terminal, an OSError\n" \
11139 "is thrown.\n" \
11140 "\n" \
11141 "This function will only be defined if an implementation is\n" \
11142 "available for this system.\n" \
11143 "\n" \
11144 "shutil.get_terminal_size is the high-level function which should \n" \
11145 "normally be used, os.get_terminal_size is the low-level implementation.");
11146
11147static PyObject*
11148get_terminal_size(PyObject *self, PyObject *args)
11149{
11150 int columns, lines;
11151 PyObject *termsize;
11152
11153 int fd = fileno(stdout);
11154 /* Under some conditions stdout may not be connected and
11155 * fileno(stdout) may point to an invalid file descriptor. For example
11156 * GUI apps don't have valid standard streams by default.
11157 *
11158 * If this happens, and the optional fd argument is not present,
11159 * the ioctl below will fail returning EBADF. This is what we want.
11160 */
11161
11162 if (!PyArg_ParseTuple(args, "|i", &fd))
11163 return NULL;
11164
11165#ifdef TERMSIZE_USE_IOCTL
11166 {
11167 struct winsize w;
11168 if (ioctl(fd, TIOCGWINSZ, &w))
11169 return PyErr_SetFromErrno(PyExc_OSError);
11170 columns = w.ws_col;
11171 lines = w.ws_row;
11172 }
11173#endif /* TERMSIZE_USE_IOCTL */
11174
11175#ifdef TERMSIZE_USE_CONIO
11176 {
11177 DWORD nhandle;
11178 HANDLE handle;
11179 CONSOLE_SCREEN_BUFFER_INFO csbi;
11180 switch (fd) {
11181 case 0: nhandle = STD_INPUT_HANDLE;
11182 break;
11183 case 1: nhandle = STD_OUTPUT_HANDLE;
11184 break;
11185 case 2: nhandle = STD_ERROR_HANDLE;
11186 break;
11187 default:
11188 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11189 }
11190 handle = GetStdHandle(nhandle);
11191 if (handle == NULL)
11192 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11193 if (handle == INVALID_HANDLE_VALUE)
11194 return PyErr_SetFromWindowsErr(0);
11195
11196 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11197 return PyErr_SetFromWindowsErr(0);
11198
11199 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11200 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11201 }
11202#endif /* TERMSIZE_USE_CONIO */
11203
11204 termsize = PyStructSequence_New(&TerminalSizeType);
11205 if (termsize == NULL)
11206 return NULL;
11207 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11208 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11209 if (PyErr_Occurred()) {
11210 Py_DECREF(termsize);
11211 return NULL;
11212 }
11213 return termsize;
11214}
11215#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11216
Larry Hastings2f936352014-08-05 14:04:04 +100011217
11218/*[clinic input]
11219os.cpu_count
11220
Charles-François Natali80d62e62015-08-13 20:37:08 +010011221Return the number of CPUs in the system; return None if indeterminable.
11222
11223This number is not equivalent to the number of CPUs the current process can
11224use. The number of usable CPUs can be obtained with
11225``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011226[clinic start generated code]*/
11227
Larry Hastings2f936352014-08-05 14:04:04 +100011228static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011229os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011230/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011231{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011232 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011233#ifdef MS_WINDOWS
11234 SYSTEM_INFO sysinfo;
11235 GetSystemInfo(&sysinfo);
11236 ncpu = sysinfo.dwNumberOfProcessors;
11237#elif defined(__hpux)
11238 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11239#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11240 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011241#elif defined(__DragonFly__) || \
11242 defined(__OpenBSD__) || \
11243 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011244 defined(__NetBSD__) || \
11245 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011246 int mib[2];
11247 size_t len = sizeof(ncpu);
11248 mib[0] = CTL_HW;
11249 mib[1] = HW_NCPU;
11250 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11251 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011252#endif
11253 if (ncpu >= 1)
11254 return PyLong_FromLong(ncpu);
11255 else
11256 Py_RETURN_NONE;
11257}
11258
Victor Stinnerdaf45552013-08-28 00:53:59 +020011259
Larry Hastings2f936352014-08-05 14:04:04 +100011260/*[clinic input]
11261os.get_inheritable -> bool
11262
11263 fd: int
11264 /
11265
11266Get the close-on-exe flag of the specified file descriptor.
11267[clinic start generated code]*/
11268
Larry Hastings2f936352014-08-05 14:04:04 +100011269static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011270os_get_inheritable_impl(PyObject *module, int fd)
11271/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011272{
Steve Dower8fc89802015-04-12 00:26:27 -040011273 int return_value;
11274 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011275 posix_error();
11276 return -1;
11277 }
11278
Steve Dower8fc89802015-04-12 00:26:27 -040011279 _Py_BEGIN_SUPPRESS_IPH
11280 return_value = _Py_get_inheritable(fd);
11281 _Py_END_SUPPRESS_IPH
11282 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011283}
11284
11285
11286/*[clinic input]
11287os.set_inheritable
11288 fd: int
11289 inheritable: int
11290 /
11291
11292Set the inheritable flag of the specified file descriptor.
11293[clinic start generated code]*/
11294
Larry Hastings2f936352014-08-05 14:04:04 +100011295static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011296os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11297/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011298{
Steve Dower8fc89802015-04-12 00:26:27 -040011299 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011300 if (!_PyVerify_fd(fd))
11301 return posix_error();
11302
Steve Dower8fc89802015-04-12 00:26:27 -040011303 _Py_BEGIN_SUPPRESS_IPH
11304 result = _Py_set_inheritable(fd, inheritable, NULL);
11305 _Py_END_SUPPRESS_IPH
11306 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011307 return NULL;
11308 Py_RETURN_NONE;
11309}
11310
11311
11312#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011313/*[clinic input]
11314os.get_handle_inheritable -> bool
11315 handle: Py_intptr_t
11316 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011317
Larry Hastings2f936352014-08-05 14:04:04 +100011318Get the close-on-exe flag of the specified file descriptor.
11319[clinic start generated code]*/
11320
Larry Hastings2f936352014-08-05 14:04:04 +100011321static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011322os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11323/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011324{
11325 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011326
11327 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11328 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011329 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011330 }
11331
Larry Hastings2f936352014-08-05 14:04:04 +100011332 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011333}
11334
Victor Stinnerdaf45552013-08-28 00:53:59 +020011335
Larry Hastings2f936352014-08-05 14:04:04 +100011336/*[clinic input]
11337os.set_handle_inheritable
11338 handle: Py_intptr_t
11339 inheritable: bool
11340 /
11341
11342Set the inheritable flag of the specified handle.
11343[clinic start generated code]*/
11344
Larry Hastings2f936352014-08-05 14:04:04 +100011345static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011346os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011347 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011348/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011349{
11350 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011351 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11352 PyErr_SetFromWindowsErr(0);
11353 return NULL;
11354 }
11355 Py_RETURN_NONE;
11356}
Larry Hastings2f936352014-08-05 14:04:04 +100011357#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011358
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011359#ifndef MS_WINDOWS
11360PyDoc_STRVAR(get_blocking__doc__,
11361 "get_blocking(fd) -> bool\n" \
11362 "\n" \
11363 "Get the blocking mode of the file descriptor:\n" \
11364 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11365
11366static PyObject*
11367posix_get_blocking(PyObject *self, PyObject *args)
11368{
11369 int fd;
11370 int blocking;
11371
11372 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11373 return NULL;
11374
11375 if (!_PyVerify_fd(fd))
11376 return posix_error();
11377
Steve Dower8fc89802015-04-12 00:26:27 -040011378 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011379 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011380 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011381 if (blocking < 0)
11382 return NULL;
11383 return PyBool_FromLong(blocking);
11384}
11385
11386PyDoc_STRVAR(set_blocking__doc__,
11387 "set_blocking(fd, blocking)\n" \
11388 "\n" \
11389 "Set the blocking mode of the specified file descriptor.\n" \
11390 "Set the O_NONBLOCK flag if blocking is False,\n" \
11391 "clear the O_NONBLOCK flag otherwise.");
11392
11393static PyObject*
11394posix_set_blocking(PyObject *self, PyObject *args)
11395{
Steve Dower8fc89802015-04-12 00:26:27 -040011396 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011397
11398 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11399 return NULL;
11400
11401 if (!_PyVerify_fd(fd))
11402 return posix_error();
11403
Steve Dower8fc89802015-04-12 00:26:27 -040011404 _Py_BEGIN_SUPPRESS_IPH
11405 result = _Py_set_blocking(fd, blocking);
11406 _Py_END_SUPPRESS_IPH
11407 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011408 return NULL;
11409 Py_RETURN_NONE;
11410}
11411#endif /* !MS_WINDOWS */
11412
11413
Victor Stinner6036e442015-03-08 01:58:04 +010011414PyDoc_STRVAR(posix_scandir__doc__,
11415"scandir(path='.') -> iterator of DirEntry objects for given path");
11416
11417static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11418
11419typedef struct {
11420 PyObject_HEAD
11421 PyObject *name;
11422 PyObject *path;
11423 PyObject *stat;
11424 PyObject *lstat;
11425#ifdef MS_WINDOWS
11426 struct _Py_stat_struct win32_lstat;
11427 __int64 win32_file_index;
11428 int got_file_index;
11429#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011430#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011431 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011432#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011433 ino_t d_ino;
11434#endif
11435} DirEntry;
11436
11437static void
11438DirEntry_dealloc(DirEntry *entry)
11439{
11440 Py_XDECREF(entry->name);
11441 Py_XDECREF(entry->path);
11442 Py_XDECREF(entry->stat);
11443 Py_XDECREF(entry->lstat);
11444 Py_TYPE(entry)->tp_free((PyObject *)entry);
11445}
11446
11447/* Forward reference */
11448static int
11449DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11450
11451/* Set exception and return -1 on error, 0 for False, 1 for True */
11452static int
11453DirEntry_is_symlink(DirEntry *self)
11454{
11455#ifdef MS_WINDOWS
11456 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011457#elif defined(HAVE_DIRENT_D_TYPE)
11458 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011459 if (self->d_type != DT_UNKNOWN)
11460 return self->d_type == DT_LNK;
11461 else
11462 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011463#else
11464 /* POSIX without d_type */
11465 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011466#endif
11467}
11468
11469static PyObject *
11470DirEntry_py_is_symlink(DirEntry *self)
11471{
11472 int result;
11473
11474 result = DirEntry_is_symlink(self);
11475 if (result == -1)
11476 return NULL;
11477 return PyBool_FromLong(result);
11478}
11479
11480static PyObject *
11481DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11482{
11483 int result;
11484 struct _Py_stat_struct st;
11485
11486#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011487 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011488
11489 path = PyUnicode_AsUnicode(self->path);
11490 if (!path)
11491 return NULL;
11492
11493 if (follow_symlinks)
11494 result = win32_stat_w(path, &st);
11495 else
11496 result = win32_lstat_w(path, &st);
11497
11498 if (result != 0) {
11499 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11500 0, self->path);
11501 }
11502#else /* POSIX */
11503 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011504 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011505
11506 if (!PyUnicode_FSConverter(self->path, &bytes))
11507 return NULL;
11508 path = PyBytes_AS_STRING(bytes);
11509
11510 if (follow_symlinks)
11511 result = STAT(path, &st);
11512 else
11513 result = LSTAT(path, &st);
11514 Py_DECREF(bytes);
11515
11516 if (result != 0)
11517 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11518#endif
11519
11520 return _pystat_fromstructstat(&st);
11521}
11522
11523static PyObject *
11524DirEntry_get_lstat(DirEntry *self)
11525{
11526 if (!self->lstat) {
11527#ifdef MS_WINDOWS
11528 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11529#else /* POSIX */
11530 self->lstat = DirEntry_fetch_stat(self, 0);
11531#endif
11532 }
11533 Py_XINCREF(self->lstat);
11534 return self->lstat;
11535}
11536
11537static PyObject *
11538DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11539{
11540 if (!follow_symlinks)
11541 return DirEntry_get_lstat(self);
11542
11543 if (!self->stat) {
11544 int result = DirEntry_is_symlink(self);
11545 if (result == -1)
11546 return NULL;
11547 else if (result)
11548 self->stat = DirEntry_fetch_stat(self, 1);
11549 else
11550 self->stat = DirEntry_get_lstat(self);
11551 }
11552
11553 Py_XINCREF(self->stat);
11554 return self->stat;
11555}
11556
11557static PyObject *
11558DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11559{
11560 int follow_symlinks = 1;
11561
11562 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11563 follow_symlinks_keywords, &follow_symlinks))
11564 return NULL;
11565
11566 return DirEntry_get_stat(self, follow_symlinks);
11567}
11568
11569/* Set exception and return -1 on error, 0 for False, 1 for True */
11570static int
11571DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11572{
11573 PyObject *stat = NULL;
11574 PyObject *st_mode = NULL;
11575 long mode;
11576 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011577#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011578 int is_symlink;
11579 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011580#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011581#ifdef MS_WINDOWS
11582 unsigned long dir_bits;
11583#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011584 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011585
11586#ifdef MS_WINDOWS
11587 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11588 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011589#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011590 is_symlink = self->d_type == DT_LNK;
11591 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11592#endif
11593
Victor Stinner35a97c02015-03-08 02:59:09 +010011594#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011595 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011596#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011597 stat = DirEntry_get_stat(self, follow_symlinks);
11598 if (!stat) {
11599 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11600 /* If file doesn't exist (anymore), then return False
11601 (i.e., say it's not a file/directory) */
11602 PyErr_Clear();
11603 return 0;
11604 }
11605 goto error;
11606 }
11607 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11608 if (!st_mode)
11609 goto error;
11610
11611 mode = PyLong_AsLong(st_mode);
11612 if (mode == -1 && PyErr_Occurred())
11613 goto error;
11614 Py_CLEAR(st_mode);
11615 Py_CLEAR(stat);
11616 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011617#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011618 }
11619 else if (is_symlink) {
11620 assert(mode_bits != S_IFLNK);
11621 result = 0;
11622 }
11623 else {
11624 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11625#ifdef MS_WINDOWS
11626 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11627 if (mode_bits == S_IFDIR)
11628 result = dir_bits != 0;
11629 else
11630 result = dir_bits == 0;
11631#else /* POSIX */
11632 if (mode_bits == S_IFDIR)
11633 result = self->d_type == DT_DIR;
11634 else
11635 result = self->d_type == DT_REG;
11636#endif
11637 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011638#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011639
11640 return result;
11641
11642error:
11643 Py_XDECREF(st_mode);
11644 Py_XDECREF(stat);
11645 return -1;
11646}
11647
11648static PyObject *
11649DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11650{
11651 int result;
11652
11653 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11654 if (result == -1)
11655 return NULL;
11656 return PyBool_FromLong(result);
11657}
11658
11659static PyObject *
11660DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11661{
11662 int follow_symlinks = 1;
11663
11664 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11665 follow_symlinks_keywords, &follow_symlinks))
11666 return NULL;
11667
11668 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11669}
11670
11671static PyObject *
11672DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11673{
11674 int follow_symlinks = 1;
11675
11676 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11677 follow_symlinks_keywords, &follow_symlinks))
11678 return NULL;
11679
11680 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11681}
11682
11683static PyObject *
11684DirEntry_inode(DirEntry *self)
11685{
11686#ifdef MS_WINDOWS
11687 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011688 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011689 struct _Py_stat_struct stat;
11690
11691 path = PyUnicode_AsUnicode(self->path);
11692 if (!path)
11693 return NULL;
11694
11695 if (win32_lstat_w(path, &stat) != 0) {
11696 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11697 0, self->path);
11698 }
11699
11700 self->win32_file_index = stat.st_ino;
11701 self->got_file_index = 1;
11702 }
11703 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11704#else /* POSIX */
11705#ifdef HAVE_LARGEFILE_SUPPORT
11706 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11707#else
11708 return PyLong_FromLong((long)self->d_ino);
11709#endif
11710#endif
11711}
11712
11713static PyObject *
11714DirEntry_repr(DirEntry *self)
11715{
11716 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11717}
11718
Brett Cannon96881cd2016-06-10 14:37:21 -070011719static PyObject *
11720DirEntry_fspath(DirEntry *self)
11721{
11722 Py_INCREF(self->path);
11723 return self->path;
11724}
11725
Victor Stinner6036e442015-03-08 01:58:04 +010011726static PyMemberDef DirEntry_members[] = {
11727 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11728 "the entry's base filename, relative to scandir() \"path\" argument"},
11729 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11730 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11731 {NULL}
11732};
11733
11734static PyMethodDef DirEntry_methods[] = {
11735 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11736 "return True if the entry is a directory; cached per entry"
11737 },
11738 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11739 "return True if the entry is a file; cached per entry"
11740 },
11741 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11742 "return True if the entry is a symbolic link; cached per entry"
11743 },
11744 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11745 "return stat_result object for the entry; cached per entry"
11746 },
11747 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11748 "return inode of the entry; cached per entry",
11749 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011750 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11751 "returns the path for the entry",
11752 },
Victor Stinner6036e442015-03-08 01:58:04 +010011753 {NULL}
11754};
11755
Benjamin Peterson5646de42015-04-12 17:56:34 -040011756static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011757 PyVarObject_HEAD_INIT(NULL, 0)
11758 MODNAME ".DirEntry", /* tp_name */
11759 sizeof(DirEntry), /* tp_basicsize */
11760 0, /* tp_itemsize */
11761 /* methods */
11762 (destructor)DirEntry_dealloc, /* tp_dealloc */
11763 0, /* tp_print */
11764 0, /* tp_getattr */
11765 0, /* tp_setattr */
11766 0, /* tp_compare */
11767 (reprfunc)DirEntry_repr, /* tp_repr */
11768 0, /* tp_as_number */
11769 0, /* tp_as_sequence */
11770 0, /* tp_as_mapping */
11771 0, /* tp_hash */
11772 0, /* tp_call */
11773 0, /* tp_str */
11774 0, /* tp_getattro */
11775 0, /* tp_setattro */
11776 0, /* tp_as_buffer */
11777 Py_TPFLAGS_DEFAULT, /* tp_flags */
11778 0, /* tp_doc */
11779 0, /* tp_traverse */
11780 0, /* tp_clear */
11781 0, /* tp_richcompare */
11782 0, /* tp_weaklistoffset */
11783 0, /* tp_iter */
11784 0, /* tp_iternext */
11785 DirEntry_methods, /* tp_methods */
11786 DirEntry_members, /* tp_members */
11787};
11788
11789#ifdef MS_WINDOWS
11790
11791static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011792join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011793{
11794 Py_ssize_t path_len;
11795 Py_ssize_t size;
11796 wchar_t *result;
11797 wchar_t ch;
11798
11799 if (!path_wide) { /* Default arg: "." */
11800 path_wide = L".";
11801 path_len = 1;
11802 }
11803 else {
11804 path_len = wcslen(path_wide);
11805 }
11806
11807 /* The +1's are for the path separator and the NUL */
11808 size = path_len + 1 + wcslen(filename) + 1;
11809 result = PyMem_New(wchar_t, size);
11810 if (!result) {
11811 PyErr_NoMemory();
11812 return NULL;
11813 }
11814 wcscpy(result, path_wide);
11815 if (path_len > 0) {
11816 ch = result[path_len - 1];
11817 if (ch != SEP && ch != ALTSEP && ch != L':')
11818 result[path_len++] = SEP;
11819 wcscpy(result + path_len, filename);
11820 }
11821 return result;
11822}
11823
11824static PyObject *
11825DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11826{
11827 DirEntry *entry;
11828 BY_HANDLE_FILE_INFORMATION file_info;
11829 ULONG reparse_tag;
11830 wchar_t *joined_path;
11831
11832 entry = PyObject_New(DirEntry, &DirEntryType);
11833 if (!entry)
11834 return NULL;
11835 entry->name = NULL;
11836 entry->path = NULL;
11837 entry->stat = NULL;
11838 entry->lstat = NULL;
11839 entry->got_file_index = 0;
11840
11841 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11842 if (!entry->name)
11843 goto error;
11844
11845 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11846 if (!joined_path)
11847 goto error;
11848
11849 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11850 PyMem_Free(joined_path);
11851 if (!entry->path)
11852 goto error;
11853
11854 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11855 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11856
11857 return (PyObject *)entry;
11858
11859error:
11860 Py_DECREF(entry);
11861 return NULL;
11862}
11863
11864#else /* POSIX */
11865
11866static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011867join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011868{
11869 Py_ssize_t path_len;
11870 Py_ssize_t size;
11871 char *result;
11872
11873 if (!path_narrow) { /* Default arg: "." */
11874 path_narrow = ".";
11875 path_len = 1;
11876 }
11877 else {
11878 path_len = strlen(path_narrow);
11879 }
11880
11881 if (filename_len == -1)
11882 filename_len = strlen(filename);
11883
11884 /* The +1's are for the path separator and the NUL */
11885 size = path_len + 1 + filename_len + 1;
11886 result = PyMem_New(char, size);
11887 if (!result) {
11888 PyErr_NoMemory();
11889 return NULL;
11890 }
11891 strcpy(result, path_narrow);
11892 if (path_len > 0 && result[path_len - 1] != '/')
11893 result[path_len++] = '/';
11894 strcpy(result + path_len, filename);
11895 return result;
11896}
11897
11898static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011899DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011900 ino_t d_ino
11901#ifdef HAVE_DIRENT_D_TYPE
11902 , unsigned char d_type
11903#endif
11904 )
Victor Stinner6036e442015-03-08 01:58:04 +010011905{
11906 DirEntry *entry;
11907 char *joined_path;
11908
11909 entry = PyObject_New(DirEntry, &DirEntryType);
11910 if (!entry)
11911 return NULL;
11912 entry->name = NULL;
11913 entry->path = NULL;
11914 entry->stat = NULL;
11915 entry->lstat = NULL;
11916
11917 joined_path = join_path_filename(path->narrow, name, name_len);
11918 if (!joined_path)
11919 goto error;
11920
11921 if (!path->narrow || !PyBytes_Check(path->object)) {
11922 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11923 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11924 }
11925 else {
11926 entry->name = PyBytes_FromStringAndSize(name, name_len);
11927 entry->path = PyBytes_FromString(joined_path);
11928 }
11929 PyMem_Free(joined_path);
11930 if (!entry->name || !entry->path)
11931 goto error;
11932
Victor Stinner35a97c02015-03-08 02:59:09 +010011933#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011934 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011935#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011936 entry->d_ino = d_ino;
11937
11938 return (PyObject *)entry;
11939
11940error:
11941 Py_XDECREF(entry);
11942 return NULL;
11943}
11944
11945#endif
11946
11947
11948typedef struct {
11949 PyObject_HEAD
11950 path_t path;
11951#ifdef MS_WINDOWS
11952 HANDLE handle;
11953 WIN32_FIND_DATAW file_data;
11954 int first_time;
11955#else /* POSIX */
11956 DIR *dirp;
11957#endif
11958} ScandirIterator;
11959
11960#ifdef MS_WINDOWS
11961
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011962static int
11963ScandirIterator_is_closed(ScandirIterator *iterator)
11964{
11965 return iterator->handle == INVALID_HANDLE_VALUE;
11966}
11967
Victor Stinner6036e442015-03-08 01:58:04 +010011968static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011969ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011970{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011971 HANDLE handle = iterator->handle;
11972
11973 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011974 return;
11975
Victor Stinner6036e442015-03-08 01:58:04 +010011976 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011977 Py_BEGIN_ALLOW_THREADS
11978 FindClose(handle);
11979 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011980}
11981
11982static PyObject *
11983ScandirIterator_iternext(ScandirIterator *iterator)
11984{
11985 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11986 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011987 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011988
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011989 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011990 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011991 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011992
11993 while (1) {
11994 if (!iterator->first_time) {
11995 Py_BEGIN_ALLOW_THREADS
11996 success = FindNextFileW(iterator->handle, file_data);
11997 Py_END_ALLOW_THREADS
11998 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011999 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012000 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012001 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012002 break;
12003 }
12004 }
12005 iterator->first_time = 0;
12006
12007 /* Skip over . and .. */
12008 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012009 wcscmp(file_data->cFileName, L"..") != 0) {
12010 entry = DirEntry_from_find_data(&iterator->path, file_data);
12011 if (!entry)
12012 break;
12013 return entry;
12014 }
Victor Stinner6036e442015-03-08 01:58:04 +010012015
12016 /* Loop till we get a non-dot directory or finish iterating */
12017 }
12018
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012019 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012020 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012021 return NULL;
12022}
12023
12024#else /* POSIX */
12025
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012026static int
12027ScandirIterator_is_closed(ScandirIterator *iterator)
12028{
12029 return !iterator->dirp;
12030}
12031
Victor Stinner6036e442015-03-08 01:58:04 +010012032static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012033ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012034{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012035 DIR *dirp = iterator->dirp;
12036
12037 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012038 return;
12039
Victor Stinner6036e442015-03-08 01:58:04 +010012040 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012041 Py_BEGIN_ALLOW_THREADS
12042 closedir(dirp);
12043 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012044 return;
12045}
12046
12047static PyObject *
12048ScandirIterator_iternext(ScandirIterator *iterator)
12049{
12050 struct dirent *direntp;
12051 Py_ssize_t name_len;
12052 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012053 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012054
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012055 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012056 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012057 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012058
12059 while (1) {
12060 errno = 0;
12061 Py_BEGIN_ALLOW_THREADS
12062 direntp = readdir(iterator->dirp);
12063 Py_END_ALLOW_THREADS
12064
12065 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012066 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012067 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012068 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012069 break;
12070 }
12071
12072 /* Skip over . and .. */
12073 name_len = NAMLEN(direntp);
12074 is_dot = direntp->d_name[0] == '.' &&
12075 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12076 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012077 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012078 name_len, direntp->d_ino
12079#ifdef HAVE_DIRENT_D_TYPE
12080 , direntp->d_type
12081#endif
12082 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012083 if (!entry)
12084 break;
12085 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012086 }
12087
12088 /* Loop till we get a non-dot directory or finish iterating */
12089 }
12090
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012091 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012092 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012093 return NULL;
12094}
12095
12096#endif
12097
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012098static PyObject *
12099ScandirIterator_close(ScandirIterator *self, PyObject *args)
12100{
12101 ScandirIterator_closedir(self);
12102 Py_RETURN_NONE;
12103}
12104
12105static PyObject *
12106ScandirIterator_enter(PyObject *self, PyObject *args)
12107{
12108 Py_INCREF(self);
12109 return self;
12110}
12111
12112static PyObject *
12113ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12114{
12115 ScandirIterator_closedir(self);
12116 Py_RETURN_NONE;
12117}
12118
Victor Stinner6036e442015-03-08 01:58:04 +010012119static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012120ScandirIterator_finalize(ScandirIterator *iterator)
12121{
12122 PyObject *error_type, *error_value, *error_traceback;
12123
12124 /* Save the current exception, if any. */
12125 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12126
12127 if (!ScandirIterator_is_closed(iterator)) {
12128 ScandirIterator_closedir(iterator);
12129
12130 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12131 "unclosed scandir iterator %R", iterator)) {
12132 /* Spurious errors can appear at shutdown */
12133 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12134 PyErr_WriteUnraisable((PyObject *) iterator);
12135 }
12136 }
12137 }
12138
12139 Py_CLEAR(iterator->path.object);
12140 path_cleanup(&iterator->path);
12141
12142 /* Restore the saved exception. */
12143 PyErr_Restore(error_type, error_value, error_traceback);
12144}
12145
12146static void
Victor Stinner6036e442015-03-08 01:58:04 +010012147ScandirIterator_dealloc(ScandirIterator *iterator)
12148{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012149 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12150 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012151
Victor Stinner6036e442015-03-08 01:58:04 +010012152 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12153}
12154
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012155static PyMethodDef ScandirIterator_methods[] = {
12156 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12157 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12158 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12159 {NULL}
12160};
12161
Benjamin Peterson5646de42015-04-12 17:56:34 -040012162static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012163 PyVarObject_HEAD_INIT(NULL, 0)
12164 MODNAME ".ScandirIterator", /* tp_name */
12165 sizeof(ScandirIterator), /* tp_basicsize */
12166 0, /* tp_itemsize */
12167 /* methods */
12168 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12169 0, /* tp_print */
12170 0, /* tp_getattr */
12171 0, /* tp_setattr */
12172 0, /* tp_compare */
12173 0, /* tp_repr */
12174 0, /* tp_as_number */
12175 0, /* tp_as_sequence */
12176 0, /* tp_as_mapping */
12177 0, /* tp_hash */
12178 0, /* tp_call */
12179 0, /* tp_str */
12180 0, /* tp_getattro */
12181 0, /* tp_setattro */
12182 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012183 Py_TPFLAGS_DEFAULT
12184 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012185 0, /* tp_doc */
12186 0, /* tp_traverse */
12187 0, /* tp_clear */
12188 0, /* tp_richcompare */
12189 0, /* tp_weaklistoffset */
12190 PyObject_SelfIter, /* tp_iter */
12191 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012192 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012193 0, /* tp_members */
12194 0, /* tp_getset */
12195 0, /* tp_base */
12196 0, /* tp_dict */
12197 0, /* tp_descr_get */
12198 0, /* tp_descr_set */
12199 0, /* tp_dictoffset */
12200 0, /* tp_init */
12201 0, /* tp_alloc */
12202 0, /* tp_new */
12203 0, /* tp_free */
12204 0, /* tp_is_gc */
12205 0, /* tp_bases */
12206 0, /* tp_mro */
12207 0, /* tp_cache */
12208 0, /* tp_subclasses */
12209 0, /* tp_weaklist */
12210 0, /* tp_del */
12211 0, /* tp_version_tag */
12212 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012213};
12214
12215static PyObject *
12216posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12217{
12218 ScandirIterator *iterator;
12219 static char *keywords[] = {"path", NULL};
12220#ifdef MS_WINDOWS
12221 wchar_t *path_strW;
12222#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012223 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010012224#endif
12225
12226 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12227 if (!iterator)
12228 return NULL;
12229 memset(&iterator->path, 0, sizeof(path_t));
12230 iterator->path.function_name = "scandir";
12231 iterator->path.nullable = 1;
12232
12233#ifdef MS_WINDOWS
12234 iterator->handle = INVALID_HANDLE_VALUE;
12235#else
12236 iterator->dirp = NULL;
12237#endif
12238
12239 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12240 path_converter, &iterator->path))
12241 goto error;
12242
12243 /* path_converter doesn't keep path.object around, so do it
12244 manually for the lifetime of the iterator here (the refcount
12245 is decremented in ScandirIterator_dealloc)
12246 */
12247 Py_XINCREF(iterator->path.object);
12248
12249#ifdef MS_WINDOWS
12250 if (iterator->path.narrow) {
12251 PyErr_SetString(PyExc_TypeError,
12252 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12253 goto error;
12254 }
12255 iterator->first_time = 1;
12256
12257 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12258 if (!path_strW)
12259 goto error;
12260
12261 Py_BEGIN_ALLOW_THREADS
12262 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12263 Py_END_ALLOW_THREADS
12264
12265 PyMem_Free(path_strW);
12266
12267 if (iterator->handle == INVALID_HANDLE_VALUE) {
12268 path_error(&iterator->path);
12269 goto error;
12270 }
12271#else /* POSIX */
12272 if (iterator->path.narrow)
12273 path = iterator->path.narrow;
12274 else
12275 path = ".";
12276
12277 errno = 0;
12278 Py_BEGIN_ALLOW_THREADS
12279 iterator->dirp = opendir(path);
12280 Py_END_ALLOW_THREADS
12281
12282 if (!iterator->dirp) {
12283 path_error(&iterator->path);
12284 goto error;
12285 }
12286#endif
12287
12288 return (PyObject *)iterator;
12289
12290error:
12291 Py_DECREF(iterator);
12292 return NULL;
12293}
12294
Ethan Furman410ef8e2016-06-04 12:06:26 -070012295/*
12296 Return the file system path representation of the object.
12297
12298 If the object is str or bytes, then allow it to pass through with
12299 an incremented refcount. If the object defines __fspath__(), then
12300 return the result of that method. All other types raise a TypeError.
12301*/
12302PyObject *
12303PyOS_FSPath(PyObject *path)
12304{
12305 _Py_IDENTIFIER(__fspath__);
12306 PyObject *func = NULL;
12307 PyObject *path_repr = NULL;
12308
12309 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12310 Py_INCREF(path);
12311 return path;
12312 }
12313
12314 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12315 if (NULL == func) {
12316 return PyErr_Format(PyExc_TypeError,
12317 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012318 "not %.200s",
12319 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012320 }
12321
12322 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12323 Py_DECREF(func);
Brett Cannon044283a2016-07-15 10:41:49 -070012324 if (NULL == path_repr) {
12325 return NULL;
12326 }
12327
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012328 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12329 PyErr_Format(PyExc_TypeError,
12330 "expected %.200s.__fspath__() to return str or bytes, "
12331 "not %.200s", Py_TYPE(path)->tp_name,
12332 Py_TYPE(path_repr)->tp_name);
12333 Py_DECREF(path_repr);
12334 return NULL;
12335 }
12336
Ethan Furman410ef8e2016-06-04 12:06:26 -070012337 return path_repr;
12338}
12339
12340/*[clinic input]
12341os.fspath
12342
12343 path: object
12344
12345Return the file system path representation of the object.
12346
Brett Cannonb4f43e92016-06-09 14:32:08 -070012347If the object is str or bytes, then allow it to pass through as-is. If the
12348object defines __fspath__(), then return the result of that method. All other
12349types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012350[clinic start generated code]*/
12351
12352static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012353os_fspath_impl(PyObject *module, PyObject *path)
12354/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012355{
12356 return PyOS_FSPath(path);
12357}
Victor Stinner6036e442015-03-08 01:58:04 +010012358
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012359#include "clinic/posixmodule.c.h"
12360
Larry Hastings7726ac92014-01-31 22:03:12 -080012361/*[clinic input]
12362dump buffer
12363[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012364/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012365
Larry Hastings31826802013-10-19 00:09:25 -070012366
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012367static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012368
12369 OS_STAT_METHODDEF
12370 OS_ACCESS_METHODDEF
12371 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012372 OS_CHDIR_METHODDEF
12373 OS_CHFLAGS_METHODDEF
12374 OS_CHMOD_METHODDEF
12375 OS_FCHMOD_METHODDEF
12376 OS_LCHMOD_METHODDEF
12377 OS_CHOWN_METHODDEF
12378 OS_FCHOWN_METHODDEF
12379 OS_LCHOWN_METHODDEF
12380 OS_LCHFLAGS_METHODDEF
12381 OS_CHROOT_METHODDEF
12382 OS_CTERMID_METHODDEF
12383 OS_GETCWD_METHODDEF
12384 OS_GETCWDB_METHODDEF
12385 OS_LINK_METHODDEF
12386 OS_LISTDIR_METHODDEF
12387 OS_LSTAT_METHODDEF
12388 OS_MKDIR_METHODDEF
12389 OS_NICE_METHODDEF
12390 OS_GETPRIORITY_METHODDEF
12391 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012392#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012393 {"readlink", (PyCFunction)posix_readlink,
12394 METH_VARARGS | METH_KEYWORDS,
12395 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012396#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012397#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012398 {"readlink", (PyCFunction)win_readlink,
12399 METH_VARARGS | METH_KEYWORDS,
12400 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012401#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012402 OS_RENAME_METHODDEF
12403 OS_REPLACE_METHODDEF
12404 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012405 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012406 OS_SYMLINK_METHODDEF
12407 OS_SYSTEM_METHODDEF
12408 OS_UMASK_METHODDEF
12409 OS_UNAME_METHODDEF
12410 OS_UNLINK_METHODDEF
12411 OS_REMOVE_METHODDEF
12412 OS_UTIME_METHODDEF
12413 OS_TIMES_METHODDEF
12414 OS__EXIT_METHODDEF
12415 OS_EXECV_METHODDEF
12416 OS_EXECVE_METHODDEF
12417 OS_SPAWNV_METHODDEF
12418 OS_SPAWNVE_METHODDEF
12419 OS_FORK1_METHODDEF
12420 OS_FORK_METHODDEF
12421 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12422 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12423 OS_SCHED_GETPARAM_METHODDEF
12424 OS_SCHED_GETSCHEDULER_METHODDEF
12425 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12426 OS_SCHED_SETPARAM_METHODDEF
12427 OS_SCHED_SETSCHEDULER_METHODDEF
12428 OS_SCHED_YIELD_METHODDEF
12429 OS_SCHED_SETAFFINITY_METHODDEF
12430 OS_SCHED_GETAFFINITY_METHODDEF
12431 OS_OPENPTY_METHODDEF
12432 OS_FORKPTY_METHODDEF
12433 OS_GETEGID_METHODDEF
12434 OS_GETEUID_METHODDEF
12435 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012436#ifdef HAVE_GETGROUPLIST
12437 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12438#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012439 OS_GETGROUPS_METHODDEF
12440 OS_GETPID_METHODDEF
12441 OS_GETPGRP_METHODDEF
12442 OS_GETPPID_METHODDEF
12443 OS_GETUID_METHODDEF
12444 OS_GETLOGIN_METHODDEF
12445 OS_KILL_METHODDEF
12446 OS_KILLPG_METHODDEF
12447 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012448#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012449 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012450#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012451 OS_SETUID_METHODDEF
12452 OS_SETEUID_METHODDEF
12453 OS_SETREUID_METHODDEF
12454 OS_SETGID_METHODDEF
12455 OS_SETEGID_METHODDEF
12456 OS_SETREGID_METHODDEF
12457 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012458#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012459 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012460#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012461 OS_GETPGID_METHODDEF
12462 OS_SETPGRP_METHODDEF
12463 OS_WAIT_METHODDEF
12464 OS_WAIT3_METHODDEF
12465 OS_WAIT4_METHODDEF
12466 OS_WAITID_METHODDEF
12467 OS_WAITPID_METHODDEF
12468 OS_GETSID_METHODDEF
12469 OS_SETSID_METHODDEF
12470 OS_SETPGID_METHODDEF
12471 OS_TCGETPGRP_METHODDEF
12472 OS_TCSETPGRP_METHODDEF
12473 OS_OPEN_METHODDEF
12474 OS_CLOSE_METHODDEF
12475 OS_CLOSERANGE_METHODDEF
12476 OS_DEVICE_ENCODING_METHODDEF
12477 OS_DUP_METHODDEF
12478 OS_DUP2_METHODDEF
12479 OS_LOCKF_METHODDEF
12480 OS_LSEEK_METHODDEF
12481 OS_READ_METHODDEF
12482 OS_READV_METHODDEF
12483 OS_PREAD_METHODDEF
12484 OS_WRITE_METHODDEF
12485 OS_WRITEV_METHODDEF
12486 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012487#ifdef HAVE_SENDFILE
12488 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12489 posix_sendfile__doc__},
12490#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012491 OS_FSTAT_METHODDEF
12492 OS_ISATTY_METHODDEF
12493 OS_PIPE_METHODDEF
12494 OS_PIPE2_METHODDEF
12495 OS_MKFIFO_METHODDEF
12496 OS_MKNOD_METHODDEF
12497 OS_MAJOR_METHODDEF
12498 OS_MINOR_METHODDEF
12499 OS_MAKEDEV_METHODDEF
12500 OS_FTRUNCATE_METHODDEF
12501 OS_TRUNCATE_METHODDEF
12502 OS_POSIX_FALLOCATE_METHODDEF
12503 OS_POSIX_FADVISE_METHODDEF
12504 OS_PUTENV_METHODDEF
12505 OS_UNSETENV_METHODDEF
12506 OS_STRERROR_METHODDEF
12507 OS_FCHDIR_METHODDEF
12508 OS_FSYNC_METHODDEF
12509 OS_SYNC_METHODDEF
12510 OS_FDATASYNC_METHODDEF
12511 OS_WCOREDUMP_METHODDEF
12512 OS_WIFCONTINUED_METHODDEF
12513 OS_WIFSTOPPED_METHODDEF
12514 OS_WIFSIGNALED_METHODDEF
12515 OS_WIFEXITED_METHODDEF
12516 OS_WEXITSTATUS_METHODDEF
12517 OS_WTERMSIG_METHODDEF
12518 OS_WSTOPSIG_METHODDEF
12519 OS_FSTATVFS_METHODDEF
12520 OS_STATVFS_METHODDEF
12521 OS_CONFSTR_METHODDEF
12522 OS_SYSCONF_METHODDEF
12523 OS_FPATHCONF_METHODDEF
12524 OS_PATHCONF_METHODDEF
12525 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012526 OS__GETFULLPATHNAME_METHODDEF
12527 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012528 OS__GETDISKUSAGE_METHODDEF
12529 OS__GETFINALPATHNAME_METHODDEF
12530 OS__GETVOLUMEPATHNAME_METHODDEF
12531 OS_GETLOADAVG_METHODDEF
12532 OS_URANDOM_METHODDEF
12533 OS_SETRESUID_METHODDEF
12534 OS_SETRESGID_METHODDEF
12535 OS_GETRESUID_METHODDEF
12536 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012537
Larry Hastings2f936352014-08-05 14:04:04 +100012538 OS_GETXATTR_METHODDEF
12539 OS_SETXATTR_METHODDEF
12540 OS_REMOVEXATTR_METHODDEF
12541 OS_LISTXATTR_METHODDEF
12542
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012543#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12544 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12545#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012546 OS_CPU_COUNT_METHODDEF
12547 OS_GET_INHERITABLE_METHODDEF
12548 OS_SET_INHERITABLE_METHODDEF
12549 OS_GET_HANDLE_INHERITABLE_METHODDEF
12550 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012551#ifndef MS_WINDOWS
12552 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12553 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12554#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012555 {"scandir", (PyCFunction)posix_scandir,
12556 METH_VARARGS | METH_KEYWORDS,
12557 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012558 OS_FSPATH_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012559 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012560};
12561
12562
Brian Curtin52173d42010-12-02 18:29:18 +000012563#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012564static int
Brian Curtin52173d42010-12-02 18:29:18 +000012565enable_symlink()
12566{
12567 HANDLE tok;
12568 TOKEN_PRIVILEGES tok_priv;
12569 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012570
12571 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012572 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012573
12574 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012575 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012576
12577 tok_priv.PrivilegeCount = 1;
12578 tok_priv.Privileges[0].Luid = luid;
12579 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12580
12581 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12582 sizeof(TOKEN_PRIVILEGES),
12583 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012584 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012585
Brian Curtin3b4499c2010-12-28 14:31:47 +000012586 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12587 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012588}
12589#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12590
Barry Warsaw4a342091996-12-19 23:50:02 +000012591static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012592all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012593{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012594#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012595 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012596#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012597#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012599#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012600#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012602#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012603#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012605#endif
Fred Drakec9680921999-12-13 16:37:25 +000012606#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012608#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012609#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012611#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012612#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012614#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012615#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012617#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012618#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012620#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012621#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012623#endif
12624#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012626#endif
12627#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012629#endif
12630#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012632#endif
12633#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012635#endif
12636#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012637 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012638#endif
12639#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012641#endif
12642#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012644#endif
12645#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012647#endif
12648#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012650#endif
12651#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012653#endif
12654#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012656#endif
12657#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012659#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012660#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012662#endif
12663#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012665#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012666#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012668#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012669#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012671#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012672#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012673#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012675#endif
12676#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012678#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012679#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012680#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012682#endif
12683#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012685#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012686#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012688#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012689#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012691#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012692#ifdef O_TMPFILE
12693 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12694#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012695#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012697#endif
12698#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012700#endif
12701#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012702 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012703#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012704#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012706#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012707#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012709#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012710
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012711
Jesus Cea94363612012-06-22 18:32:07 +020012712#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012714#endif
12715#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012717#endif
12718
Tim Peters5aa91602002-01-30 05:46:57 +000012719/* MS Windows */
12720#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012721 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012723#endif
12724#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012725 /* Optimize for short life (keep in memory). */
12726 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012727 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012728#endif
12729#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012730 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012732#endif
12733#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012734 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012736#endif
12737#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012738 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012739 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012740#endif
12741
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012742/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012743#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012744 /* Send a SIGIO signal whenever input or output
12745 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012747#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012748#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012749 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012751#endif
12752#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012753 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012755#endif
12756#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012757 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012759#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012760#ifdef O_NOLINKS
12761 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012763#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012764#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012765 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012767#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012768
Victor Stinner8c62be82010-05-06 00:08:46 +000012769 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012770#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012772#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012773#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012775#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012776#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012778#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012779#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012781#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012782#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012783 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012784#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012785#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012787#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012788#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012790#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012791#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012792 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012793#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012794#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012796#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012797#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012798 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012799#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012800#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012801 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012802#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012803#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012805#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012806#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012807 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012808#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012809#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012810 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012811#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012812#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012813 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012814#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012815#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012816 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012817#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012818#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012819 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012820#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012821
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012822 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012823#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012824 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012825#endif /* ST_RDONLY */
12826#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012827 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012828#endif /* ST_NOSUID */
12829
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012830 /* GNU extensions */
12831#ifdef ST_NODEV
12832 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12833#endif /* ST_NODEV */
12834#ifdef ST_NOEXEC
12835 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12836#endif /* ST_NOEXEC */
12837#ifdef ST_SYNCHRONOUS
12838 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12839#endif /* ST_SYNCHRONOUS */
12840#ifdef ST_MANDLOCK
12841 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12842#endif /* ST_MANDLOCK */
12843#ifdef ST_WRITE
12844 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12845#endif /* ST_WRITE */
12846#ifdef ST_APPEND
12847 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12848#endif /* ST_APPEND */
12849#ifdef ST_NOATIME
12850 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12851#endif /* ST_NOATIME */
12852#ifdef ST_NODIRATIME
12853 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12854#endif /* ST_NODIRATIME */
12855#ifdef ST_RELATIME
12856 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12857#endif /* ST_RELATIME */
12858
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012859 /* FreeBSD sendfile() constants */
12860#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012861 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012862#endif
12863#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012864 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012865#endif
12866#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012867 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012868#endif
12869
Ross Lagerwall7807c352011-03-17 20:20:30 +020012870 /* constants for posix_fadvise */
12871#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012873#endif
12874#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012876#endif
12877#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012879#endif
12880#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012882#endif
12883#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012884 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012885#endif
12886#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012887 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012888#endif
12889
12890 /* constants for waitid */
12891#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012892 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12893 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12894 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012895#endif
12896#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012897 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012898#endif
12899#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012900 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012901#endif
12902#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012903 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012904#endif
12905#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012906 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012907#endif
12908#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012909 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012910#endif
12911#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012912 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012913#endif
12914#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012915 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012916#endif
12917
12918 /* constants for lockf */
12919#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012921#endif
12922#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012923 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012924#endif
12925#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012926 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012927#endif
12928#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012929 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012930#endif
12931
Guido van Rossum246bc171999-02-01 23:54:31 +000012932#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012933 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12934 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12935 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12936 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12937 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012938#endif
12939
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012940#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012941#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012942 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012943#endif
12944#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012945 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012946#endif
12947#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012948 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012949#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012950#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012952#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012953#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012954 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012955#endif
12956#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012958#endif
12959#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012961#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012962#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012963 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012964#endif
12965#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012966 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012967#endif
12968#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012969 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012970#endif
12971#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012972 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012973#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012974#endif
12975
Benjamin Peterson9428d532011-09-14 11:45:52 -040012976#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012977 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12978 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12979 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012980#endif
12981
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012982#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012983 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012984#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012985#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012986 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012987#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012988#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012989 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012990#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012991#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012992 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012993#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012994#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012995 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012996#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012997#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012998 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012999#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030013000#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020013001 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020013002#endif
13003
Victor Stinner8c62be82010-05-06 00:08:46 +000013004 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000013005}
13006
13007
Martin v. Löwis1a214512008-06-11 05:26:20 +000013008static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 PyModuleDef_HEAD_INIT,
13010 MODNAME,
13011 posix__doc__,
13012 -1,
13013 posix_methods,
13014 NULL,
13015 NULL,
13016 NULL,
13017 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013018};
13019
13020
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013021static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013022
13023#ifdef HAVE_FACCESSAT
13024 "HAVE_FACCESSAT",
13025#endif
13026
13027#ifdef HAVE_FCHDIR
13028 "HAVE_FCHDIR",
13029#endif
13030
13031#ifdef HAVE_FCHMOD
13032 "HAVE_FCHMOD",
13033#endif
13034
13035#ifdef HAVE_FCHMODAT
13036 "HAVE_FCHMODAT",
13037#endif
13038
13039#ifdef HAVE_FCHOWN
13040 "HAVE_FCHOWN",
13041#endif
13042
Larry Hastings00964ed2013-08-12 13:49:30 -040013043#ifdef HAVE_FCHOWNAT
13044 "HAVE_FCHOWNAT",
13045#endif
13046
Larry Hastings9cf065c2012-06-22 16:30:09 -070013047#ifdef HAVE_FEXECVE
13048 "HAVE_FEXECVE",
13049#endif
13050
13051#ifdef HAVE_FDOPENDIR
13052 "HAVE_FDOPENDIR",
13053#endif
13054
Georg Brandl306336b2012-06-24 12:55:33 +020013055#ifdef HAVE_FPATHCONF
13056 "HAVE_FPATHCONF",
13057#endif
13058
Larry Hastings9cf065c2012-06-22 16:30:09 -070013059#ifdef HAVE_FSTATAT
13060 "HAVE_FSTATAT",
13061#endif
13062
13063#ifdef HAVE_FSTATVFS
13064 "HAVE_FSTATVFS",
13065#endif
13066
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013067#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013068 "HAVE_FTRUNCATE",
13069#endif
13070
Larry Hastings9cf065c2012-06-22 16:30:09 -070013071#ifdef HAVE_FUTIMENS
13072 "HAVE_FUTIMENS",
13073#endif
13074
13075#ifdef HAVE_FUTIMES
13076 "HAVE_FUTIMES",
13077#endif
13078
13079#ifdef HAVE_FUTIMESAT
13080 "HAVE_FUTIMESAT",
13081#endif
13082
13083#ifdef HAVE_LINKAT
13084 "HAVE_LINKAT",
13085#endif
13086
13087#ifdef HAVE_LCHFLAGS
13088 "HAVE_LCHFLAGS",
13089#endif
13090
13091#ifdef HAVE_LCHMOD
13092 "HAVE_LCHMOD",
13093#endif
13094
13095#ifdef HAVE_LCHOWN
13096 "HAVE_LCHOWN",
13097#endif
13098
13099#ifdef HAVE_LSTAT
13100 "HAVE_LSTAT",
13101#endif
13102
13103#ifdef HAVE_LUTIMES
13104 "HAVE_LUTIMES",
13105#endif
13106
13107#ifdef HAVE_MKDIRAT
13108 "HAVE_MKDIRAT",
13109#endif
13110
13111#ifdef HAVE_MKFIFOAT
13112 "HAVE_MKFIFOAT",
13113#endif
13114
13115#ifdef HAVE_MKNODAT
13116 "HAVE_MKNODAT",
13117#endif
13118
13119#ifdef HAVE_OPENAT
13120 "HAVE_OPENAT",
13121#endif
13122
13123#ifdef HAVE_READLINKAT
13124 "HAVE_READLINKAT",
13125#endif
13126
13127#ifdef HAVE_RENAMEAT
13128 "HAVE_RENAMEAT",
13129#endif
13130
13131#ifdef HAVE_SYMLINKAT
13132 "HAVE_SYMLINKAT",
13133#endif
13134
13135#ifdef HAVE_UNLINKAT
13136 "HAVE_UNLINKAT",
13137#endif
13138
13139#ifdef HAVE_UTIMENSAT
13140 "HAVE_UTIMENSAT",
13141#endif
13142
13143#ifdef MS_WINDOWS
13144 "MS_WINDOWS",
13145#endif
13146
13147 NULL
13148};
13149
13150
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013151PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013152INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013153{
Victor Stinner8c62be82010-05-06 00:08:46 +000013154 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013155 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013156 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013157
Brian Curtin52173d42010-12-02 18:29:18 +000013158#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013159 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013160#endif
13161
Victor Stinner8c62be82010-05-06 00:08:46 +000013162 m = PyModule_Create(&posixmodule);
13163 if (m == NULL)
13164 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013165
Victor Stinner8c62be82010-05-06 00:08:46 +000013166 /* Initialize environ dictionary */
13167 v = convertenviron();
13168 Py_XINCREF(v);
13169 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13170 return NULL;
13171 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013172
Victor Stinner8c62be82010-05-06 00:08:46 +000013173 if (all_ins(m))
13174 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013175
Victor Stinner8c62be82010-05-06 00:08:46 +000013176 if (setup_confname_tables(m))
13177 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013178
Victor Stinner8c62be82010-05-06 00:08:46 +000013179 Py_INCREF(PyExc_OSError);
13180 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013181
Guido van Rossumb3d39562000-01-31 18:41:26 +000013182#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013183 if (posix_putenv_garbage == NULL)
13184 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013185#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013186
Victor Stinner8c62be82010-05-06 00:08:46 +000013187 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013188#if defined(HAVE_WAITID) && !defined(__APPLE__)
13189 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013190 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13191 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013192#endif
13193
Christian Heimes25827622013-10-12 01:27:08 +020013194 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013195 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13196 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13197 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013198 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13199 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013200 structseq_new = StatResultType.tp_new;
13201 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013202
Christian Heimes25827622013-10-12 01:27:08 +020013203 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013204 if (PyStructSequence_InitType2(&StatVFSResultType,
13205 &statvfs_result_desc) < 0)
13206 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013207#ifdef NEED_TICKS_PER_SECOND
13208# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013209 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013210# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013211 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013212# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013213 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013214# endif
13215#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013216
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013217#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013218 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013219 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13220 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013221 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013222#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013223
13224 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013225 if (PyStructSequence_InitType2(&TerminalSizeType,
13226 &TerminalSize_desc) < 0)
13227 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013228
13229 /* initialize scandir types */
13230 if (PyType_Ready(&ScandirIteratorType) < 0)
13231 return NULL;
13232 if (PyType_Ready(&DirEntryType) < 0)
13233 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013234 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013235#if defined(HAVE_WAITID) && !defined(__APPLE__)
13236 Py_INCREF((PyObject*) &WaitidResultType);
13237 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13238#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013239 Py_INCREF((PyObject*) &StatResultType);
13240 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13241 Py_INCREF((PyObject*) &StatVFSResultType);
13242 PyModule_AddObject(m, "statvfs_result",
13243 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013244
13245#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013246 Py_INCREF(&SchedParamType);
13247 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013248#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013249
Larry Hastings605a62d2012-06-24 04:33:36 -070013250 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013251 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13252 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013253 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13254
13255 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013256 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13257 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013258 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13259
Thomas Wouters477c8d52006-05-27 19:21:47 +000013260#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013261 /*
13262 * Step 2 of weak-linking support on Mac OS X.
13263 *
13264 * The code below removes functions that are not available on the
13265 * currently active platform.
13266 *
13267 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013268 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013269 * OSX 10.4.
13270 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013271#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013272 if (fstatvfs == NULL) {
13273 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13274 return NULL;
13275 }
13276 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013277#endif /* HAVE_FSTATVFS */
13278
13279#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013280 if (statvfs == NULL) {
13281 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13282 return NULL;
13283 }
13284 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013285#endif /* HAVE_STATVFS */
13286
13287# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013288 if (lchown == NULL) {
13289 if (PyObject_DelAttrString(m, "lchown") == -1) {
13290 return NULL;
13291 }
13292 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013293#endif /* HAVE_LCHOWN */
13294
13295
13296#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013297
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013298 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013299 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13300
Larry Hastings6fe20b32012-04-19 15:07:49 -070013301 billion = PyLong_FromLong(1000000000);
13302 if (!billion)
13303 return NULL;
13304
Larry Hastings9cf065c2012-06-22 16:30:09 -070013305 /* suppress "function not used" warnings */
13306 {
13307 int ignored;
13308 fd_specified("", -1);
13309 follow_symlinks_specified("", 1);
13310 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13311 dir_fd_converter(Py_None, &ignored);
13312 dir_fd_unavailable(Py_None, &ignored);
13313 }
13314
13315 /*
13316 * provide list of locally available functions
13317 * so os.py can populate support_* lists
13318 */
13319 list = PyList_New(0);
13320 if (!list)
13321 return NULL;
13322 for (trace = have_functions; *trace; trace++) {
13323 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13324 if (!unicode)
13325 return NULL;
13326 if (PyList_Append(list, unicode))
13327 return NULL;
13328 Py_DECREF(unicode);
13329 }
13330 PyModule_AddObject(m, "_have_functions", list);
Brett Cannona32c4d02016-06-24 14:14:44 -070013331 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013332
13333 initialized = 1;
13334
Victor Stinner8c62be82010-05-06 00:08:46 +000013335 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013336}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013337
13338#ifdef __cplusplus
13339}
13340#endif