blob: 4c0f26e89c1e6af8af977b909cdb034dbb8a43d7 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Stefan Krahfb7c8ae2016-04-26 17:04:18 +020035/* On android API level 21, 'AT_EACCESS' is not declared although
36 * HAVE_FACCESSAT is defined. */
37#ifdef __ANDROID__
38#undef HAVE_FACCESSAT
39#endif
40
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000041#include <stdio.h> /* needed for ctermid() */
42
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000043#ifdef __cplusplus
44extern "C" {
45#endif
46
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000047PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000048"This module provides access to operating system functionality that is\n\
49standardized by the C Standard and the POSIX standard (a thinly\n\
50disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000051corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000052
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000053
Ross Lagerwall4d076da2011-03-18 06:56:53 +020054#ifdef HAVE_SYS_UIO_H
55#include <sys/uio.h>
56#endif
57
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000059#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000060#endif /* HAVE_SYS_TYPES_H */
61
62#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000063#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000065
Guido van Rossum36bc6801995-06-14 22:54:23 +000066#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000067#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000068#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Thomas Wouters0e3f5912006-08-11 14:57:12 +000070#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000071#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000073
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#ifdef HAVE_FCNTL_H
75#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000076#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000077
Guido van Rossuma6535fd2001-10-18 19:44:10 +000078#ifdef HAVE_GRP_H
79#include <grp.h>
80#endif
81
Barry Warsaw5676bd12003-01-07 20:57:09 +000082#ifdef HAVE_SYSEXITS_H
83#include <sysexits.h>
84#endif /* HAVE_SYSEXITS_H */
85
Anthony Baxter8a560de2004-10-13 15:30:56 +000086#ifdef HAVE_SYS_LOADAVG_H
87#include <sys/loadavg.h>
88#endif
89
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000090#ifdef HAVE_LANGINFO_H
91#include <langinfo.h>
92#endif
93
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000094#ifdef HAVE_SYS_SENDFILE_H
95#include <sys/sendfile.h>
96#endif
97
Benjamin Peterson94b580d2011-08-02 17:30:04 -050098#ifdef HAVE_SCHED_H
99#include <sched.h>
100#endif
101
Benjamin Peterson2dbda072012-03-16 10:12:55 -0500102#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -0500103#undef HAVE_SCHED_SETAFFINITY
104#endif
105
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200106#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400107#define USE_XATTRS
108#endif
109
110#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400111#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400112#endif
113
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000114#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
115#ifdef HAVE_SYS_SOCKET_H
116#include <sys/socket.h>
117#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000118#endif
119
Victor Stinner8b905bd2011-10-25 13:34:04 +0200120#ifdef HAVE_DLFCN_H
121#include <dlfcn.h>
122#endif
123
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200124#ifdef __hpux
125#include <sys/mpctl.h>
126#endif
127
128#if defined(__DragonFly__) || \
129 defined(__OpenBSD__) || \
130 defined(__FreeBSD__) || \
131 defined(__NetBSD__) || \
132 defined(__APPLE__)
133#include <sys/sysctl.h>
134#endif
135
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100136#if defined(MS_WINDOWS)
137# define TERMSIZE_USE_CONIO
138#elif defined(HAVE_SYS_IOCTL_H)
139# include <sys/ioctl.h>
140# if defined(HAVE_TERMIOS_H)
141# include <termios.h>
142# endif
143# if defined(TIOCGWINSZ)
144# define TERMSIZE_USE_IOCTL
145# endif
146#endif /* MS_WINDOWS */
147
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000148/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000149/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#include <process.h>
154#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000156#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000157#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000158#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000159#define HAVE_EXECV 1
160#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#define HAVE_SYSTEM 1
162#define HAVE_CWAIT 1
163#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000164#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000165#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166/* Unix functions that the configure script doesn't check for */
167#define HAVE_EXECV 1
168#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000169#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000170#define HAVE_FORK1 1
171#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000172#define HAVE_GETEGID 1
173#define HAVE_GETEUID 1
174#define HAVE_GETGID 1
175#define HAVE_GETPPID 1
176#define HAVE_GETUID 1
177#define HAVE_KILL 1
178#define HAVE_OPENDIR 1
179#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000180#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000181#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000182#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000183#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000184#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000185
Victor Stinnera2f7c002012-02-08 03:36:25 +0100186
Larry Hastings61272b72014-01-07 12:41:53 -0800187/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000188# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800189module os
Larry Hastings61272b72014-01-07 12:41:53 -0800190[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000191/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100192
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000193#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000194
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000195#if defined(__sgi)&&_COMPILER_VERSION>=700
196/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
197 (default) */
198extern char *ctermid_r(char *);
199#endif
200
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000201#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000203extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000205#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000207#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000208extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000209#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000210#endif
211#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chdir(char *);
213extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000214#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000215extern int chdir(const char *);
216extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000217#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000218extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000219/*#ifdef HAVE_FCHMOD
220extern int fchmod(int, mode_t);
221#endif*/
222/*#ifdef HAVE_LCHMOD
223extern int lchmod(const char *, mode_t);
224#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int chown(const char *, uid_t, gid_t);
226extern char *getcwd(char *, int);
227extern char *strerror(int);
228extern int link(const char *, const char *);
229extern int rename(const char *, const char *);
230extern int stat(const char *, struct stat *);
231extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000233extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000234#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000235#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000236extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000237#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000238#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000239
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000240#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000241
Guido van Rossumb6775db1994-08-01 11:34:53 +0000242#ifdef HAVE_UTIME_H
243#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000244#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000246#ifdef HAVE_SYS_UTIME_H
247#include <sys/utime.h>
248#define HAVE_UTIME_H /* pretend we do for the rest of this file */
249#endif /* HAVE_SYS_UTIME_H */
250
Guido van Rossumb6775db1994-08-01 11:34:53 +0000251#ifdef HAVE_SYS_TIMES_H
252#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
255#ifdef HAVE_SYS_PARAM_H
256#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000257#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258
259#ifdef HAVE_SYS_UTSNAME_H
260#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000261#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000262
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000263#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000264#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000265#define NAMLEN(dirent) strlen((dirent)->d_name)
266#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000267#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000268#include <direct.h>
269#define NAMLEN(dirent) strlen((dirent)->d_name)
270#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000271#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000272#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000273#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000279#endif
280#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000282#endif
283#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000285#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
289#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000290#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000291#endif
292#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000293#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000294#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
298#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000299#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000300#endif
301#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000302#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000303#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100304#ifndef IO_REPARSE_TAG_MOUNT_POINT
305#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
306#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000307#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000308#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000309#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000310#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000311#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000312#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
313#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000314static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000315#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000316#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000317
Tim Petersbc2e10e2002-03-03 23:17:02 +0000318#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000319#if defined(PATH_MAX) && PATH_MAX > 1024
320#define MAXPATHLEN PATH_MAX
321#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000322#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000323#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000324#endif /* MAXPATHLEN */
325
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000326#ifdef UNION_WAIT
327/* Emulate some macros on systems that have a union instead of macros */
328
329#ifndef WIFEXITED
330#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
331#endif
332
333#ifndef WEXITSTATUS
334#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
335#endif
336
337#ifndef WTERMSIG
338#define WTERMSIG(u_wait) ((u_wait).w_termsig)
339#endif
340
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000341#define WAIT_TYPE union wait
342#define WAIT_STATUS_INT(s) (s.w_status)
343
344#else /* !UNION_WAIT */
345#define WAIT_TYPE int
346#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000347#endif /* UNION_WAIT */
348
Greg Wardb48bc172000-03-01 21:51:56 +0000349/* Don't use the "_r" form if we don't need it (also, won't have a
350 prototype for it, at least on Solaris -- maybe others as well?). */
351#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
352#define USE_CTERMID_R
353#endif
354
Fred Drake699f3522000-06-29 21:12:41 +0000355/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000356#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000357#undef FSTAT
358#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200359#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000360# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700361# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200362# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800363# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000364#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000365# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700366# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000367# define FSTAT fstat
368# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000369#endif
370
Tim Peters11b23062003-04-23 02:39:17 +0000371#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#include <sys/mkdev.h>
373#else
374#if defined(MAJOR_IN_SYSMACROS)
375#include <sys/sysmacros.h>
376#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000377#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
378#include <sys/mkdev.h>
379#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000380#endif
Fred Drake699f3522000-06-29 21:12:41 +0000381
Victor Stinner6edddfa2013-11-24 19:22:57 +0100382#define DWORD_MAX 4294967295U
383
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200384#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100385#define INITFUNC PyInit_nt
386#define MODNAME "nt"
387#else
388#define INITFUNC PyInit_posix
389#define MODNAME "posix"
390#endif
391
392#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200393/* defined in fileutils.c */
394PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
395PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
396 ULONG, struct _Py_stat_struct *);
397#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700398
399#ifdef MS_WINDOWS
400static int
401win32_warn_bytes_api()
402{
403 return PyErr_WarnEx(PyExc_DeprecationWarning,
404 "The Windows bytes API has been deprecated, "
405 "use Unicode filenames instead",
406 1);
407}
408#endif
409
410
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200411#ifndef MS_WINDOWS
412PyObject *
413_PyLong_FromUid(uid_t uid)
414{
415 if (uid == (uid_t)-1)
416 return PyLong_FromLong(-1);
417 return PyLong_FromUnsignedLong(uid);
418}
419
420PyObject *
421_PyLong_FromGid(gid_t gid)
422{
423 if (gid == (gid_t)-1)
424 return PyLong_FromLong(-1);
425 return PyLong_FromUnsignedLong(gid);
426}
427
428int
429_Py_Uid_Converter(PyObject *obj, void *p)
430{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700431 uid_t uid;
432 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200433 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200434 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700435 unsigned long uresult;
436
437 index = PyNumber_Index(obj);
438 if (index == NULL) {
439 PyErr_Format(PyExc_TypeError,
440 "uid should be integer, not %.200s",
441 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200442 return 0;
443 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700444
445 /*
446 * Handling uid_t is complicated for two reasons:
447 * * Although uid_t is (always?) unsigned, it still
448 * accepts -1.
449 * * We don't know its size in advance--it may be
450 * bigger than an int, or it may be smaller than
451 * a long.
452 *
453 * So a bit of defensive programming is in order.
454 * Start with interpreting the value passed
455 * in as a signed long and see if it works.
456 */
457
458 result = PyLong_AsLongAndOverflow(index, &overflow);
459
460 if (!overflow) {
461 uid = (uid_t)result;
462
463 if (result == -1) {
464 if (PyErr_Occurred())
465 goto fail;
466 /* It's a legitimate -1, we're done. */
467 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200468 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700469
470 /* Any other negative number is disallowed. */
471 if (result < 0)
472 goto underflow;
473
474 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200475 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700476 (long)uid != result)
477 goto underflow;
478 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200479 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700480
481 if (overflow < 0)
482 goto underflow;
483
484 /*
485 * Okay, the value overflowed a signed long. If it
486 * fits in an *unsigned* long, it may still be okay,
487 * as uid_t may be unsigned long on this platform.
488 */
489 uresult = PyLong_AsUnsignedLong(index);
490 if (PyErr_Occurred()) {
491 if (PyErr_ExceptionMatches(PyExc_OverflowError))
492 goto overflow;
493 goto fail;
494 }
495
496 uid = (uid_t)uresult;
497
498 /*
499 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
500 * but this value would get interpreted as (uid_t)-1 by chown
501 * and its siblings. That's not what the user meant! So we
502 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100503 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700504 */
505 if (uid == (uid_t)-1)
506 goto overflow;
507
508 /* Ensure the value wasn't truncated. */
509 if (sizeof(uid_t) < sizeof(long) &&
510 (unsigned long)uid != uresult)
511 goto overflow;
512 /* fallthrough */
513
514success:
515 Py_DECREF(index);
516 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517 return 1;
518
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700519underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200520 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700521 "uid is less than minimum");
522 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200523
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700524overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200525 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700526 "uid is greater than maximum");
527 /* fallthrough */
528
529fail:
530 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200531 return 0;
532}
533
534int
535_Py_Gid_Converter(PyObject *obj, void *p)
536{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700537 gid_t gid;
538 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200539 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200540 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700541 unsigned long uresult;
542
543 index = PyNumber_Index(obj);
544 if (index == NULL) {
545 PyErr_Format(PyExc_TypeError,
546 "gid should be integer, not %.200s",
547 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200548 return 0;
549 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700550
551 /*
552 * Handling gid_t is complicated for two reasons:
553 * * Although gid_t is (always?) unsigned, it still
554 * accepts -1.
555 * * We don't know its size in advance--it may be
556 * bigger than an int, or it may be smaller than
557 * a long.
558 *
559 * So a bit of defensive programming is in order.
560 * Start with interpreting the value passed
561 * in as a signed long and see if it works.
562 */
563
564 result = PyLong_AsLongAndOverflow(index, &overflow);
565
566 if (!overflow) {
567 gid = (gid_t)result;
568
569 if (result == -1) {
570 if (PyErr_Occurred())
571 goto fail;
572 /* It's a legitimate -1, we're done. */
573 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575
576 /* Any other negative number is disallowed. */
577 if (result < 0) {
578 goto underflow;
579 }
580
581 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200582 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700583 (long)gid != result)
584 goto underflow;
585 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200586 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700587
588 if (overflow < 0)
589 goto underflow;
590
591 /*
592 * Okay, the value overflowed a signed long. If it
593 * fits in an *unsigned* long, it may still be okay,
594 * as gid_t may be unsigned long on this platform.
595 */
596 uresult = PyLong_AsUnsignedLong(index);
597 if (PyErr_Occurred()) {
598 if (PyErr_ExceptionMatches(PyExc_OverflowError))
599 goto overflow;
600 goto fail;
601 }
602
603 gid = (gid_t)uresult;
604
605 /*
606 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
607 * but this value would get interpreted as (gid_t)-1 by chown
608 * and its siblings. That's not what the user meant! So we
609 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100610 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700611 */
612 if (gid == (gid_t)-1)
613 goto overflow;
614
615 /* Ensure the value wasn't truncated. */
616 if (sizeof(gid_t) < sizeof(long) &&
617 (unsigned long)gid != uresult)
618 goto overflow;
619 /* fallthrough */
620
621success:
622 Py_DECREF(index);
623 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 return 1;
625
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700626underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200627 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700628 "gid is less than minimum");
629 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700631overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700633 "gid is greater than maximum");
634 /* fallthrough */
635
636fail:
637 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200638 return 0;
639}
640#endif /* MS_WINDOWS */
641
642
Gregory P. Smith702dada2015-01-28 16:07:52 -0800643#ifdef HAVE_LONG_LONG
644# define _PyLong_FromDev PyLong_FromLongLong
645#else
646# define _PyLong_FromDev PyLong_FromLong
647#endif
648
649
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200650#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
651static int
652_Py_Dev_Converter(PyObject *obj, void *p)
653{
654#ifdef HAVE_LONG_LONG
655 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
656#else
657 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
658#endif
659 if (PyErr_Occurred())
660 return 0;
661 return 1;
662}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800663#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200664
665
Larry Hastings9cf065c2012-06-22 16:30:09 -0700666#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400667/*
668 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
669 * without the int cast, the value gets interpreted as uint (4291925331),
670 * which doesn't play nicely with all the initializer lines in this file that
671 * look like this:
672 * int dir_fd = DEFAULT_DIR_FD;
673 */
674#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700675#else
676#define DEFAULT_DIR_FD (-100)
677#endif
678
679static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300680_fd_converter(PyObject *o, int *p)
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200681{
682 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700683 long long_value;
684
685 PyObject *index = PyNumber_Index(o);
686 if (index == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700687 return 0;
688 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300690 assert(PyLong_Check(index));
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700691 long_value = PyLong_AsLongAndOverflow(index, &overflow);
692 Py_DECREF(index);
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300693 assert(!PyErr_Occurred());
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700697 return 0;
698 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200699 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700700 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700701 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700702 return 0;
703 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700704
Larry Hastings9cf065c2012-06-22 16:30:09 -0700705 *p = (int)long_value;
706 return 1;
707}
708
709static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200710dir_fd_converter(PyObject *o, void *p)
711{
712 if (o == Py_None) {
713 *(int *)p = DEFAULT_DIR_FD;
714 return 1;
715 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300716 else if (PyIndex_Check(o)) {
717 return _fd_converter(o, (int *)p);
718 }
719 else {
720 PyErr_Format(PyExc_TypeError,
721 "argument should be integer or None, not %.200s",
722 Py_TYPE(o)->tp_name);
723 return 0;
724 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700725}
726
727
Larry Hastings9cf065c2012-06-22 16:30:09 -0700728/*
729 * A PyArg_ParseTuple "converter" function
730 * that handles filesystem paths in the manner
731 * preferred by the os module.
732 *
733 * path_converter accepts (Unicode) strings and their
734 * subclasses, and bytes and their subclasses. What
735 * it does with the argument depends on the platform:
736 *
737 * * On Windows, if we get a (Unicode) string we
738 * extract the wchar_t * and return it; if we get
739 * bytes we extract the char * and return that.
740 *
741 * * On all other platforms, strings are encoded
742 * to bytes using PyUnicode_FSConverter, then we
743 * extract the char * from the bytes object and
744 * return that.
745 *
746 * path_converter also optionally accepts signed
747 * integers (representing open file descriptors) instead
748 * of path strings.
749 *
750 * Input fields:
751 * path.nullable
752 * If nonzero, the path is permitted to be None.
753 * path.allow_fd
754 * If nonzero, the path is permitted to be a file handle
755 * (a signed int) instead of a string.
756 * path.function_name
757 * If non-NULL, path_converter will use that as the name
758 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700759 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700760 * path.argument_name
761 * If non-NULL, path_converter will use that as the name
762 * of the parameter in error messages.
763 * (If path.argument_name is NULL it uses "path".)
764 *
765 * Output fields:
766 * path.wide
767 * Points to the path if it was expressed as Unicode
768 * and was not encoded. (Only used on Windows.)
769 * path.narrow
770 * Points to the path if it was expressed as bytes,
771 * or it was Unicode and was encoded to bytes.
772 * path.fd
773 * Contains a file descriptor if path.accept_fd was true
774 * and the caller provided a signed integer instead of any
775 * sort of string.
776 *
777 * WARNING: if your "path" parameter is optional, and is
778 * unspecified, path_converter will never get called.
779 * So if you set allow_fd, you *MUST* initialize path.fd = -1
780 * yourself!
781 * path.length
782 * The length of the path in characters, if specified as
783 * a string.
784 * path.object
785 * The original object passed in.
786 * path.cleanup
787 * For internal use only. May point to a temporary object.
788 * (Pay no attention to the man behind the curtain.)
789 *
790 * At most one of path.wide or path.narrow will be non-NULL.
791 * If path was None and path.nullable was set,
792 * or if path was an integer and path.allow_fd was set,
793 * both path.wide and path.narrow will be NULL
794 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200795 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700796 * path_converter takes care to not write to the path_t
797 * unless it's successful. However it must reset the
798 * "cleanup" field each time it's called.
799 *
800 * Use as follows:
801 * path_t path;
802 * memset(&path, 0, sizeof(path));
803 * PyArg_ParseTuple(args, "O&", path_converter, &path);
804 * // ... use values from path ...
805 * path_cleanup(&path);
806 *
807 * (Note that if PyArg_Parse fails you don't need to call
808 * path_cleanup(). However it is safe to do so.)
809 */
810typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100811 const char *function_name;
812 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813 int nullable;
814 int allow_fd;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300815 const wchar_t *wide;
816 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817 int fd;
818 Py_ssize_t length;
819 PyObject *object;
820 PyObject *cleanup;
821} path_t;
822
Larry Hastings2f936352014-08-05 14:04:04 +1000823#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
824 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700825
Larry Hastings9cf065c2012-06-22 16:30:09 -0700826static void
827path_cleanup(path_t *path) {
828 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200829 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700830 }
831}
832
833static int
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300834path_converter(PyObject *o, void *p)
835{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700836 path_t *path = (path_t *)p;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300837 PyObject *bytes;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700838 Py_ssize_t length;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300839 const char *narrow;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700840
841#define FORMAT_EXCEPTION(exc, fmt) \
842 PyErr_Format(exc, "%s%s" fmt, \
843 path->function_name ? path->function_name : "", \
844 path->function_name ? ": " : "", \
845 path->argument_name ? path->argument_name : "path")
846
847 /* Py_CLEANUP_SUPPORTED support */
848 if (o == NULL) {
849 path_cleanup(path);
850 return 1;
851 }
852
853 /* ensure it's always safe to call path_cleanup() */
854 path->cleanup = NULL;
855
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300856 if ((o == Py_None) && path->nullable) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700857 path->wide = NULL;
858 path->narrow = NULL;
859 path->length = 0;
860 path->object = o;
861 path->fd = -1;
862 return 1;
863 }
864
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300865 if (PyUnicode_Check(o)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +0300867 const wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100868
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300869 wide = PyUnicode_AsUnicodeAndSize(o, &length);
Victor Stinner59799a82013-11-13 14:17:30 +0100870 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700871 return 0;
872 }
Victor Stinner59799a82013-11-13 14:17:30 +0100873 if (length > 32767) {
874 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700875 return 0;
876 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300877 if (wcslen(wide) != length) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300878 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300879 return 0;
880 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700881
882 path->wide = wide;
883 path->narrow = NULL;
884 path->length = length;
885 path->object = o;
886 path->fd = -1;
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300887 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700888#else
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300889 if (!PyUnicode_FSConverter(o, &bytes)) {
890 return 0;
891 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700892#endif
893 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300894 else if (PyObject_CheckBuffer(o)) {
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300895#ifdef MS_WINDOWS
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300896 if (win32_warn_bytes_api()) {
897 return 0;
898 }
Serhiy Storchaka3291d852016-04-06 23:02:46 +0300899#endif
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300900 bytes = PyBytes_FromObject(o);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901 if (!bytes) {
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300902 return 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903 }
904 }
Serhiy Storchaka819399b2016-04-06 22:17:52 +0300905 else if (path->allow_fd && PyIndex_Check(o)) {
906 if (!_fd_converter(o, &path->fd)) {
907 return 0;
908 }
909 path->wide = NULL;
910 path->narrow = NULL;
911 path->length = 0;
912 path->object = o;
913 return 1;
914 }
915 else {
916 PyErr_Format(PyExc_TypeError, "%s%s%s should be %s, not %.200s",
917 path->function_name ? path->function_name : "",
918 path->function_name ? ": " : "",
919 path->argument_name ? path->argument_name : "path",
920 path->allow_fd && path->nullable ? "string, bytes, integer or None" :
921 path->allow_fd ? "string, bytes or integer" :
922 path->nullable ? "string, bytes or None" :
923 "string or bytes",
924 Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700925 return 0;
926 }
927
Larry Hastings9cf065c2012-06-22 16:30:09 -0700928 length = PyBytes_GET_SIZE(bytes);
929#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100930 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
932 Py_DECREF(bytes);
933 return 0;
934 }
935#endif
936
937 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200938 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300939 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 Py_DECREF(bytes);
941 return 0;
942 }
943
944 path->wide = NULL;
945 path->narrow = narrow;
946 path->length = length;
947 path->object = o;
948 path->fd = -1;
949 path->cleanup = bytes;
950 return Py_CLEANUP_SUPPORTED;
951}
952
953static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200954argument_unavailable_error(const char *function_name, const char *argument_name)
955{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700956 PyErr_Format(PyExc_NotImplementedError,
957 "%s%s%s unavailable on this platform",
958 (function_name != NULL) ? function_name : "",
959 (function_name != NULL) ? ": ": "",
960 argument_name);
961}
962
963static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200964dir_fd_unavailable(PyObject *o, void *p)
965{
966 int dir_fd;
967 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700968 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200969 if (dir_fd != DEFAULT_DIR_FD) {
970 argument_unavailable_error(NULL, "dir_fd");
971 return 0;
972 }
973 *(int *)p = dir_fd;
974 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700975}
976
977static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200978fd_specified(const char *function_name, int fd)
979{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700980 if (fd == -1)
981 return 0;
982
983 argument_unavailable_error(function_name, "fd");
984 return 1;
985}
986
987static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200988follow_symlinks_specified(const char *function_name, int follow_symlinks)
989{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700990 if (follow_symlinks)
991 return 0;
992
993 argument_unavailable_error(function_name, "follow_symlinks");
994 return 1;
995}
996
997static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200998path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
999{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001000 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
1001 PyErr_Format(PyExc_ValueError,
1002 "%s: can't specify dir_fd without matching path",
1003 function_name);
1004 return 1;
1005 }
1006 return 0;
1007}
1008
1009static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001010dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1011{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001012 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1013 PyErr_Format(PyExc_ValueError,
1014 "%s: can't specify both dir_fd and fd",
1015 function_name);
1016 return 1;
1017 }
1018 return 0;
1019}
1020
1021static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001022fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1023 int follow_symlinks)
1024{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001025 if ((fd > 0) && (!follow_symlinks)) {
1026 PyErr_Format(PyExc_ValueError,
1027 "%s: cannot use fd and follow_symlinks together",
1028 function_name);
1029 return 1;
1030 }
1031 return 0;
1032}
1033
1034static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001035dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1036 int follow_symlinks)
1037{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001038 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1039 PyErr_Format(PyExc_ValueError,
1040 "%s: cannot use dir_fd and follow_symlinks together",
1041 function_name);
1042 return 1;
1043 }
1044 return 0;
1045}
1046
Larry Hastings2f936352014-08-05 14:04:04 +10001047#ifdef MS_WINDOWS
1048 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001049#else
Larry Hastings2f936352014-08-05 14:04:04 +10001050 typedef off_t Py_off_t;
1051#endif
1052
1053static int
1054Py_off_t_converter(PyObject *arg, void *addr)
1055{
1056#ifdef HAVE_LARGEFILE_SUPPORT
1057 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1058#else
1059 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001060#endif
1061 if (PyErr_Occurred())
1062 return 0;
1063 return 1;
1064}
Larry Hastings2f936352014-08-05 14:04:04 +10001065
1066static PyObject *
1067PyLong_FromPy_off_t(Py_off_t offset)
1068{
1069#ifdef HAVE_LARGEFILE_SUPPORT
1070 return PyLong_FromLongLong(offset);
1071#else
1072 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001073#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001074}
1075
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001076
Steve Dowerd81431f2015-03-06 14:47:02 -08001077#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1078/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1079 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001080 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001081#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001082#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001083#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001084#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001085#define _NO_CONSOLE_FILENO (intptr_t)-2
1086
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001087/* the special case of checking dup2. The target fd must be in a sensible range */
1088static int
1089_PyVerify_fd_dup2(int fd1, int fd2)
1090{
Victor Stinner8c62be82010-05-06 00:08:46 +00001091 if (!_PyVerify_fd(fd1))
1092 return 0;
1093 if (fd2 == _NO_CONSOLE_FILENO)
1094 return 0;
1095 if ((unsigned)fd2 < _NHANDLE_)
1096 return 1;
1097 else
1098 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001099}
1100#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001101#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001102#endif
1103
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001104#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001105
1106static int
Brian Curtind25aef52011-06-13 15:16:04 -05001107win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001108{
1109 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1110 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1111 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112
1113 if (0 == DeviceIoControl(
1114 reparse_point_handle,
1115 FSCTL_GET_REPARSE_POINT,
1116 NULL, 0, /* in buffer */
1117 target_buffer, sizeof(target_buffer),
1118 &n_bytes_returned,
1119 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001120 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001121
1122 if (reparse_tag)
1123 *reparse_tag = rdb->ReparseTag;
1124
Brian Curtind25aef52011-06-13 15:16:04 -05001125 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001126}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001127
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001128#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001129
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001131#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001132/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001133** environ directly, we must obtain it with _NSGetEnviron(). See also
1134** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001135*/
1136#include <crt_externs.h>
1137static char **environ;
1138#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001140#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001141
Barry Warsaw53699e91996-12-10 23:23:01 +00001142static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001143convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001144{
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001146#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001147 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001148#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001149 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001150#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001151
Victor Stinner8c62be82010-05-06 00:08:46 +00001152 d = PyDict_New();
1153 if (d == NULL)
1154 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001155#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001156 if (environ == NULL)
1157 environ = *_NSGetEnviron();
1158#endif
1159#ifdef MS_WINDOWS
1160 /* _wenviron must be initialized in this way if the program is started
1161 through main() instead of wmain(). */
1162 _wgetenv(L"");
1163 if (_wenviron == NULL)
1164 return d;
1165 /* This part ignores errors */
1166 for (e = _wenviron; *e != NULL; e++) {
1167 PyObject *k;
1168 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001169 const wchar_t *p = wcschr(*e, L'=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001170 if (p == NULL)
1171 continue;
1172 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1173 if (k == NULL) {
1174 PyErr_Clear();
1175 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001176 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001177 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1178 if (v == NULL) {
1179 PyErr_Clear();
1180 Py_DECREF(k);
1181 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001182 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001183 if (PyDict_GetItem(d, k) == NULL) {
1184 if (PyDict_SetItem(d, k, v) != 0)
1185 PyErr_Clear();
1186 }
1187 Py_DECREF(k);
1188 Py_DECREF(v);
1189 }
1190#else
1191 if (environ == NULL)
1192 return d;
1193 /* This part ignores errors */
1194 for (e = environ; *e != NULL; e++) {
1195 PyObject *k;
1196 PyObject *v;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03001197 const char *p = strchr(*e, '=');
Victor Stinner8c62be82010-05-06 00:08:46 +00001198 if (p == NULL)
1199 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001200 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001201 if (k == NULL) {
1202 PyErr_Clear();
1203 continue;
1204 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001205 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001206 if (v == NULL) {
1207 PyErr_Clear();
1208 Py_DECREF(k);
1209 continue;
1210 }
1211 if (PyDict_GetItem(d, k) == NULL) {
1212 if (PyDict_SetItem(d, k, v) != 0)
1213 PyErr_Clear();
1214 }
1215 Py_DECREF(k);
1216 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001217 }
1218#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001219 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220}
1221
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001222/* Set a POSIX-specific error from errno, and return NULL */
1223
Barry Warsawd58d7641998-07-23 16:14:40 +00001224static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001225posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001226{
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001228}
Mark Hammondef8b6542001-05-13 08:04:26 +00001229
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001230#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001231static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001232win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001233{
Victor Stinner8c62be82010-05-06 00:08:46 +00001234 /* XXX We should pass the function name along in the future.
1235 (winreg.c also wants to pass the function name.)
1236 This would however require an additional param to the
1237 Windows error object, which is non-trivial.
1238 */
1239 errno = GetLastError();
1240 if (filename)
1241 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1242 else
1243 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001244}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001245
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001246static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001247win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001248{
1249 /* XXX - see win32_error for comments on 'function' */
1250 errno = GetLastError();
1251 if (filename)
1252 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001253 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001254 errno,
1255 filename);
1256 else
1257 return PyErr_SetFromWindowsErr(errno);
1258}
1259
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001260#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001261
Larry Hastings9cf065c2012-06-22 16:30:09 -07001262static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001263path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001264{
1265#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001266 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1267 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001268#else
Victor Stinner292c8352012-10-30 02:17:38 +01001269 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001270#endif
1271}
1272
Larry Hastings31826802013-10-19 00:09:25 -07001273
Larry Hastingsb0827312014-02-09 22:05:19 -08001274static PyObject *
1275path_error2(path_t *path, path_t *path2)
1276{
1277#ifdef MS_WINDOWS
1278 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1279 0, path->object, path2->object);
1280#else
1281 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1282 path->object, path2->object);
1283#endif
1284}
1285
1286
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001287/* POSIX generic methods */
1288
Larry Hastings2f936352014-08-05 14:04:04 +10001289static int
1290fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001291{
Victor Stinner8c62be82010-05-06 00:08:46 +00001292 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001293 int *pointer = (int *)p;
1294 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001295 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001296 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001297 *pointer = fd;
1298 return 1;
1299}
1300
1301static PyObject *
1302posix_fildes_fd(int fd, int (*func)(int))
1303{
1304 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001305 int async_err = 0;
1306
Steve Dower8fc89802015-04-12 00:26:27 -04001307 if (!_PyVerify_fd(fd))
1308 return posix_error();
1309
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001310 do {
1311 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001312 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001313 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001314 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001315 Py_END_ALLOW_THREADS
1316 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1317 if (res != 0)
1318 return (!async_err) ? posix_error() : NULL;
1319 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001320}
Guido van Rossum21142a01999-01-08 21:05:37 +00001321
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001322
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001323#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001324/* This is a reimplementation of the C library's chdir function,
1325 but one that produces Win32 errors instead of DOS error codes.
1326 chdir is essentially a wrapper around SetCurrentDirectory; however,
1327 it also needs to set "magic" environment variables indicating
1328 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001329static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001330win32_chdir(LPCSTR path)
1331{
Victor Stinner75875072013-11-24 19:23:25 +01001332 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001333 int result;
1334 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001335
Victor Stinner8c62be82010-05-06 00:08:46 +00001336 if(!SetCurrentDirectoryA(path))
1337 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001338 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001339 if (!result)
1340 return FALSE;
1341 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001342 than MAX_PATH-1 (not including the final null character). */
1343 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001344 if (strncmp(new_path, "\\\\", 2) == 0 ||
1345 strncmp(new_path, "//", 2) == 0)
1346 /* UNC path, nothing to do. */
1347 return TRUE;
1348 env[1] = new_path[0];
1349 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001350}
1351
1352/* The Unicode version differs from the ANSI version
1353 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001354static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001355win32_wchdir(LPCWSTR path)
1356{
Victor Stinnered537822015-12-13 21:40:26 +01001357 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001358 int result;
1359 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001360
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 if(!SetCurrentDirectoryW(path))
1362 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001363 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001364 if (!result)
1365 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001366 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001367 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 if (!new_path) {
1369 SetLastError(ERROR_OUTOFMEMORY);
1370 return FALSE;
1371 }
1372 result = GetCurrentDirectoryW(result, new_path);
1373 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001374 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001375 return FALSE;
1376 }
1377 }
1378 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1379 wcsncmp(new_path, L"//", 2) == 0)
1380 /* UNC path, nothing to do. */
1381 return TRUE;
1382 env[1] = new_path[0];
1383 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001384 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001385 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001386 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001387}
1388#endif
1389
Martin v. Löwis14694662006-02-03 12:54:16 +00001390#ifdef MS_WINDOWS
1391/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1392 - time stamps are restricted to second resolution
1393 - file modification times suffer from forth-and-back conversions between
1394 UTC and local time
1395 Therefore, we implement our own stat, based on the Win32 API directly.
1396*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001397#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001398#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001399
Guido van Rossumd8faa362007-04-27 19:54:29 +00001400static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001401attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001402{
Victor Stinner8c62be82010-05-06 00:08:46 +00001403 HANDLE hFindFile;
1404 WIN32_FIND_DATAA FileData;
1405 hFindFile = FindFirstFileA(pszFile, &FileData);
1406 if (hFindFile == INVALID_HANDLE_VALUE)
1407 return FALSE;
1408 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001409 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001410 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001411 info->dwFileAttributes = FileData.dwFileAttributes;
1412 info->ftCreationTime = FileData.ftCreationTime;
1413 info->ftLastAccessTime = FileData.ftLastAccessTime;
1414 info->ftLastWriteTime = FileData.ftLastWriteTime;
1415 info->nFileSizeHigh = FileData.nFileSizeHigh;
1416 info->nFileSizeLow = FileData.nFileSizeLow;
1417/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001418 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1419 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001420 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001421}
1422
Victor Stinner6036e442015-03-08 01:58:04 +01001423static void
1424find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1425 BY_HANDLE_FILE_INFORMATION *info,
1426 ULONG *reparse_tag)
1427{
1428 memset(info, 0, sizeof(*info));
1429 info->dwFileAttributes = pFileData->dwFileAttributes;
1430 info->ftCreationTime = pFileData->ftCreationTime;
1431 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1432 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1433 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1434 info->nFileSizeLow = pFileData->nFileSizeLow;
1435/* info->nNumberOfLinks = 1; */
1436 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1437 *reparse_tag = pFileData->dwReserved0;
1438 else
1439 *reparse_tag = 0;
1440}
1441
Guido van Rossumd8faa362007-04-27 19:54:29 +00001442static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001443attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001444{
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 HANDLE hFindFile;
1446 WIN32_FIND_DATAW FileData;
1447 hFindFile = FindFirstFileW(pszFile, &FileData);
1448 if (hFindFile == INVALID_HANDLE_VALUE)
1449 return FALSE;
1450 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001451 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001452 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001453}
1454
Brian Curtind25aef52011-06-13 15:16:04 -05001455static BOOL
1456get_target_path(HANDLE hdl, wchar_t **target_path)
1457{
1458 int buf_size, result_length;
1459 wchar_t *buf;
1460
1461 /* We have a good handle to the target, use it to determine
1462 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001463 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1464 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001465 if(!buf_size)
1466 return FALSE;
1467
Victor Stinnerc36674a2016-03-16 14:30:16 +01001468 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001469 if (!buf) {
1470 SetLastError(ERROR_OUTOFMEMORY);
1471 return FALSE;
1472 }
1473
Steve Dower2ea51c92015-03-20 21:49:12 -07001474 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001475 buf, buf_size, VOLUME_NAME_DOS);
1476
1477 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001478 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001479 return FALSE;
1480 }
1481
1482 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001483 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001484 return FALSE;
1485 }
1486
1487 buf[result_length] = 0;
1488
1489 *target_path = buf;
1490 return TRUE;
1491}
1492
1493static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001494win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001495 BOOL traverse);
1496static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001497win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001498 BOOL traverse)
1499{
Victor Stinner26de69d2011-06-17 15:15:38 +02001500 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001501 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001502 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001503 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001504 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001505 const char *dot;
1506
1507 hFile = CreateFileA(
1508 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001509 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 0, /* share mode */
1511 NULL, /* security attributes */
1512 OPEN_EXISTING,
1513 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001514 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1515 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001516 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001517 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1518 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001519 NULL);
1520
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001522 /* Either the target doesn't exist, or we don't have access to
1523 get a handle to it. If the former, we need to return an error.
1524 If the latter, we can use attributes_from_dir. */
1525 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001526 return -1;
1527 /* Could not get attributes on open file. Fall back to
1528 reading the directory. */
1529 if (!attributes_from_dir(path, &info, &reparse_tag))
1530 /* Very strange. This should not fail now */
1531 return -1;
1532 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1533 if (traverse) {
1534 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001535 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001536 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001537 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001538 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001539 } else {
1540 if (!GetFileInformationByHandle(hFile, &info)) {
1541 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001542 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001543 }
1544 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001545 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1546 return -1;
1547
1548 /* Close the outer open file handle now that we're about to
1549 reopen it with different flags. */
1550 if (!CloseHandle(hFile))
1551 return -1;
1552
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001553 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001554 /* In order to call GetFinalPathNameByHandle we need to open
1555 the file without the reparse handling flag set. */
1556 hFile2 = CreateFileA(
1557 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1558 NULL, OPEN_EXISTING,
1559 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1560 NULL);
1561 if (hFile2 == INVALID_HANDLE_VALUE)
1562 return -1;
1563
1564 if (!get_target_path(hFile2, &target_path))
1565 return -1;
1566
1567 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001568 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001569 return code;
1570 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001571 } else
1572 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001574 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575
1576 /* Set S_IEXEC if it is an .exe, .bat, ... */
1577 dot = strrchr(path, '.');
1578 if (dot) {
1579 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1580 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1581 result->st_mode |= 0111;
1582 }
1583 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001584}
1585
1586static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001587win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001588 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001589{
1590 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001591 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001592 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001593 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001594 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 const wchar_t *dot;
1596
1597 hFile = CreateFileW(
1598 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001599 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001600 0, /* share mode */
1601 NULL, /* security attributes */
1602 OPEN_EXISTING,
1603 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001604 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1605 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001606 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001607 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001608 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001609 NULL);
1610
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001611 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001612 /* Either the target doesn't exist, or we don't have access to
1613 get a handle to it. If the former, we need to return an error.
1614 If the latter, we can use attributes_from_dir. */
1615 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001616 return -1;
1617 /* Could not get attributes on open file. Fall back to
1618 reading the directory. */
1619 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1620 /* Very strange. This should not fail now */
1621 return -1;
1622 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1623 if (traverse) {
1624 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001627 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001628 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001629 } else {
1630 if (!GetFileInformationByHandle(hFile, &info)) {
1631 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001632 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001633 }
1634 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001635 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1636 return -1;
1637
1638 /* Close the outer open file handle now that we're about to
1639 reopen it with different flags. */
1640 if (!CloseHandle(hFile))
1641 return -1;
1642
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001643 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001644 /* In order to call GetFinalPathNameByHandle we need to open
1645 the file without the reparse handling flag set. */
1646 hFile2 = CreateFileW(
1647 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1648 NULL, OPEN_EXISTING,
1649 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1650 NULL);
1651 if (hFile2 == INVALID_HANDLE_VALUE)
1652 return -1;
1653
1654 if (!get_target_path(hFile2, &target_path))
1655 return -1;
1656
1657 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001658 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001659 return code;
1660 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001661 } else
1662 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001664 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001665
1666 /* Set S_IEXEC if it is an .exe, .bat, ... */
1667 dot = wcsrchr(path, '.');
1668 if (dot) {
1669 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1670 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1671 result->st_mode |= 0111;
1672 }
1673 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001674}
1675
1676static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001677win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001678{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 /* Protocol violation: we explicitly clear errno, instead of
1680 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001681 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001682 errno = 0;
1683 return code;
1684}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001687win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001688{
1689 /* Protocol violation: we explicitly clear errno, instead of
1690 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001691 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001692 errno = 0;
1693 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001694}
Brian Curtind25aef52011-06-13 15:16:04 -05001695/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001696
1697 In Posix, stat automatically traverses symlinks and returns the stat
1698 structure for the target. In Windows, the equivalent GetFileAttributes by
1699 default does not traverse symlinks and instead returns attributes for
1700 the symlink.
1701
1702 Therefore, win32_lstat will get the attributes traditionally, and
1703 win32_stat will first explicitly resolve the symlink target and then will
1704 call win32_lstat on that result.
1705
Ezio Melotti4969f702011-03-15 05:59:46 +02001706 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001707
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001708static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001709win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001710{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001711 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001712}
1713
Victor Stinner8c62be82010-05-06 00:08:46 +00001714static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001715win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001716{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001717 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001718}
1719
1720static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001721win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001722{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001723 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001724}
1725
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001726static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001727win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001728{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001729 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001730}
1731
Martin v. Löwis14694662006-02-03 12:54:16 +00001732#endif /* MS_WINDOWS */
1733
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001735"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001736This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001737 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001738or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1739\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001740Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1741or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001742\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001743See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001744
1745static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001746 {"st_mode", "protection bits"},
1747 {"st_ino", "inode"},
1748 {"st_dev", "device"},
1749 {"st_nlink", "number of hard links"},
1750 {"st_uid", "user ID of owner"},
1751 {"st_gid", "group ID of owner"},
1752 {"st_size", "total size, in bytes"},
1753 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1754 {NULL, "integer time of last access"},
1755 {NULL, "integer time of last modification"},
1756 {NULL, "integer time of last change"},
1757 {"st_atime", "time of last access"},
1758 {"st_mtime", "time of last modification"},
1759 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001760 {"st_atime_ns", "time of last access in nanoseconds"},
1761 {"st_mtime_ns", "time of last modification in nanoseconds"},
1762 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001763#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001766#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001768#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001769#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001772#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001774#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001775#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001777#endif
1778#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001780#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001781#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1782 {"st_file_attributes", "Windows file attribute bits"},
1783#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001784 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785};
1786
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001787#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001788#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001790#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791#endif
1792
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001793#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001794#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1795#else
1796#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1797#endif
1798
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001799#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001800#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1801#else
1802#define ST_RDEV_IDX ST_BLOCKS_IDX
1803#endif
1804
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001805#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1806#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1807#else
1808#define ST_FLAGS_IDX ST_RDEV_IDX
1809#endif
1810
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001811#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001812#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001813#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001814#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001815#endif
1816
1817#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1818#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1819#else
1820#define ST_BIRTHTIME_IDX ST_GEN_IDX
1821#endif
1822
Zachary Ware63f277b2014-06-19 09:46:37 -05001823#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1824#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1825#else
1826#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1827#endif
1828
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001830 "stat_result", /* name */
1831 stat_result__doc__, /* doc */
1832 stat_result_fields,
1833 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834};
1835
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001836PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001837"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1838This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001839 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001840or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001842See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001843
1844static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 {"f_bsize", },
1846 {"f_frsize", },
1847 {"f_blocks", },
1848 {"f_bfree", },
1849 {"f_bavail", },
1850 {"f_files", },
1851 {"f_ffree", },
1852 {"f_favail", },
1853 {"f_flag", },
1854 {"f_namemax",},
1855 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001856};
1857
1858static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001859 "statvfs_result", /* name */
1860 statvfs_result__doc__, /* doc */
1861 statvfs_result_fields,
1862 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001863};
1864
Ross Lagerwall7807c352011-03-17 20:20:30 +02001865#if defined(HAVE_WAITID) && !defined(__APPLE__)
1866PyDoc_STRVAR(waitid_result__doc__,
1867"waitid_result: Result from waitid.\n\n\
1868This object may be accessed either as a tuple of\n\
1869 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1870or via the attributes si_pid, si_uid, and so on.\n\
1871\n\
1872See os.waitid for more information.");
1873
1874static PyStructSequence_Field waitid_result_fields[] = {
1875 {"si_pid", },
1876 {"si_uid", },
1877 {"si_signo", },
1878 {"si_status", },
1879 {"si_code", },
1880 {0}
1881};
1882
1883static PyStructSequence_Desc waitid_result_desc = {
1884 "waitid_result", /* name */
1885 waitid_result__doc__, /* doc */
1886 waitid_result_fields,
1887 5
1888};
1889static PyTypeObject WaitidResultType;
1890#endif
1891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001892static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001893static PyTypeObject StatResultType;
1894static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001895#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001896static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001897#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001898static newfunc structseq_new;
1899
1900static PyObject *
1901statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1902{
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 PyStructSequence *result;
1904 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001905
Victor Stinner8c62be82010-05-06 00:08:46 +00001906 result = (PyStructSequence*)structseq_new(type, args, kwds);
1907 if (!result)
1908 return NULL;
1909 /* If we have been initialized from a tuple,
1910 st_?time might be set to None. Initialize it
1911 from the int slots. */
1912 for (i = 7; i <= 9; i++) {
1913 if (result->ob_item[i+3] == Py_None) {
1914 Py_DECREF(Py_None);
1915 Py_INCREF(result->ob_item[i]);
1916 result->ob_item[i+3] = result->ob_item[i];
1917 }
1918 }
1919 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001920}
1921
1922
1923
1924/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001925static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001926
1927PyDoc_STRVAR(stat_float_times__doc__,
1928"stat_float_times([newval]) -> oldval\n\n\
1929Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001930\n\
1931If value is True, future calls to stat() return floats; if it is False,\n\
1932future calls return ints.\n\
1933If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001934
Larry Hastings2f936352014-08-05 14:04:04 +10001935/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001936static PyObject*
1937stat_float_times(PyObject* self, PyObject *args)
1938{
Victor Stinner8c62be82010-05-06 00:08:46 +00001939 int newval = -1;
1940 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1941 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001942 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1943 "stat_float_times() is deprecated",
1944 1))
1945 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001946 if (newval == -1)
1947 /* Return old value */
1948 return PyBool_FromLong(_stat_float_times);
1949 _stat_float_times = newval;
1950 Py_INCREF(Py_None);
1951 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001952}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001953
Larry Hastings6fe20b32012-04-19 15:07:49 -07001954static PyObject *billion = NULL;
1955
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001956static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001957fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001958{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001959 PyObject *s = _PyLong_FromTime_t(sec);
1960 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1961 PyObject *s_in_ns = NULL;
1962 PyObject *ns_total = NULL;
1963 PyObject *float_s = NULL;
1964
1965 if (!(s && ns_fractional))
1966 goto exit;
1967
1968 s_in_ns = PyNumber_Multiply(s, billion);
1969 if (!s_in_ns)
1970 goto exit;
1971
1972 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1973 if (!ns_total)
1974 goto exit;
1975
Victor Stinner4195b5c2012-02-08 23:03:19 +01001976 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001977 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1978 if (!float_s)
1979 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001980 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001981 else {
1982 float_s = s;
1983 Py_INCREF(float_s);
1984 }
1985
1986 PyStructSequence_SET_ITEM(v, index, s);
1987 PyStructSequence_SET_ITEM(v, index+3, float_s);
1988 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1989 s = NULL;
1990 float_s = NULL;
1991 ns_total = NULL;
1992exit:
1993 Py_XDECREF(s);
1994 Py_XDECREF(ns_fractional);
1995 Py_XDECREF(s_in_ns);
1996 Py_XDECREF(ns_total);
1997 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001998}
1999
Tim Peters5aa91602002-01-30 05:46:57 +00002000/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00002001 (used by posix_stat() and posix_fstat()) */
2002static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002003_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002004{
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 unsigned long ansec, mnsec, cnsec;
2006 PyObject *v = PyStructSequence_New(&StatResultType);
2007 if (v == NULL)
2008 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002009
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002011#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 PyStructSequence_SET_ITEM(v, 1,
2013 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002014#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002015 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002016#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002017#ifdef MS_WINDOWS
2018 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002019#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002020 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002021#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002023#if defined(MS_WINDOWS)
2024 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2025 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2026#else
2027 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2028 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2029#endif
Fred Drake699f3522000-06-29 21:12:41 +00002030#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 PyStructSequence_SET_ITEM(v, 6,
2032 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002033#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002034 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002035#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002036
Martin v. Löwis14694662006-02-03 12:54:16 +00002037#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002038 ansec = st->st_atim.tv_nsec;
2039 mnsec = st->st_mtim.tv_nsec;
2040 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002041#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002042 ansec = st->st_atimespec.tv_nsec;
2043 mnsec = st->st_mtimespec.tv_nsec;
2044 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002045#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002046 ansec = st->st_atime_nsec;
2047 mnsec = st->st_mtime_nsec;
2048 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002049#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002050 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002051#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002052 fill_time(v, 7, st->st_atime, ansec);
2053 fill_time(v, 8, st->st_mtime, mnsec);
2054 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002055
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002056#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002057 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2058 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002059#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002060#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002061 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2062 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002063#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002064#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002065 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2066 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002067#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002068#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002069 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2070 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002071#endif
2072#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002073 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002074 PyObject *val;
2075 unsigned long bsec,bnsec;
2076 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002077#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002078 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002079#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002080 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002081#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002082 if (_stat_float_times) {
2083 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2084 } else {
2085 val = PyLong_FromLong((long)bsec);
2086 }
2087 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2088 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002090#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002091#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002092 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2093 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002094#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002095#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2096 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2097 PyLong_FromUnsignedLong(st->st_file_attributes));
2098#endif
Fred Drake699f3522000-06-29 21:12:41 +00002099
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 if (PyErr_Occurred()) {
2101 Py_DECREF(v);
2102 return NULL;
2103 }
Fred Drake699f3522000-06-29 21:12:41 +00002104
Victor Stinner8c62be82010-05-06 00:08:46 +00002105 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002106}
2107
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002108/* POSIX methods */
2109
Guido van Rossum94f6f721999-01-06 18:42:14 +00002110
2111static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002112posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002113 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002114{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002115 STRUCT_STAT st;
2116 int result;
2117
2118#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2119 if (follow_symlinks_specified(function_name, follow_symlinks))
2120 return NULL;
2121#endif
2122
2123 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2124 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2125 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2126 return NULL;
2127
2128 Py_BEGIN_ALLOW_THREADS
2129 if (path->fd != -1)
2130 result = FSTAT(path->fd, &st);
2131 else
2132#ifdef MS_WINDOWS
2133 if (path->wide) {
2134 if (follow_symlinks)
2135 result = win32_stat_w(path->wide, &st);
2136 else
2137 result = win32_lstat_w(path->wide, &st);
2138 }
2139 else
2140#endif
2141#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2142 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2143 result = LSTAT(path->narrow, &st);
2144 else
2145#endif
2146#ifdef HAVE_FSTATAT
2147 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2148 result = fstatat(dir_fd, path->narrow, &st,
2149 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2150 else
2151#endif
2152 result = STAT(path->narrow, &st);
2153 Py_END_ALLOW_THREADS
2154
Victor Stinner292c8352012-10-30 02:17:38 +01002155 if (result != 0) {
2156 return path_error(path);
2157 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002158
2159 return _pystat_fromstructstat(&st);
2160}
2161
Larry Hastings2f936352014-08-05 14:04:04 +10002162/*[python input]
2163
2164for s in """
2165
2166FACCESSAT
2167FCHMODAT
2168FCHOWNAT
2169FSTATAT
2170LINKAT
2171MKDIRAT
2172MKFIFOAT
2173MKNODAT
2174OPENAT
2175READLINKAT
2176SYMLINKAT
2177UNLINKAT
2178
2179""".strip().split():
2180 s = s.strip()
2181 print("""
2182#ifdef HAVE_{s}
2183 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002184#else
Larry Hastings2f936352014-08-05 14:04:04 +10002185 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002186#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002187""".rstrip().format(s=s))
2188
2189for s in """
2190
2191FCHDIR
2192FCHMOD
2193FCHOWN
2194FDOPENDIR
2195FEXECVE
2196FPATHCONF
2197FSTATVFS
2198FTRUNCATE
2199
2200""".strip().split():
2201 s = s.strip()
2202 print("""
2203#ifdef HAVE_{s}
2204 #define PATH_HAVE_{s} 1
2205#else
2206 #define PATH_HAVE_{s} 0
2207#endif
2208
2209""".rstrip().format(s=s))
2210[python start generated code]*/
2211
2212#ifdef HAVE_FACCESSAT
2213 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2214#else
2215 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2216#endif
2217
2218#ifdef HAVE_FCHMODAT
2219 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2220#else
2221 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2222#endif
2223
2224#ifdef HAVE_FCHOWNAT
2225 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2226#else
2227 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2228#endif
2229
2230#ifdef HAVE_FSTATAT
2231 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2232#else
2233 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2234#endif
2235
2236#ifdef HAVE_LINKAT
2237 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2238#else
2239 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2240#endif
2241
2242#ifdef HAVE_MKDIRAT
2243 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2244#else
2245 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2246#endif
2247
2248#ifdef HAVE_MKFIFOAT
2249 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2250#else
2251 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2252#endif
2253
2254#ifdef HAVE_MKNODAT
2255 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2256#else
2257 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2258#endif
2259
2260#ifdef HAVE_OPENAT
2261 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2262#else
2263 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2264#endif
2265
2266#ifdef HAVE_READLINKAT
2267 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2268#else
2269 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2270#endif
2271
2272#ifdef HAVE_SYMLINKAT
2273 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2274#else
2275 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2276#endif
2277
2278#ifdef HAVE_UNLINKAT
2279 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2280#else
2281 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2282#endif
2283
2284#ifdef HAVE_FCHDIR
2285 #define PATH_HAVE_FCHDIR 1
2286#else
2287 #define PATH_HAVE_FCHDIR 0
2288#endif
2289
2290#ifdef HAVE_FCHMOD
2291 #define PATH_HAVE_FCHMOD 1
2292#else
2293 #define PATH_HAVE_FCHMOD 0
2294#endif
2295
2296#ifdef HAVE_FCHOWN
2297 #define PATH_HAVE_FCHOWN 1
2298#else
2299 #define PATH_HAVE_FCHOWN 0
2300#endif
2301
2302#ifdef HAVE_FDOPENDIR
2303 #define PATH_HAVE_FDOPENDIR 1
2304#else
2305 #define PATH_HAVE_FDOPENDIR 0
2306#endif
2307
2308#ifdef HAVE_FEXECVE
2309 #define PATH_HAVE_FEXECVE 1
2310#else
2311 #define PATH_HAVE_FEXECVE 0
2312#endif
2313
2314#ifdef HAVE_FPATHCONF
2315 #define PATH_HAVE_FPATHCONF 1
2316#else
2317 #define PATH_HAVE_FPATHCONF 0
2318#endif
2319
2320#ifdef HAVE_FSTATVFS
2321 #define PATH_HAVE_FSTATVFS 1
2322#else
2323 #define PATH_HAVE_FSTATVFS 0
2324#endif
2325
2326#ifdef HAVE_FTRUNCATE
2327 #define PATH_HAVE_FTRUNCATE 1
2328#else
2329 #define PATH_HAVE_FTRUNCATE 0
2330#endif
2331/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002332
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002333#ifdef MS_WINDOWS
2334 #undef PATH_HAVE_FTRUNCATE
2335 #define PATH_HAVE_FTRUNCATE 1
2336#endif
Larry Hastings31826802013-10-19 00:09:25 -07002337
Larry Hastings61272b72014-01-07 12:41:53 -08002338/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002339
2340class path_t_converter(CConverter):
2341
2342 type = "path_t"
2343 impl_by_reference = True
2344 parse_by_reference = True
2345
2346 converter = 'path_converter'
2347
2348 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002349 # right now path_t doesn't support default values.
2350 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002351 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002352 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002353
Larry Hastings2f936352014-08-05 14:04:04 +10002354 if self.c_default not in (None, 'Py_None'):
2355 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002356
2357 self.nullable = nullable
2358 self.allow_fd = allow_fd
2359
Larry Hastings7726ac92014-01-31 22:03:12 -08002360 def pre_render(self):
2361 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002362 if isinstance(value, str):
2363 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002364 return str(int(bool(value)))
2365
2366 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002367 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002368 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002369 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002370 strify(self.nullable),
2371 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002372 )
2373
2374 def cleanup(self):
2375 return "path_cleanup(&" + self.name + ");\n"
2376
2377
2378class dir_fd_converter(CConverter):
2379 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002380
Larry Hastings2f936352014-08-05 14:04:04 +10002381 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002382 if self.default in (unspecified, None):
2383 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002384 if isinstance(requires, str):
2385 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2386 else:
2387 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002388
Larry Hastings2f936352014-08-05 14:04:04 +10002389class fildes_converter(CConverter):
2390 type = 'int'
2391 converter = 'fildes_converter'
2392
2393class uid_t_converter(CConverter):
2394 type = "uid_t"
2395 converter = '_Py_Uid_Converter'
2396
2397class gid_t_converter(CConverter):
2398 type = "gid_t"
2399 converter = '_Py_Gid_Converter'
2400
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002401class dev_t_converter(CConverter):
2402 type = 'dev_t'
2403 converter = '_Py_Dev_Converter'
2404
2405class dev_t_return_converter(unsigned_long_return_converter):
2406 type = 'dev_t'
2407 conversion_fn = '_PyLong_FromDev'
2408 unsigned_cast = '(dev_t)'
2409
Larry Hastings2f936352014-08-05 14:04:04 +10002410class FSConverter_converter(CConverter):
2411 type = 'PyObject *'
2412 converter = 'PyUnicode_FSConverter'
2413 def converter_init(self):
2414 if self.default is not unspecified:
2415 fail("FSConverter_converter does not support default values")
2416 self.c_default = 'NULL'
2417
2418 def cleanup(self):
2419 return "Py_XDECREF(" + self.name + ");\n"
2420
2421class pid_t_converter(CConverter):
2422 type = 'pid_t'
2423 format_unit = '" _Py_PARSE_PID "'
2424
2425class idtype_t_converter(int_converter):
2426 type = 'idtype_t'
2427
2428class id_t_converter(CConverter):
2429 type = 'id_t'
2430 format_unit = '" _Py_PARSE_PID "'
2431
2432class Py_intptr_t_converter(CConverter):
2433 type = 'Py_intptr_t'
2434 format_unit = '" _Py_PARSE_INTPTR "'
2435
2436class Py_off_t_converter(CConverter):
2437 type = 'Py_off_t'
2438 converter = 'Py_off_t_converter'
2439
2440class Py_off_t_return_converter(long_return_converter):
2441 type = 'Py_off_t'
2442 conversion_fn = 'PyLong_FromPy_off_t'
2443
2444class path_confname_converter(CConverter):
2445 type="int"
2446 converter="conv_path_confname"
2447
2448class confstr_confname_converter(path_confname_converter):
2449 converter='conv_confstr_confname'
2450
2451class sysconf_confname_converter(path_confname_converter):
2452 converter="conv_sysconf_confname"
2453
2454class sched_param_converter(CConverter):
2455 type = 'struct sched_param'
2456 converter = 'convert_sched_param'
2457 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002458
Larry Hastings61272b72014-01-07 12:41:53 -08002459[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002460/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002461
Larry Hastings61272b72014-01-07 12:41:53 -08002462/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002463
Larry Hastings2a727912014-01-16 11:32:01 -08002464os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002465
2466 path : path_t(allow_fd=True)
2467 Path to be examined; can be string, bytes, or open-file-descriptor int.
2468
2469 *
2470
Larry Hastings2f936352014-08-05 14:04:04 +10002471 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002472 If not None, it should be a file descriptor open to a directory,
2473 and path should be a relative string; path will then be relative to
2474 that directory.
2475
2476 follow_symlinks: bool = True
2477 If False, and the last element of the path is a symbolic link,
2478 stat will examine the symbolic link itself instead of the file
2479 the link points to.
2480
2481Perform a stat system call on the given path.
2482
2483dir_fd and follow_symlinks may not be implemented
2484 on your platform. If they are unavailable, using them will raise a
2485 NotImplementedError.
2486
2487It's an error to use dir_fd or follow_symlinks when specifying path as
2488 an open file descriptor.
2489
Larry Hastings61272b72014-01-07 12:41:53 -08002490[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002491
Larry Hastings31826802013-10-19 00:09:25 -07002492static PyObject *
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
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003896 if (!path->narrow)
3897 attributes = GetFileAttributesW(path->wide);
3898 else
3899 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003900
Brian Curtin9c669cc2011-06-08 18:17:18 -05003901 if (attributes == INVALID_FILE_ATTRIBUTES)
3902 Py_RETURN_FALSE;
3903
Brian Curtin9c669cc2011-06-08 18:17:18 -05003904 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3905 Py_RETURN_TRUE;
3906 else
3907 Py_RETURN_FALSE;
3908}
Tim Golden6b528062013-08-01 12:44:00 +01003909
Tim Golden6b528062013-08-01 12:44:00 +01003910
Larry Hastings2f936352014-08-05 14:04:04 +10003911/*[clinic input]
3912os._getvolumepathname
3913
3914 path: unicode
3915
3916A helper function for ismount on Win32.
3917[clinic start generated code]*/
3918
Larry Hastings2f936352014-08-05 14:04:04 +10003919static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003920os__getvolumepathname_impl(PyObject *module, PyObject *path)
3921/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003922{
3923 PyObject *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03003924 const wchar_t *path_wchar;
3925 wchar_t *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003926 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003927 BOOL ret;
3928
Larry Hastings2f936352014-08-05 14:04:04 +10003929 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3930 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003931 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003932 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003933
3934 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003935 buflen = Py_MAX(buflen, MAX_PATH);
3936
3937 if (buflen > DWORD_MAX) {
3938 PyErr_SetString(PyExc_OverflowError, "path too long");
3939 return NULL;
3940 }
3941
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003942 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003943 if (mountpath == NULL)
3944 return PyErr_NoMemory();
3945
3946 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003947 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003948 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003949 Py_END_ALLOW_THREADS
3950
3951 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003952 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003953 goto exit;
3954 }
3955 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3956
3957exit:
3958 PyMem_Free(mountpath);
3959 return result;
3960}
Tim Golden6b528062013-08-01 12:44:00 +01003961
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003962#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003963
Larry Hastings2f936352014-08-05 14:04:04 +10003964
3965/*[clinic input]
3966os.mkdir
3967
3968 path : path_t
3969
3970 mode: int = 0o777
3971
3972 *
3973
3974 dir_fd : dir_fd(requires='mkdirat') = None
3975
3976# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3977
3978Create a directory.
3979
3980If dir_fd is not None, it should be a file descriptor open to a directory,
3981 and path should be relative; path will then be relative to that directory.
3982dir_fd may not be implemented on your platform.
3983 If it is unavailable, using it will raise a NotImplementedError.
3984
3985The mode argument is ignored on Windows.
3986[clinic start generated code]*/
3987
Larry Hastings2f936352014-08-05 14:04:04 +10003988static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003989os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3990/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003991{
3992 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003993
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003994#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003995 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003996 if (path->wide)
3997 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003998 else
Larry Hastings2f936352014-08-05 14:04:04 +10003999 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00004000 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004001
Larry Hastings2f936352014-08-05 14:04:04 +10004002 if (!result)
4003 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004005 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004006#if HAVE_MKDIRAT
4007 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004008 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004009 else
4010#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004011#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004012 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004013#else
Larry Hastings2f936352014-08-05 14:04:04 +10004014 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004015#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004017 if (result < 0)
4018 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004019#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004020 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004021}
4022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004023
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004024/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4025#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004026#include <sys/resource.h>
4027#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004028
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004029
4030#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004031/*[clinic input]
4032os.nice
4033
4034 increment: int
4035 /
4036
4037Add increment to the priority of process and return the new priority.
4038[clinic start generated code]*/
4039
Larry Hastings2f936352014-08-05 14:04:04 +10004040static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004041os_nice_impl(PyObject *module, int increment)
4042/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004043{
4044 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004045
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 /* There are two flavours of 'nice': one that returns the new
4047 priority (as required by almost all standards out there) and the
4048 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4049 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004050
Victor Stinner8c62be82010-05-06 00:08:46 +00004051 If we are of the nice family that returns the new priority, we
4052 need to clear errno before the call, and check if errno is filled
4053 before calling posix_error() on a returnvalue of -1, because the
4054 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004055
Victor Stinner8c62be82010-05-06 00:08:46 +00004056 errno = 0;
4057 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004058#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004059 if (value == 0)
4060 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004061#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004062 if (value == -1 && errno != 0)
4063 /* either nice() or getpriority() returned an error */
4064 return posix_error();
4065 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004066}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004067#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004068
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004069
4070#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004071/*[clinic input]
4072os.getpriority
4073
4074 which: int
4075 who: int
4076
4077Return program scheduling priority.
4078[clinic start generated code]*/
4079
Larry Hastings2f936352014-08-05 14:04:04 +10004080static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004081os_getpriority_impl(PyObject *module, int which, int who)
4082/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004083{
4084 int retval;
4085
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004086 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004087 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004088 if (errno != 0)
4089 return posix_error();
4090 return PyLong_FromLong((long)retval);
4091}
4092#endif /* HAVE_GETPRIORITY */
4093
4094
4095#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004096/*[clinic input]
4097os.setpriority
4098
4099 which: int
4100 who: int
4101 priority: int
4102
4103Set program scheduling priority.
4104[clinic start generated code]*/
4105
Larry Hastings2f936352014-08-05 14:04:04 +10004106static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004107os_setpriority_impl(PyObject *module, int which, int who, int priority)
4108/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004109{
4110 int retval;
4111
4112 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004113 if (retval == -1)
4114 return posix_error();
4115 Py_RETURN_NONE;
4116}
4117#endif /* HAVE_SETPRIORITY */
4118
4119
Barry Warsaw53699e91996-12-10 23:23:01 +00004120static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004121internal_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 +00004122{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004123 const char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004125
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004126#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004127 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004128 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004129#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004131#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004132
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4134 (dst_dir_fd != DEFAULT_DIR_FD);
4135#ifndef HAVE_RENAMEAT
4136 if (dir_fd_specified) {
4137 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004138 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004139 }
4140#endif
4141
Larry Hastings2f936352014-08-05 14:04:04 +10004142 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004143 PyErr_Format(PyExc_ValueError,
4144 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004145 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146 }
4147
4148#ifdef MS_WINDOWS
4149 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004150 if (src->wide)
4151 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152 else
Larry Hastings2f936352014-08-05 14:04:04 +10004153 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154 Py_END_ALLOW_THREADS
4155
Larry Hastings2f936352014-08-05 14:04:04 +10004156 if (!result)
4157 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004158
4159#else
4160 Py_BEGIN_ALLOW_THREADS
4161#ifdef HAVE_RENAMEAT
4162 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004163 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004164 else
4165#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004166 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004167 Py_END_ALLOW_THREADS
4168
Larry Hastings2f936352014-08-05 14:04:04 +10004169 if (result)
4170 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004171#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004172 Py_RETURN_NONE;
4173}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004174
Larry Hastings2f936352014-08-05 14:04:04 +10004175
4176/*[clinic input]
4177os.rename
4178
4179 src : path_t
4180 dst : path_t
4181 *
4182 src_dir_fd : dir_fd = None
4183 dst_dir_fd : dir_fd = None
4184
4185Rename a file or directory.
4186
4187If either src_dir_fd or dst_dir_fd is not None, it should be a file
4188 descriptor open to a directory, and the respective path string (src or dst)
4189 should be relative; the path will then be relative to that directory.
4190src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4191 If they are unavailable, using them will raise a NotImplementedError.
4192[clinic start generated code]*/
4193
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004194static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004195os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004196 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004197/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004198{
Larry Hastings2f936352014-08-05 14:04:04 +10004199 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004200}
4201
Larry Hastings2f936352014-08-05 14:04:04 +10004202
4203/*[clinic input]
4204os.replace = os.rename
4205
4206Rename a file or directory, overwriting the destination.
4207
4208If either src_dir_fd or dst_dir_fd is not None, it should be a file
4209 descriptor open to a directory, and the respective path string (src or dst)
4210 should be relative; the path will then be relative to that directory.
4211src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4212 If they are unavailable, using them will raise a NotImplementedError."
4213[clinic start generated code]*/
4214
Larry Hastings2f936352014-08-05 14:04:04 +10004215static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004216os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4217 int dst_dir_fd)
4218/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004219{
4220 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4221}
4222
4223
4224/*[clinic input]
4225os.rmdir
4226
4227 path: path_t
4228 *
4229 dir_fd: dir_fd(requires='unlinkat') = None
4230
4231Remove a directory.
4232
4233If dir_fd is not None, it should be a file descriptor open to a directory,
4234 and path should be relative; path will then be relative to that directory.
4235dir_fd may not be implemented on your platform.
4236 If it is unavailable, using it will raise a NotImplementedError.
4237[clinic start generated code]*/
4238
Larry Hastings2f936352014-08-05 14:04:04 +10004239static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004240os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4241/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004242{
4243 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004244
4245 Py_BEGIN_ALLOW_THREADS
4246#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004247 if (path->wide)
4248 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249 else
Larry Hastings2f936352014-08-05 14:04:04 +10004250 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004251 result = !result; /* Windows, success=1, UNIX, success=0 */
4252#else
4253#ifdef HAVE_UNLINKAT
4254 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004255 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004256 else
4257#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004258 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004259#endif
4260 Py_END_ALLOW_THREADS
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262 if (result)
4263 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004264
Larry Hastings2f936352014-08-05 14:04:04 +10004265 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004266}
4267
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004268
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004269#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004270#ifdef MS_WINDOWS
4271/*[clinic input]
4272os.system -> long
4273
4274 command: Py_UNICODE
4275
4276Execute the command in a subshell.
4277[clinic start generated code]*/
4278
Larry Hastings2f936352014-08-05 14:04:04 +10004279static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004280os_system_impl(PyObject *module, Py_UNICODE *command)
4281/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004282{
4283 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004284 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004285 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004286 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004287 return result;
4288}
4289#else /* MS_WINDOWS */
4290/*[clinic input]
4291os.system -> long
4292
4293 command: FSConverter
4294
4295Execute the command in a subshell.
4296[clinic start generated code]*/
4297
Larry Hastings2f936352014-08-05 14:04:04 +10004298static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004299os_system_impl(PyObject *module, PyObject *command)
4300/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004301{
4302 long result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004303 const char *bytes = PyBytes_AsString(command);
Larry Hastings2f936352014-08-05 14:04:04 +10004304 Py_BEGIN_ALLOW_THREADS
4305 result = system(bytes);
4306 Py_END_ALLOW_THREADS
4307 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004308}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004309#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004310#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004311
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004312
Larry Hastings2f936352014-08-05 14:04:04 +10004313/*[clinic input]
4314os.umask
4315
4316 mask: int
4317 /
4318
4319Set the current numeric umask and return the previous umask.
4320[clinic start generated code]*/
4321
Larry Hastings2f936352014-08-05 14:04:04 +10004322static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004323os_umask_impl(PyObject *module, int mask)
4324/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004325{
4326 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004327 if (i < 0)
4328 return posix_error();
4329 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004330}
4331
Brian Curtind40e6f72010-07-08 21:39:08 +00004332#ifdef MS_WINDOWS
4333
4334/* override the default DeleteFileW behavior so that directory
4335symlinks can be removed with this function, the same as with
4336Unix symlinks */
4337BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4338{
4339 WIN32_FILE_ATTRIBUTE_DATA info;
4340 WIN32_FIND_DATAW find_data;
4341 HANDLE find_data_handle;
4342 int is_directory = 0;
4343 int is_link = 0;
4344
4345 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4346 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004347
Brian Curtind40e6f72010-07-08 21:39:08 +00004348 /* Get WIN32_FIND_DATA structure for the path to determine if
4349 it is a symlink */
4350 if(is_directory &&
4351 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4352 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4353
4354 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004355 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4356 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4357 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4358 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004359 FindClose(find_data_handle);
4360 }
4361 }
4362 }
4363
4364 if (is_directory && is_link)
4365 return RemoveDirectoryW(lpFileName);
4366
4367 return DeleteFileW(lpFileName);
4368}
4369#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004370
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004371
Larry Hastings2f936352014-08-05 14:04:04 +10004372/*[clinic input]
4373os.unlink
4374
4375 path: path_t
4376 *
4377 dir_fd: dir_fd(requires='unlinkat')=None
4378
4379Remove a file (same as remove()).
4380
4381If dir_fd is not None, it should be a file descriptor open to a directory,
4382 and path should be relative; path will then be relative to that directory.
4383dir_fd may not be implemented on your platform.
4384 If it is unavailable, using it will raise a NotImplementedError.
4385
4386[clinic start generated code]*/
4387
Larry Hastings2f936352014-08-05 14:04:04 +10004388static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004389os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4390/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004391{
4392 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393
4394 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004395 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004397 if (path->wide)
4398 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004399 else
Larry Hastings2f936352014-08-05 14:04:04 +10004400 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004401 result = !result; /* Windows, success=1, UNIX, success=0 */
4402#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403#ifdef HAVE_UNLINKAT
4404 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004405 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004406 else
4407#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004408 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004410 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004411 Py_END_ALLOW_THREADS
4412
Larry Hastings2f936352014-08-05 14:04:04 +10004413 if (result)
4414 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004415
Larry Hastings2f936352014-08-05 14:04:04 +10004416 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004417}
4418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Larry Hastings2f936352014-08-05 14:04:04 +10004420/*[clinic input]
4421os.remove = os.unlink
4422
4423Remove a file (same as unlink()).
4424
4425If dir_fd is not None, it should be a file descriptor open to a directory,
4426 and path should be relative; path will then be relative to that directory.
4427dir_fd may not be implemented on your platform.
4428 If it is unavailable, using it will raise a NotImplementedError.
4429[clinic start generated code]*/
4430
Larry Hastings2f936352014-08-05 14:04:04 +10004431static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004432os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4433/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004434{
4435 return os_unlink_impl(module, path, dir_fd);
4436}
4437
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004438
Larry Hastings605a62d2012-06-24 04:33:36 -07004439static PyStructSequence_Field uname_result_fields[] = {
4440 {"sysname", "operating system name"},
4441 {"nodename", "name of machine on network (implementation-defined)"},
4442 {"release", "operating system release"},
4443 {"version", "operating system version"},
4444 {"machine", "hardware identifier"},
4445 {NULL}
4446};
4447
4448PyDoc_STRVAR(uname_result__doc__,
4449"uname_result: Result from os.uname().\n\n\
4450This object may be accessed either as a tuple of\n\
4451 (sysname, nodename, release, version, machine),\n\
4452or via the attributes sysname, nodename, release, version, and machine.\n\
4453\n\
4454See os.uname for more information.");
4455
4456static PyStructSequence_Desc uname_result_desc = {
4457 "uname_result", /* name */
4458 uname_result__doc__, /* doc */
4459 uname_result_fields,
4460 5
4461};
4462
4463static PyTypeObject UnameResultType;
4464
4465
4466#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004467/*[clinic input]
4468os.uname
4469
4470Return an object identifying the current operating system.
4471
4472The object behaves like a named tuple with the following fields:
4473 (sysname, nodename, release, version, machine)
4474
4475[clinic start generated code]*/
4476
Larry Hastings2f936352014-08-05 14:04:04 +10004477static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004478os_uname_impl(PyObject *module)
4479/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004480{
Victor Stinner8c62be82010-05-06 00:08:46 +00004481 struct utsname u;
4482 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004483 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004484
Victor Stinner8c62be82010-05-06 00:08:46 +00004485 Py_BEGIN_ALLOW_THREADS
4486 res = uname(&u);
4487 Py_END_ALLOW_THREADS
4488 if (res < 0)
4489 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004490
4491 value = PyStructSequence_New(&UnameResultType);
4492 if (value == NULL)
4493 return NULL;
4494
4495#define SET(i, field) \
4496 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004497 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004498 if (!o) { \
4499 Py_DECREF(value); \
4500 return NULL; \
4501 } \
4502 PyStructSequence_SET_ITEM(value, i, o); \
4503 } \
4504
4505 SET(0, u.sysname);
4506 SET(1, u.nodename);
4507 SET(2, u.release);
4508 SET(3, u.version);
4509 SET(4, u.machine);
4510
4511#undef SET
4512
4513 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004514}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004515#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004516
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004517
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518
4519typedef struct {
4520 int now;
4521 time_t atime_s;
4522 long atime_ns;
4523 time_t mtime_s;
4524 long mtime_ns;
4525} utime_t;
4526
4527/*
Victor Stinner484df002014-10-09 13:52:31 +02004528 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 * they also intentionally leak the declaration of a pointer named "time"
4530 */
4531#define UTIME_TO_TIMESPEC \
4532 struct timespec ts[2]; \
4533 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004534 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535 time = NULL; \
4536 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004537 ts[0].tv_sec = ut->atime_s; \
4538 ts[0].tv_nsec = ut->atime_ns; \
4539 ts[1].tv_sec = ut->mtime_s; \
4540 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004541 time = ts; \
4542 } \
4543
4544#define UTIME_TO_TIMEVAL \
4545 struct timeval tv[2]; \
4546 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004547 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004548 time = NULL; \
4549 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004550 tv[0].tv_sec = ut->atime_s; \
4551 tv[0].tv_usec = ut->atime_ns / 1000; \
4552 tv[1].tv_sec = ut->mtime_s; \
4553 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 time = tv; \
4555 } \
4556
4557#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004558 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004560 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004561 time = NULL; \
4562 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004563 u.actime = ut->atime_s; \
4564 u.modtime = ut->mtime_s; \
4565 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004566 }
4567
4568#define UTIME_TO_TIME_T \
4569 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004570 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004571 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572 time = NULL; \
4573 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004574 timet[0] = ut->atime_s; \
4575 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004576 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004577 } \
4578
4579
Victor Stinner528a9ab2015-09-03 21:30:26 +02004580#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004581
4582static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004583utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004584{
4585#ifdef HAVE_UTIMENSAT
4586 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4587 UTIME_TO_TIMESPEC;
4588 return utimensat(dir_fd, path, time, flags);
4589#elif defined(HAVE_FUTIMESAT)
4590 UTIME_TO_TIMEVAL;
4591 /*
4592 * follow_symlinks will never be false here;
4593 * we only allow !follow_symlinks and dir_fd together
4594 * if we have utimensat()
4595 */
4596 assert(follow_symlinks);
4597 return futimesat(dir_fd, path, time);
4598#endif
4599}
4600
Larry Hastings2f936352014-08-05 14:04:04 +10004601 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4602#else
4603 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004604#endif
4605
Victor Stinner528a9ab2015-09-03 21:30:26 +02004606#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004607
4608static int
Victor Stinner484df002014-10-09 13:52:31 +02004609utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004610{
4611#ifdef HAVE_FUTIMENS
4612 UTIME_TO_TIMESPEC;
4613 return futimens(fd, time);
4614#else
4615 UTIME_TO_TIMEVAL;
4616 return futimes(fd, time);
4617#endif
4618}
4619
Larry Hastings2f936352014-08-05 14:04:04 +10004620 #define PATH_UTIME_HAVE_FD 1
4621#else
4622 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623#endif
4624
Victor Stinner5ebae872015-09-22 01:29:33 +02004625#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4626# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4627#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628
Victor Stinner4552ced2015-09-21 22:37:15 +02004629#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630
4631static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004632utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004633{
4634#ifdef HAVE_UTIMENSAT
4635 UTIME_TO_TIMESPEC;
4636 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4637#else
4638 UTIME_TO_TIMEVAL;
4639 return lutimes(path, time);
4640#endif
4641}
4642
4643#endif
4644
4645#ifndef MS_WINDOWS
4646
4647static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004648utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004649{
4650#ifdef HAVE_UTIMENSAT
4651 UTIME_TO_TIMESPEC;
4652 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4653#elif defined(HAVE_UTIMES)
4654 UTIME_TO_TIMEVAL;
4655 return utimes(path, time);
4656#elif defined(HAVE_UTIME_H)
4657 UTIME_TO_UTIMBUF;
4658 return utime(path, time);
4659#else
4660 UTIME_TO_TIME_T;
4661 return utime(path, time);
4662#endif
4663}
4664
4665#endif
4666
Larry Hastings76ad59b2012-05-03 00:30:07 -07004667static int
4668split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4669{
4670 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004671 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004672 divmod = PyNumber_Divmod(py_long, billion);
4673 if (!divmod)
4674 goto exit;
4675 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4676 if ((*s == -1) && PyErr_Occurred())
4677 goto exit;
4678 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004679 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004680 goto exit;
4681
4682 result = 1;
4683exit:
4684 Py_XDECREF(divmod);
4685 return result;
4686}
4687
Larry Hastings2f936352014-08-05 14:04:04 +10004688
4689/*[clinic input]
4690os.utime
4691
4692 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4693 times: object = NULL
4694 *
4695 ns: object = NULL
4696 dir_fd: dir_fd(requires='futimensat') = None
4697 follow_symlinks: bool=True
4698
Martin Panter0ff89092015-09-09 01:56:53 +00004699# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004700
4701Set the access and modified time of path.
4702
4703path may always be specified as a string.
4704On some platforms, path may also be specified as an open file descriptor.
4705 If this functionality is unavailable, using it raises an exception.
4706
4707If times is not None, it must be a tuple (atime, mtime);
4708 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004709If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004710 atime_ns and mtime_ns should be expressed as integer nanoseconds
4711 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004712If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004713Specifying tuples for both times and ns is an error.
4714
4715If dir_fd is not None, it should be a file descriptor open to a directory,
4716 and path should be relative; path will then be relative to that directory.
4717If follow_symlinks is False, and the last element of the path is a symbolic
4718 link, utime will modify the symbolic link itself instead of the file the
4719 link points to.
4720It is an error to use dir_fd or follow_symlinks when specifying path
4721 as an open file descriptor.
4722dir_fd and follow_symlinks may not be available on your platform.
4723 If they are unavailable, using them will raise a NotImplementedError.
4724
4725[clinic start generated code]*/
4726
Larry Hastings2f936352014-08-05 14:04:04 +10004727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004728os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4729 int dir_fd, int follow_symlinks)
4730/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004731{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732#ifdef MS_WINDOWS
4733 HANDLE hFile;
4734 FILETIME atime, mtime;
4735#else
4736 int result;
4737#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004738
Larry Hastings9cf065c2012-06-22 16:30:09 -07004739 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004740 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741
Christian Heimesb3c87242013-08-01 00:08:16 +02004742 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004743
Larry Hastings9cf065c2012-06-22 16:30:09 -07004744 if (times && (times != Py_None) && ns) {
4745 PyErr_SetString(PyExc_ValueError,
4746 "utime: you may specify either 'times'"
4747 " or 'ns' but not both");
4748 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004749 }
4750
4751 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004752 time_t a_sec, m_sec;
4753 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004754 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755 PyErr_SetString(PyExc_TypeError,
4756 "utime: 'times' must be either"
4757 " a tuple of two ints or None");
4758 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004759 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004761 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004762 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004763 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004764 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004766 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004767 utime.atime_s = a_sec;
4768 utime.atime_ns = a_nsec;
4769 utime.mtime_s = m_sec;
4770 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004771 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004773 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774 PyErr_SetString(PyExc_TypeError,
4775 "utime: 'ns' must be a tuple of two ints");
4776 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004779 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004781 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 &utime.mtime_s, &utime.mtime_ns)) {
4783 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004784 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785 }
4786 else {
4787 /* times and ns are both None/unspecified. use "now". */
4788 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004789 }
4790
Victor Stinner4552ced2015-09-21 22:37:15 +02004791#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 if (follow_symlinks_specified("utime", follow_symlinks))
4793 goto exit;
4794#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004795
Larry Hastings2f936352014-08-05 14:04:04 +10004796 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4797 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4798 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004800
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801#if !defined(HAVE_UTIMENSAT)
4802 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004803 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 "utime: cannot use dir_fd and follow_symlinks "
4805 "together on this platform");
4806 goto exit;
4807 }
4808#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004809
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004810#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004812 if (path->wide)
4813 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 NULL, OPEN_EXISTING,
4815 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816 else
Larry Hastings2f936352014-08-05 14:04:04 +10004817 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 NULL, OPEN_EXISTING,
4819 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004820 Py_END_ALLOW_THREADS
4821 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004822 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004824 }
4825
Larry Hastings9cf065c2012-06-22 16:30:09 -07004826 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004827 GetSystemTimeAsFileTime(&mtime);
4828 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004830 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004831 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4832 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004833 }
4834 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4835 /* Avoid putting the file name into the error here,
4836 as that may confuse the user into believing that
4837 something is wrong with the file, when it also
4838 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004839 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004841 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004842#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004844
Victor Stinner4552ced2015-09-21 22:37:15 +02004845#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004847 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004849#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004850
Victor Stinner528a9ab2015-09-03 21:30:26 +02004851#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004853 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854 else
4855#endif
4856
Victor Stinner528a9ab2015-09-03 21:30:26 +02004857#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004858 if (path->fd != -1)
4859 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004860 else
4861#endif
4862
Larry Hastings2f936352014-08-05 14:04:04 +10004863 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864
4865 Py_END_ALLOW_THREADS
4866
4867 if (result < 0) {
4868 /* see previous comment about not putting filename in error here */
4869 return_value = posix_error();
4870 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004871 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004872
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004873#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004874
4875 Py_INCREF(Py_None);
4876 return_value = Py_None;
4877
4878exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004879#ifdef MS_WINDOWS
4880 if (hFile != INVALID_HANDLE_VALUE)
4881 CloseHandle(hFile);
4882#endif
4883 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004884}
4885
Guido van Rossum3b066191991-06-04 19:40:25 +00004886/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004887
Larry Hastings2f936352014-08-05 14:04:04 +10004888
4889/*[clinic input]
4890os._exit
4891
4892 status: int
4893
4894Exit to the system with specified status, without normal exit processing.
4895[clinic start generated code]*/
4896
Larry Hastings2f936352014-08-05 14:04:04 +10004897static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004898os__exit_impl(PyObject *module, int status)
4899/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004900{
4901 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004902 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004903}
4904
Martin v. Löwis114619e2002-10-07 06:44:21 +00004905#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4906static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004907free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004908{
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 Py_ssize_t i;
4910 for (i = 0; i < count; i++)
4911 PyMem_Free(array[i]);
4912 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004913}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004914
Antoine Pitrou69f71142009-05-24 21:25:49 +00004915static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004916int fsconvert_strdup(PyObject *o, char**out)
4917{
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 PyObject *bytes;
4919 Py_ssize_t size;
4920 if (!PyUnicode_FSConverter(o, &bytes))
4921 return 0;
4922 size = PyBytes_GET_SIZE(bytes);
4923 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004924 if (!*out) {
4925 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004927 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 memcpy(*out, PyBytes_AsString(bytes), size+1);
4929 Py_DECREF(bytes);
4930 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004931}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004932#endif
4933
Ross Lagerwall7807c352011-03-17 20:20:30 +02004934#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004935static char**
4936parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4937{
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 char **envlist;
4939 Py_ssize_t i, pos, envc;
4940 PyObject *keys=NULL, *vals=NULL;
4941 PyObject *key, *val, *key2, *val2;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03004942 char *p;
4943 const char *k, *v;
Victor Stinner8c62be82010-05-06 00:08:46 +00004944 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004945
Victor Stinner8c62be82010-05-06 00:08:46 +00004946 i = PyMapping_Size(env);
4947 if (i < 0)
4948 return NULL;
4949 envlist = PyMem_NEW(char *, i + 1);
4950 if (envlist == NULL) {
4951 PyErr_NoMemory();
4952 return NULL;
4953 }
4954 envc = 0;
4955 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004956 if (!keys)
4957 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004958 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004959 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 goto error;
4961 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4962 PyErr_Format(PyExc_TypeError,
4963 "env.keys() or env.values() is not a list");
4964 goto error;
4965 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004966
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 for (pos = 0; pos < i; pos++) {
4968 key = PyList_GetItem(keys, pos);
4969 val = PyList_GetItem(vals, pos);
4970 if (!key || !val)
4971 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004972
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 if (PyUnicode_FSConverter(key, &key2) == 0)
4974 goto error;
4975 if (PyUnicode_FSConverter(val, &val2) == 0) {
4976 Py_DECREF(key2);
4977 goto error;
4978 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004979
Victor Stinner8c62be82010-05-06 00:08:46 +00004980 k = PyBytes_AsString(key2);
4981 v = PyBytes_AsString(val2);
4982 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004983
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 p = PyMem_NEW(char, len);
4985 if (p == NULL) {
4986 PyErr_NoMemory();
4987 Py_DECREF(key2);
4988 Py_DECREF(val2);
4989 goto error;
4990 }
4991 PyOS_snprintf(p, len, "%s=%s", k, v);
4992 envlist[envc++] = p;
4993 Py_DECREF(key2);
4994 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004995 }
4996 Py_DECREF(vals);
4997 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004998
Victor Stinner8c62be82010-05-06 00:08:46 +00004999 envlist[envc] = 0;
5000 *envc_ptr = envc;
5001 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005002
5003error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005004 Py_XDECREF(keys);
5005 Py_XDECREF(vals);
5006 while (--envc >= 0)
5007 PyMem_DEL(envlist[envc]);
5008 PyMem_DEL(envlist);
5009 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005010}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005011
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012static char**
5013parse_arglist(PyObject* argv, Py_ssize_t *argc)
5014{
5015 int i;
5016 char **argvlist = PyMem_NEW(char *, *argc+1);
5017 if (argvlist == NULL) {
5018 PyErr_NoMemory();
5019 return NULL;
5020 }
5021 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005022 PyObject* item = PySequence_ITEM(argv, i);
5023 if (item == NULL)
5024 goto fail;
5025 if (!fsconvert_strdup(item, &argvlist[i])) {
5026 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027 goto fail;
5028 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005029 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030 }
5031 argvlist[*argc] = NULL;
5032 return argvlist;
5033fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005034 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005035 free_string_array(argvlist, *argc);
5036 return NULL;
5037}
5038#endif
5039
Larry Hastings2f936352014-08-05 14:04:04 +10005040
Ross Lagerwall7807c352011-03-17 20:20:30 +02005041#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005042/*[clinic input]
5043os.execv
5044
5045 path: FSConverter
5046 Path of executable file.
5047 argv: object
5048 Tuple or list of strings.
5049 /
5050
5051Execute an executable path with arguments, replacing current process.
5052[clinic start generated code]*/
5053
Larry Hastings2f936352014-08-05 14:04:04 +10005054static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005055os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5056/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005057{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005058 const char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 char **argvlist;
5060 Py_ssize_t argc;
5061
5062 /* execv has two arguments: (path, argv), where
5063 argv is a list or tuple of strings. */
5064
Larry Hastings2f936352014-08-05 14:04:04 +10005065 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5067 PyErr_SetString(PyExc_TypeError,
5068 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005069 return NULL;
5070 }
5071 argc = PySequence_Size(argv);
5072 if (argc < 1) {
5073 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074 return NULL;
5075 }
5076
5077 argvlist = parse_arglist(argv, &argc);
5078 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005079 return NULL;
5080 }
5081
Larry Hastings2f936352014-08-05 14:04:04 +10005082 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005083
5084 /* If we get here it's definitely an error */
5085
5086 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005087 return posix_error();
5088}
5089
Larry Hastings2f936352014-08-05 14:04:04 +10005090
5091/*[clinic input]
5092os.execve
5093
5094 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5095 Path of executable file.
5096 argv: object
5097 Tuple or list of strings.
5098 env: object
5099 Dictionary of strings mapping to strings.
5100
5101Execute an executable path with arguments, replacing current process.
5102[clinic start generated code]*/
5103
Larry Hastings2f936352014-08-05 14:04:04 +10005104static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005105os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5106/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005107{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005108 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005111
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 /* execve has three arguments: (path, argv, env), where
5113 argv is a list or tuple of strings and env is a dictionary
5114 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005115
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005118 "execve: argv must be a tuple or list");
5119 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005121 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 if (!PyMapping_Check(env)) {
5123 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124 "execve: environment must be a mapping object");
5125 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005126 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005127
Ross Lagerwall7807c352011-03-17 20:20:30 +02005128 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005130 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005132
Victor Stinner8c62be82010-05-06 00:08:46 +00005133 envlist = parse_envlist(env, &envc);
5134 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005135 goto fail;
5136
Larry Hastings9cf065c2012-06-22 16:30:09 -07005137#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005138 if (path->fd > -1)
5139 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005140 else
5141#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005142 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005143
5144 /* If we get here it's definitely an error */
5145
Larry Hastings2f936352014-08-05 14:04:04 +10005146 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005147
5148 while (--envc >= 0)
5149 PyMem_DEL(envlist[envc]);
5150 PyMem_DEL(envlist);
5151 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005152 if (argvlist)
5153 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005154 return NULL;
5155}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005156#endif /* HAVE_EXECV */
5157
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005158
Guido van Rossuma1065681999-01-25 23:20:23 +00005159#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005160/*[clinic input]
5161os.spawnv
5162
5163 mode: int
5164 Mode of process creation.
5165 path: FSConverter
5166 Path of executable file.
5167 argv: object
5168 Tuple or list of strings.
5169 /
5170
5171Execute the program specified by path in a new process.
5172[clinic start generated code]*/
5173
Larry Hastings2f936352014-08-05 14:04:04 +10005174static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005175os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5176/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005177{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005178 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005179 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005180 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 Py_ssize_t argc;
5182 Py_intptr_t spawnval;
5183 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005184
Victor Stinner8c62be82010-05-06 00:08:46 +00005185 /* spawnv has three arguments: (mode, path, argv), where
5186 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005187
Larry Hastings2f936352014-08-05 14:04:04 +10005188 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 if (PyList_Check(argv)) {
5190 argc = PyList_Size(argv);
5191 getitem = PyList_GetItem;
5192 }
5193 else if (PyTuple_Check(argv)) {
5194 argc = PyTuple_Size(argv);
5195 getitem = PyTuple_GetItem;
5196 }
5197 else {
5198 PyErr_SetString(PyExc_TypeError,
5199 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 return NULL;
5201 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 argvlist = PyMem_NEW(char *, argc+1);
5204 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 return PyErr_NoMemory();
5206 }
5207 for (i = 0; i < argc; i++) {
5208 if (!fsconvert_strdup((*getitem)(argv, i),
5209 &argvlist[i])) {
5210 free_string_array(argvlist, i);
5211 PyErr_SetString(
5212 PyExc_TypeError,
5213 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 return NULL;
5215 }
5216 }
5217 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005218
Victor Stinner8c62be82010-05-06 00:08:46 +00005219 if (mode == _OLD_P_OVERLAY)
5220 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005221
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005223 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005225
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 if (spawnval == -1)
5229 return posix_error();
5230 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005231 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005232}
5233
5234
Larry Hastings2f936352014-08-05 14:04:04 +10005235/*[clinic input]
5236os.spawnve
5237
5238 mode: int
5239 Mode of process creation.
5240 path: FSConverter
5241 Path of executable file.
5242 argv: object
5243 Tuple or list of strings.
5244 env: object
5245 Dictionary of strings mapping to strings.
5246 /
5247
5248Execute the program specified by path in a new process.
5249[clinic start generated code]*/
5250
Larry Hastings2f936352014-08-05 14:04:04 +10005251static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005252os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5253 PyObject *env)
5254/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005255{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03005256 const char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 char **argvlist;
5258 char **envlist;
5259 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005260 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005261 Py_intptr_t spawnval;
5262 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5263 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005264
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 /* spawnve has four arguments: (mode, path, argv, env), where
5266 argv is a list or tuple of strings and env is a dictionary
5267 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005268
Larry Hastings2f936352014-08-05 14:04:04 +10005269 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 if (PyList_Check(argv)) {
5271 argc = PyList_Size(argv);
5272 getitem = PyList_GetItem;
5273 }
5274 else if (PyTuple_Check(argv)) {
5275 argc = PyTuple_Size(argv);
5276 getitem = PyTuple_GetItem;
5277 }
5278 else {
5279 PyErr_SetString(PyExc_TypeError,
5280 "spawnve() arg 2 must be a tuple or list");
5281 goto fail_0;
5282 }
5283 if (!PyMapping_Check(env)) {
5284 PyErr_SetString(PyExc_TypeError,
5285 "spawnve() arg 3 must be a mapping object");
5286 goto fail_0;
5287 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005288
Victor Stinner8c62be82010-05-06 00:08:46 +00005289 argvlist = PyMem_NEW(char *, argc+1);
5290 if (argvlist == NULL) {
5291 PyErr_NoMemory();
5292 goto fail_0;
5293 }
5294 for (i = 0; i < argc; i++) {
5295 if (!fsconvert_strdup((*getitem)(argv, i),
5296 &argvlist[i]))
5297 {
5298 lastarg = i;
5299 goto fail_1;
5300 }
5301 }
5302 lastarg = argc;
5303 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005304
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 envlist = parse_envlist(env, &envc);
5306 if (envlist == NULL)
5307 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 if (mode == _OLD_P_OVERLAY)
5310 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005311
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005313 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005315
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 if (spawnval == -1)
5317 (void) posix_error();
5318 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005319 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005320
Victor Stinner8c62be82010-05-06 00:08:46 +00005321 while (--envc >= 0)
5322 PyMem_DEL(envlist[envc]);
5323 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005324 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005326 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005328}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005329
Guido van Rossuma1065681999-01-25 23:20:23 +00005330#endif /* HAVE_SPAWNV */
5331
5332
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005333#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005334/*[clinic input]
5335os.fork1
5336
5337Fork a child process with a single multiplexed (i.e., not bound) thread.
5338
5339Return 0 to child process and PID of child to parent process.
5340[clinic start generated code]*/
5341
Larry Hastings2f936352014-08-05 14:04:04 +10005342static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005343os_fork1_impl(PyObject *module)
5344/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005345{
Victor Stinner8c62be82010-05-06 00:08:46 +00005346 pid_t pid;
5347 int result = 0;
5348 _PyImport_AcquireLock();
5349 pid = fork1();
5350 if (pid == 0) {
5351 /* child: this clobbers and resets the import lock. */
5352 PyOS_AfterFork();
5353 } else {
5354 /* parent: release the import lock. */
5355 result = _PyImport_ReleaseLock();
5356 }
5357 if (pid == -1)
5358 return posix_error();
5359 if (result < 0) {
5360 /* Don't clobber the OSError if the fork failed. */
5361 PyErr_SetString(PyExc_RuntimeError,
5362 "not holding the import lock");
5363 return NULL;
5364 }
5365 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005366}
Larry Hastings2f936352014-08-05 14:04:04 +10005367#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005368
5369
Guido van Rossumad0ee831995-03-01 10:34:45 +00005370#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005371/*[clinic input]
5372os.fork
5373
5374Fork a child process.
5375
5376Return 0 to child process and PID of child to parent process.
5377[clinic start generated code]*/
5378
Larry Hastings2f936352014-08-05 14:04:04 +10005379static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005380os_fork_impl(PyObject *module)
5381/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005382{
Victor Stinner8c62be82010-05-06 00:08:46 +00005383 pid_t pid;
5384 int result = 0;
5385 _PyImport_AcquireLock();
5386 pid = fork();
5387 if (pid == 0) {
5388 /* child: this clobbers and resets the import lock. */
5389 PyOS_AfterFork();
5390 } else {
5391 /* parent: release the import lock. */
5392 result = _PyImport_ReleaseLock();
5393 }
5394 if (pid == -1)
5395 return posix_error();
5396 if (result < 0) {
5397 /* Don't clobber the OSError if the fork failed. */
5398 PyErr_SetString(PyExc_RuntimeError,
5399 "not holding the import lock");
5400 return NULL;
5401 }
5402 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005403}
Larry Hastings2f936352014-08-05 14:04:04 +10005404#endif /* HAVE_FORK */
5405
Guido van Rossum85e3b011991-06-03 12:42:10 +00005406
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005407#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005408#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005409/*[clinic input]
5410os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005411
Larry Hastings2f936352014-08-05 14:04:04 +10005412 policy: int
5413
5414Get the maximum scheduling priority for policy.
5415[clinic start generated code]*/
5416
Larry Hastings2f936352014-08-05 14:04:04 +10005417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005418os_sched_get_priority_max_impl(PyObject *module, int policy)
5419/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005420{
5421 int max;
5422
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005423 max = sched_get_priority_max(policy);
5424 if (max < 0)
5425 return posix_error();
5426 return PyLong_FromLong(max);
5427}
5428
Larry Hastings2f936352014-08-05 14:04:04 +10005429
5430/*[clinic input]
5431os.sched_get_priority_min
5432
5433 policy: int
5434
5435Get the minimum scheduling priority for policy.
5436[clinic start generated code]*/
5437
Larry Hastings2f936352014-08-05 14:04:04 +10005438static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005439os_sched_get_priority_min_impl(PyObject *module, int policy)
5440/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005441{
5442 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005443 if (min < 0)
5444 return posix_error();
5445 return PyLong_FromLong(min);
5446}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005447#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5448
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005449
Larry Hastings2f936352014-08-05 14:04:04 +10005450#ifdef HAVE_SCHED_SETSCHEDULER
5451/*[clinic input]
5452os.sched_getscheduler
5453 pid: pid_t
5454 /
5455
5456Get the scheduling policy for the process identifiedy by pid.
5457
5458Passing 0 for pid returns the scheduling policy for the calling process.
5459[clinic start generated code]*/
5460
Larry Hastings2f936352014-08-05 14:04:04 +10005461static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005462os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5463/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005464{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465 int policy;
5466
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005467 policy = sched_getscheduler(pid);
5468 if (policy < 0)
5469 return posix_error();
5470 return PyLong_FromLong(policy);
5471}
Larry Hastings2f936352014-08-05 14:04:04 +10005472#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005473
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005474
5475#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005476/*[clinic input]
5477class os.sched_param "PyObject *" "&SchedParamType"
5478
5479@classmethod
5480os.sched_param.__new__
5481
5482 sched_priority: object
5483 A scheduling parameter.
5484
5485Current has only one field: sched_priority");
5486[clinic start generated code]*/
5487
Larry Hastings2f936352014-08-05 14:04:04 +10005488static PyObject *
5489os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005490/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005491{
5492 PyObject *res;
5493
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005494 res = PyStructSequence_New(type);
5495 if (!res)
5496 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005497 Py_INCREF(sched_priority);
5498 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005499 return res;
5500}
5501
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005502
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005503PyDoc_VAR(os_sched_param__doc__);
5504
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005505static PyStructSequence_Field sched_param_fields[] = {
5506 {"sched_priority", "the scheduling priority"},
5507 {0}
5508};
5509
5510static PyStructSequence_Desc sched_param_desc = {
5511 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005512 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005513 sched_param_fields,
5514 1
5515};
5516
5517static int
5518convert_sched_param(PyObject *param, struct sched_param *res)
5519{
5520 long priority;
5521
5522 if (Py_TYPE(param) != &SchedParamType) {
5523 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5524 return 0;
5525 }
5526 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5527 if (priority == -1 && PyErr_Occurred())
5528 return 0;
5529 if (priority > INT_MAX || priority < INT_MIN) {
5530 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5531 return 0;
5532 }
5533 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5534 return 1;
5535}
Larry Hastings2f936352014-08-05 14:04:04 +10005536#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005537
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005538
5539#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005540/*[clinic input]
5541os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005542
Larry Hastings2f936352014-08-05 14:04:04 +10005543 pid: pid_t
5544 policy: int
5545 param: sched_param
5546 /
5547
5548Set the scheduling policy for the process identified by pid.
5549
5550If pid is 0, the calling process is changed.
5551param is an instance of sched_param.
5552[clinic start generated code]*/
5553
Larry Hastings2f936352014-08-05 14:04:04 +10005554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005555os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005556 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005557/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005558{
Jesus Cea9c822272011-09-10 01:40:52 +02005559 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005560 ** sched_setscheduler() returns 0 in Linux, but the previous
5561 ** scheduling policy under Solaris/Illumos, and others.
5562 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005563 */
Larry Hastings2f936352014-08-05 14:04:04 +10005564 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005565 return posix_error();
5566 Py_RETURN_NONE;
5567}
Larry Hastings2f936352014-08-05 14:04:04 +10005568#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005569
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005570
5571#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005572/*[clinic input]
5573os.sched_getparam
5574 pid: pid_t
5575 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005576
Larry Hastings2f936352014-08-05 14:04:04 +10005577Returns scheduling parameters for the process identified by pid.
5578
5579If pid is 0, returns parameters for the calling process.
5580Return value is an instance of sched_param.
5581[clinic start generated code]*/
5582
Larry Hastings2f936352014-08-05 14:04:04 +10005583static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005584os_sched_getparam_impl(PyObject *module, pid_t pid)
5585/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005586{
5587 struct sched_param param;
5588 PyObject *result;
5589 PyObject *priority;
5590
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005591 if (sched_getparam(pid, &param))
5592 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005593 result = PyStructSequence_New(&SchedParamType);
5594 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005595 return NULL;
5596 priority = PyLong_FromLong(param.sched_priority);
5597 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005598 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005599 return NULL;
5600 }
Larry Hastings2f936352014-08-05 14:04:04 +10005601 PyStructSequence_SET_ITEM(result, 0, priority);
5602 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005603}
5604
Larry Hastings2f936352014-08-05 14:04:04 +10005605
5606/*[clinic input]
5607os.sched_setparam
5608 pid: pid_t
5609 param: sched_param
5610 /
5611
5612Set scheduling parameters for the process identified by pid.
5613
5614If pid is 0, sets parameters for the calling process.
5615param should be an instance of sched_param.
5616[clinic start generated code]*/
5617
Larry Hastings2f936352014-08-05 14:04:04 +10005618static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005619os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005620 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005621/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005622{
5623 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005624 return posix_error();
5625 Py_RETURN_NONE;
5626}
Larry Hastings2f936352014-08-05 14:04:04 +10005627#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005628
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005629
5630#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005631/*[clinic input]
5632os.sched_rr_get_interval -> double
5633 pid: pid_t
5634 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005635
Larry Hastings2f936352014-08-05 14:04:04 +10005636Return the round-robin quantum for the process identified by pid, in seconds.
5637
5638Value returned is a float.
5639[clinic start generated code]*/
5640
Larry Hastings2f936352014-08-05 14:04:04 +10005641static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005642os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5643/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005644{
5645 struct timespec interval;
5646 if (sched_rr_get_interval(pid, &interval)) {
5647 posix_error();
5648 return -1.0;
5649 }
5650 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5651}
5652#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005653
Larry Hastings2f936352014-08-05 14:04:04 +10005654
5655/*[clinic input]
5656os.sched_yield
5657
5658Voluntarily relinquish the CPU.
5659[clinic start generated code]*/
5660
Larry Hastings2f936352014-08-05 14:04:04 +10005661static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005662os_sched_yield_impl(PyObject *module)
5663/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005664{
5665 if (sched_yield())
5666 return posix_error();
5667 Py_RETURN_NONE;
5668}
5669
Benjamin Peterson2740af82011-08-02 17:41:34 -05005670#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005671/* The minimum number of CPUs allocated in a cpu_set_t */
5672static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005673
Larry Hastings2f936352014-08-05 14:04:04 +10005674/*[clinic input]
5675os.sched_setaffinity
5676 pid: pid_t
5677 mask : object
5678 /
5679
5680Set the CPU affinity of the process identified by pid to mask.
5681
5682mask should be an iterable of integers identifying CPUs.
5683[clinic start generated code]*/
5684
Larry Hastings2f936352014-08-05 14:04:04 +10005685static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005686os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5687/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005688{
Antoine Pitrou84869872012-08-04 16:16:35 +02005689 int ncpus;
5690 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005691 cpu_set_t *cpu_set = NULL;
5692 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005693
Larry Hastings2f936352014-08-05 14:04:04 +10005694 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005695 if (iterator == NULL)
5696 return NULL;
5697
5698 ncpus = NCPUS_START;
5699 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005700 cpu_set = CPU_ALLOC(ncpus);
5701 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005702 PyErr_NoMemory();
5703 goto error;
5704 }
Larry Hastings2f936352014-08-05 14:04:04 +10005705 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005706
5707 while ((item = PyIter_Next(iterator))) {
5708 long cpu;
5709 if (!PyLong_Check(item)) {
5710 PyErr_Format(PyExc_TypeError,
5711 "expected an iterator of ints, "
5712 "but iterator yielded %R",
5713 Py_TYPE(item));
5714 Py_DECREF(item);
5715 goto error;
5716 }
5717 cpu = PyLong_AsLong(item);
5718 Py_DECREF(item);
5719 if (cpu < 0) {
5720 if (!PyErr_Occurred())
5721 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5722 goto error;
5723 }
5724 if (cpu > INT_MAX - 1) {
5725 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5726 goto error;
5727 }
5728 if (cpu >= ncpus) {
5729 /* Grow CPU mask to fit the CPU number */
5730 int newncpus = ncpus;
5731 cpu_set_t *newmask;
5732 size_t newsetsize;
5733 while (newncpus <= cpu) {
5734 if (newncpus > INT_MAX / 2)
5735 newncpus = cpu + 1;
5736 else
5737 newncpus = newncpus * 2;
5738 }
5739 newmask = CPU_ALLOC(newncpus);
5740 if (newmask == NULL) {
5741 PyErr_NoMemory();
5742 goto error;
5743 }
5744 newsetsize = CPU_ALLOC_SIZE(newncpus);
5745 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005746 memcpy(newmask, cpu_set, setsize);
5747 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005748 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005749 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005750 ncpus = newncpus;
5751 }
Larry Hastings2f936352014-08-05 14:04:04 +10005752 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005753 }
5754 Py_CLEAR(iterator);
5755
Larry Hastings2f936352014-08-05 14:04:04 +10005756 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005757 posix_error();
5758 goto error;
5759 }
Larry Hastings2f936352014-08-05 14:04:04 +10005760 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005761 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005762
5763error:
Larry Hastings2f936352014-08-05 14:04:04 +10005764 if (cpu_set)
5765 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005766 Py_XDECREF(iterator);
5767 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005768}
5769
Larry Hastings2f936352014-08-05 14:04:04 +10005770
5771/*[clinic input]
5772os.sched_getaffinity
5773 pid: pid_t
5774 /
5775
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005776Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005777
5778The affinity is returned as a set of CPU identifiers.
5779[clinic start generated code]*/
5780
Larry Hastings2f936352014-08-05 14:04:04 +10005781static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005782os_sched_getaffinity_impl(PyObject *module, pid_t pid)
Serhiy Storchaka2954f832016-07-07 18:20:03 +03005783/*[clinic end generated code: output=f726f2c193c17a4f input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005784{
Antoine Pitrou84869872012-08-04 16:16:35 +02005785 int cpu, ncpus, count;
5786 size_t setsize;
5787 cpu_set_t *mask = NULL;
5788 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005789
Antoine Pitrou84869872012-08-04 16:16:35 +02005790 ncpus = NCPUS_START;
5791 while (1) {
5792 setsize = CPU_ALLOC_SIZE(ncpus);
5793 mask = CPU_ALLOC(ncpus);
5794 if (mask == NULL)
5795 return PyErr_NoMemory();
5796 if (sched_getaffinity(pid, setsize, mask) == 0)
5797 break;
5798 CPU_FREE(mask);
5799 if (errno != EINVAL)
5800 return posix_error();
5801 if (ncpus > INT_MAX / 2) {
5802 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5803 "a large enough CPU set");
5804 return NULL;
5805 }
5806 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005807 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005808
5809 res = PySet_New(NULL);
5810 if (res == NULL)
5811 goto error;
5812 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5813 if (CPU_ISSET_S(cpu, setsize, mask)) {
5814 PyObject *cpu_num = PyLong_FromLong(cpu);
5815 --count;
5816 if (cpu_num == NULL)
5817 goto error;
5818 if (PySet_Add(res, cpu_num)) {
5819 Py_DECREF(cpu_num);
5820 goto error;
5821 }
5822 Py_DECREF(cpu_num);
5823 }
5824 }
5825 CPU_FREE(mask);
5826 return res;
5827
5828error:
5829 if (mask)
5830 CPU_FREE(mask);
5831 Py_XDECREF(res);
5832 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005833}
5834
Benjamin Peterson2740af82011-08-02 17:41:34 -05005835#endif /* HAVE_SCHED_SETAFFINITY */
5836
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005837#endif /* HAVE_SCHED_H */
5838
Larry Hastings2f936352014-08-05 14:04:04 +10005839
Neal Norwitzb59798b2003-03-21 01:43:31 +00005840/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005841/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5842#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005843#define DEV_PTY_FILE "/dev/ptc"
5844#define HAVE_DEV_PTMX
5845#else
5846#define DEV_PTY_FILE "/dev/ptmx"
5847#endif
5848
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005849#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005850#ifdef HAVE_PTY_H
5851#include <pty.h>
5852#else
5853#ifdef HAVE_LIBUTIL_H
5854#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005855#else
5856#ifdef HAVE_UTIL_H
5857#include <util.h>
5858#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005859#endif /* HAVE_LIBUTIL_H */
5860#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005861#ifdef HAVE_STROPTS_H
5862#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005863#endif
5864#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005865
Larry Hastings2f936352014-08-05 14:04:04 +10005866
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005867#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005868/*[clinic input]
5869os.openpty
5870
5871Open a pseudo-terminal.
5872
5873Return a tuple of (master_fd, slave_fd) containing open file descriptors
5874for both the master and slave ends.
5875[clinic start generated code]*/
5876
Larry Hastings2f936352014-08-05 14:04:04 +10005877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005878os_openpty_impl(PyObject *module)
5879/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005880{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005881 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005882#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005884#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005885#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005887#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005888 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005889#endif
5890#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005891
Thomas Wouters70c21a12000-07-14 14:28:33 +00005892#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005893 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005894 goto posix_error;
5895
5896 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5897 goto error;
5898 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5899 goto error;
5900
Neal Norwitzb59798b2003-03-21 01:43:31 +00005901#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5903 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005904 goto posix_error;
5905 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5906 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005907
Victor Stinnerdaf45552013-08-28 00:53:59 +02005908 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005909 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005910 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005912#else
Victor Stinner000de532013-11-25 23:19:58 +01005913 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915 goto posix_error;
5916
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005918
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 /* change permission of slave */
5920 if (grantpt(master_fd) < 0) {
5921 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005922 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005924
Victor Stinner8c62be82010-05-06 00:08:46 +00005925 /* unlock slave */
5926 if (unlockpt(master_fd) < 0) {
5927 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005928 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005930
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005932
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 slave_name = ptsname(master_fd); /* get name of slave */
5934 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005935 goto posix_error;
5936
5937 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005938 if (slave_fd == -1)
5939 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005940
5941 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5942 goto posix_error;
5943
Stefan Krahfb7c8ae2016-04-26 17:04:18 +02005944#if !defined(__CYGWIN__) && !defined(__ANDROID__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005945 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5946 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005947#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005948 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005949#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005950#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005951#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005952
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005954
Victor Stinnerdaf45552013-08-28 00:53:59 +02005955posix_error:
5956 posix_error();
5957error:
5958 if (master_fd != -1)
5959 close(master_fd);
5960 if (slave_fd != -1)
5961 close(slave_fd);
5962 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005963}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005964#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005965
Larry Hastings2f936352014-08-05 14:04:04 +10005966
Fred Drake8cef4cf2000-06-28 16:40:38 +00005967#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005968/*[clinic input]
5969os.forkpty
5970
5971Fork a new process with a new pseudo-terminal as controlling tty.
5972
5973Returns a tuple of (pid, master_fd).
5974Like fork(), return pid of 0 to the child process,
5975and pid of child to the parent process.
5976To both, return fd of newly opened pseudo-terminal.
5977[clinic start generated code]*/
5978
Larry Hastings2f936352014-08-05 14:04:04 +10005979static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005980os_forkpty_impl(PyObject *module)
5981/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005982{
Victor Stinner8c62be82010-05-06 00:08:46 +00005983 int master_fd = -1, result = 0;
5984 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005985
Victor Stinner8c62be82010-05-06 00:08:46 +00005986 _PyImport_AcquireLock();
5987 pid = forkpty(&master_fd, NULL, NULL, NULL);
5988 if (pid == 0) {
5989 /* child: this clobbers and resets the import lock. */
5990 PyOS_AfterFork();
5991 } else {
5992 /* parent: release the import lock. */
5993 result = _PyImport_ReleaseLock();
5994 }
5995 if (pid == -1)
5996 return posix_error();
5997 if (result < 0) {
5998 /* Don't clobber the OSError if the fork failed. */
5999 PyErr_SetString(PyExc_RuntimeError,
6000 "not holding the import lock");
6001 return NULL;
6002 }
6003 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006004}
Larry Hastings2f936352014-08-05 14:04:04 +10006005#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006006
Ross Lagerwall7807c352011-03-17 20:20:30 +02006007
Guido van Rossumad0ee831995-03-01 10:34:45 +00006008#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006009/*[clinic input]
6010os.getegid
6011
6012Return the current process's effective group id.
6013[clinic start generated code]*/
6014
Larry Hastings2f936352014-08-05 14:04:04 +10006015static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006016os_getegid_impl(PyObject *module)
6017/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006018{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006019 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006020}
Larry Hastings2f936352014-08-05 14:04:04 +10006021#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006022
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006023
Guido van Rossumad0ee831995-03-01 10:34:45 +00006024#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006025/*[clinic input]
6026os.geteuid
6027
6028Return the current process's effective user id.
6029[clinic start generated code]*/
6030
Larry Hastings2f936352014-08-05 14:04:04 +10006031static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006032os_geteuid_impl(PyObject *module)
6033/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006034{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006035 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006036}
Larry Hastings2f936352014-08-05 14:04:04 +10006037#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006038
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006039
Guido van Rossumad0ee831995-03-01 10:34:45 +00006040#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006041/*[clinic input]
6042os.getgid
6043
6044Return the current process's group id.
6045[clinic start generated code]*/
6046
Larry Hastings2f936352014-08-05 14:04:04 +10006047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006048os_getgid_impl(PyObject *module)
6049/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006050{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006051 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006052}
Larry Hastings2f936352014-08-05 14:04:04 +10006053#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006054
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006055
Larry Hastings2f936352014-08-05 14:04:04 +10006056/*[clinic input]
6057os.getpid
6058
6059Return the current process id.
6060[clinic start generated code]*/
6061
Larry Hastings2f936352014-08-05 14:04:04 +10006062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006063os_getpid_impl(PyObject *module)
6064/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006065{
Victor Stinner8c62be82010-05-06 00:08:46 +00006066 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006067}
6068
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006069#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006070
6071/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006072PyDoc_STRVAR(posix_getgrouplist__doc__,
6073"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6074Returns a list of groups to which a user belongs.\n\n\
6075 user: username to lookup\n\
6076 group: base group id of the user");
6077
6078static PyObject *
6079posix_getgrouplist(PyObject *self, PyObject *args)
6080{
6081#ifdef NGROUPS_MAX
6082#define MAX_GROUPS NGROUPS_MAX
6083#else
6084 /* defined to be 16 on Solaris7, so this should be a small number */
6085#define MAX_GROUPS 64
6086#endif
6087
6088 const char *user;
6089 int i, ngroups;
6090 PyObject *list;
6091#ifdef __APPLE__
6092 int *groups, basegid;
6093#else
6094 gid_t *groups, basegid;
6095#endif
6096 ngroups = MAX_GROUPS;
6097
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006098#ifdef __APPLE__
6099 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006100 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006101#else
6102 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6103 _Py_Gid_Converter, &basegid))
6104 return NULL;
6105#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006106
6107#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006108 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006109#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006110 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006111#endif
6112 if (groups == NULL)
6113 return PyErr_NoMemory();
6114
6115 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6116 PyMem_Del(groups);
6117 return posix_error();
6118 }
6119
6120 list = PyList_New(ngroups);
6121 if (list == NULL) {
6122 PyMem_Del(groups);
6123 return NULL;
6124 }
6125
6126 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006127#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006128 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006129#else
6130 PyObject *o = _PyLong_FromGid(groups[i]);
6131#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006132 if (o == NULL) {
6133 Py_DECREF(list);
6134 PyMem_Del(groups);
6135 return NULL;
6136 }
6137 PyList_SET_ITEM(list, i, o);
6138 }
6139
6140 PyMem_Del(groups);
6141
6142 return list;
6143}
Larry Hastings2f936352014-08-05 14:04:04 +10006144#endif /* HAVE_GETGROUPLIST */
6145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006146
Fred Drakec9680921999-12-13 16:37:25 +00006147#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006148/*[clinic input]
6149os.getgroups
6150
6151Return list of supplemental group IDs for the process.
6152[clinic start generated code]*/
6153
Larry Hastings2f936352014-08-05 14:04:04 +10006154static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006155os_getgroups_impl(PyObject *module)
6156/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006157{
6158 PyObject *result = NULL;
6159
Fred Drakec9680921999-12-13 16:37:25 +00006160#ifdef NGROUPS_MAX
6161#define MAX_GROUPS NGROUPS_MAX
6162#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006163 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006164#define MAX_GROUPS 64
6165#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006167
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006168 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006169 * This is a helper variable to store the intermediate result when
6170 * that happens.
6171 *
6172 * To keep the code readable the OSX behaviour is unconditional,
6173 * according to the POSIX spec this should be safe on all unix-y
6174 * systems.
6175 */
6176 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006177 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006178
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006179#ifdef __APPLE__
6180 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6181 * there are more groups than can fit in grouplist. Therefore, on OS X
6182 * always first call getgroups with length 0 to get the actual number
6183 * of groups.
6184 */
6185 n = getgroups(0, NULL);
6186 if (n < 0) {
6187 return posix_error();
6188 } else if (n <= MAX_GROUPS) {
6189 /* groups will fit in existing array */
6190 alt_grouplist = grouplist;
6191 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006192 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006193 if (alt_grouplist == NULL) {
6194 errno = EINVAL;
6195 return posix_error();
6196 }
6197 }
6198
6199 n = getgroups(n, alt_grouplist);
6200 if (n == -1) {
6201 if (alt_grouplist != grouplist) {
6202 PyMem_Free(alt_grouplist);
6203 }
6204 return posix_error();
6205 }
6206#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006208 if (n < 0) {
6209 if (errno == EINVAL) {
6210 n = getgroups(0, NULL);
6211 if (n == -1) {
6212 return posix_error();
6213 }
6214 if (n == 0) {
6215 /* Avoid malloc(0) */
6216 alt_grouplist = grouplist;
6217 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006218 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006219 if (alt_grouplist == NULL) {
6220 errno = EINVAL;
6221 return posix_error();
6222 }
6223 n = getgroups(n, alt_grouplist);
6224 if (n == -1) {
6225 PyMem_Free(alt_grouplist);
6226 return posix_error();
6227 }
6228 }
6229 } else {
6230 return posix_error();
6231 }
6232 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006233#endif
6234
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006235 result = PyList_New(n);
6236 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006237 int i;
6238 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006239 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006241 Py_DECREF(result);
6242 result = NULL;
6243 break;
Fred Drakec9680921999-12-13 16:37:25 +00006244 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006245 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006246 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006247 }
6248
6249 if (alt_grouplist != grouplist) {
6250 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006251 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006252
Fred Drakec9680921999-12-13 16:37:25 +00006253 return result;
6254}
Larry Hastings2f936352014-08-05 14:04:04 +10006255#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006256
Antoine Pitroub7572f02009-12-02 20:46:48 +00006257#ifdef HAVE_INITGROUPS
6258PyDoc_STRVAR(posix_initgroups__doc__,
6259"initgroups(username, gid) -> None\n\n\
6260Call the system initgroups() to initialize the group access list with all of\n\
6261the groups of which the specified username is a member, plus the specified\n\
6262group id.");
6263
Larry Hastings2f936352014-08-05 14:04:04 +10006264/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006265static PyObject *
6266posix_initgroups(PyObject *self, PyObject *args)
6267{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006268 PyObject *oname;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03006269 const char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006270 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006271#ifdef __APPLE__
6272 int gid;
6273#else
6274 gid_t gid;
6275#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006276
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006277#ifdef __APPLE__
6278 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6279 PyUnicode_FSConverter, &oname,
6280 &gid))
6281#else
6282 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6283 PyUnicode_FSConverter, &oname,
6284 _Py_Gid_Converter, &gid))
6285#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006286 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006287 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006288
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006289 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006290 Py_DECREF(oname);
6291 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006293
Victor Stinner8c62be82010-05-06 00:08:46 +00006294 Py_INCREF(Py_None);
6295 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006296}
Larry Hastings2f936352014-08-05 14:04:04 +10006297#endif /* HAVE_INITGROUPS */
6298
Antoine Pitroub7572f02009-12-02 20:46:48 +00006299
Martin v. Löwis606edc12002-06-13 21:09:11 +00006300#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006301/*[clinic input]
6302os.getpgid
6303
6304 pid: pid_t
6305
6306Call the system call getpgid(), and return the result.
6307[clinic start generated code]*/
6308
Larry Hastings2f936352014-08-05 14:04:04 +10006309static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006310os_getpgid_impl(PyObject *module, pid_t pid)
6311/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006312{
6313 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 if (pgid < 0)
6315 return posix_error();
6316 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006317}
6318#endif /* HAVE_GETPGID */
6319
6320
Guido van Rossumb6775db1994-08-01 11:34:53 +00006321#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006322/*[clinic input]
6323os.getpgrp
6324
6325Return the current process group id.
6326[clinic start generated code]*/
6327
Larry Hastings2f936352014-08-05 14:04:04 +10006328static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006329os_getpgrp_impl(PyObject *module)
6330/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006331{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006332#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006333 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006334#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006335 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006336#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006337}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006338#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006339
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006340
Guido van Rossumb6775db1994-08-01 11:34:53 +00006341#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006342/*[clinic input]
6343os.setpgrp
6344
6345Make the current process the leader of its process group.
6346[clinic start generated code]*/
6347
Larry Hastings2f936352014-08-05 14:04:04 +10006348static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006349os_setpgrp_impl(PyObject *module)
6350/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006351{
Guido van Rossum64933891994-10-20 21:56:42 +00006352#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006354#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006356#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006357 return posix_error();
6358 Py_INCREF(Py_None);
6359 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006360}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006361#endif /* HAVE_SETPGRP */
6362
Guido van Rossumad0ee831995-03-01 10:34:45 +00006363#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006364
6365#ifdef MS_WINDOWS
6366#include <tlhelp32.h>
6367
6368static PyObject*
6369win32_getppid()
6370{
6371 HANDLE snapshot;
6372 pid_t mypid;
6373 PyObject* result = NULL;
6374 BOOL have_record;
6375 PROCESSENTRY32 pe;
6376
6377 mypid = getpid(); /* This function never fails */
6378
6379 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6380 if (snapshot == INVALID_HANDLE_VALUE)
6381 return PyErr_SetFromWindowsErr(GetLastError());
6382
6383 pe.dwSize = sizeof(pe);
6384 have_record = Process32First(snapshot, &pe);
6385 while (have_record) {
6386 if (mypid == (pid_t)pe.th32ProcessID) {
6387 /* We could cache the ulong value in a static variable. */
6388 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6389 break;
6390 }
6391
6392 have_record = Process32Next(snapshot, &pe);
6393 }
6394
6395 /* If our loop exits and our pid was not found (result will be NULL)
6396 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6397 * error anyway, so let's raise it. */
6398 if (!result)
6399 result = PyErr_SetFromWindowsErr(GetLastError());
6400
6401 CloseHandle(snapshot);
6402
6403 return result;
6404}
6405#endif /*MS_WINDOWS*/
6406
Larry Hastings2f936352014-08-05 14:04:04 +10006407
6408/*[clinic input]
6409os.getppid
6410
6411Return the parent's process id.
6412
6413If the parent process has already exited, Windows machines will still
6414return its id; others systems will return the id of the 'init' process (1).
6415[clinic start generated code]*/
6416
Larry Hastings2f936352014-08-05 14:04:04 +10006417static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006418os_getppid_impl(PyObject *module)
6419/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006420{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006421#ifdef MS_WINDOWS
6422 return win32_getppid();
6423#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006425#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006426}
6427#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006428
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006429
Fred Drake12c6e2d1999-12-14 21:25:03 +00006430#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006431/*[clinic input]
6432os.getlogin
6433
6434Return the actual login name.
6435[clinic start generated code]*/
6436
Larry Hastings2f936352014-08-05 14:04:04 +10006437static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006438os_getlogin_impl(PyObject *module)
6439/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006440{
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006442#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006443 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006444 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006445
6446 if (GetUserNameW(user_name, &num_chars)) {
6447 /* num_chars is the number of unicode chars plus null terminator */
6448 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006449 }
6450 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006451 result = PyErr_SetFromWindowsErr(GetLastError());
6452#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 char *name;
6454 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006455
Victor Stinner8c62be82010-05-06 00:08:46 +00006456 errno = 0;
6457 name = getlogin();
6458 if (name == NULL) {
6459 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006460 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006461 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006462 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 }
6464 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006465 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006467#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006468 return result;
6469}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006470#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006471
Larry Hastings2f936352014-08-05 14:04:04 +10006472
Guido van Rossumad0ee831995-03-01 10:34:45 +00006473#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006474/*[clinic input]
6475os.getuid
6476
6477Return the current process's user id.
6478[clinic start generated code]*/
6479
Larry Hastings2f936352014-08-05 14:04:04 +10006480static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006481os_getuid_impl(PyObject *module)
6482/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006483{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006484 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006485}
Larry Hastings2f936352014-08-05 14:04:04 +10006486#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006487
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006488
Brian Curtineb24d742010-04-12 17:16:38 +00006489#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006490#define HAVE_KILL
6491#endif /* MS_WINDOWS */
6492
6493#ifdef HAVE_KILL
6494/*[clinic input]
6495os.kill
6496
6497 pid: pid_t
6498 signal: Py_ssize_t
6499 /
6500
6501Kill a process with a signal.
6502[clinic start generated code]*/
6503
Larry Hastings2f936352014-08-05 14:04:04 +10006504static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006505os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6506/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006507#ifndef MS_WINDOWS
6508{
6509 if (kill(pid, (int)signal) == -1)
6510 return posix_error();
6511 Py_RETURN_NONE;
6512}
6513#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006514{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006515 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006516 DWORD sig = (DWORD)signal;
6517 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006519
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 /* Console processes which share a common console can be sent CTRL+C or
6521 CTRL+BREAK events, provided they handle said events. */
6522 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006523 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006524 err = GetLastError();
6525 PyErr_SetFromWindowsErr(err);
6526 }
6527 else
6528 Py_RETURN_NONE;
6529 }
Brian Curtineb24d742010-04-12 17:16:38 +00006530
Victor Stinner8c62be82010-05-06 00:08:46 +00006531 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6532 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006533 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 if (handle == NULL) {
6535 err = GetLastError();
6536 return PyErr_SetFromWindowsErr(err);
6537 }
Brian Curtineb24d742010-04-12 17:16:38 +00006538
Victor Stinner8c62be82010-05-06 00:08:46 +00006539 if (TerminateProcess(handle, sig) == 0) {
6540 err = GetLastError();
6541 result = PyErr_SetFromWindowsErr(err);
6542 } else {
6543 Py_INCREF(Py_None);
6544 result = Py_None;
6545 }
Brian Curtineb24d742010-04-12 17:16:38 +00006546
Victor Stinner8c62be82010-05-06 00:08:46 +00006547 CloseHandle(handle);
6548 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006549}
Larry Hastings2f936352014-08-05 14:04:04 +10006550#endif /* !MS_WINDOWS */
6551#endif /* HAVE_KILL */
6552
6553
6554#ifdef HAVE_KILLPG
6555/*[clinic input]
6556os.killpg
6557
6558 pgid: pid_t
6559 signal: int
6560 /
6561
6562Kill a process group with a signal.
6563[clinic start generated code]*/
6564
Larry Hastings2f936352014-08-05 14:04:04 +10006565static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006566os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6567/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006568{
6569 /* XXX some man pages make the `pgid` parameter an int, others
6570 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6571 take the same type. Moreover, pid_t is always at least as wide as
6572 int (else compilation of this module fails), which is safe. */
6573 if (killpg(pgid, signal) == -1)
6574 return posix_error();
6575 Py_RETURN_NONE;
6576}
6577#endif /* HAVE_KILLPG */
6578
Brian Curtineb24d742010-04-12 17:16:38 +00006579
Guido van Rossumc0125471996-06-28 18:55:32 +00006580#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006581#ifdef HAVE_SYS_LOCK_H
6582#include <sys/lock.h>
6583#endif
6584
Larry Hastings2f936352014-08-05 14:04:04 +10006585/*[clinic input]
6586os.plock
6587 op: int
6588 /
6589
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006590Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006591[clinic start generated code]*/
6592
Larry Hastings2f936352014-08-05 14:04:04 +10006593static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006594os_plock_impl(PyObject *module, int op)
6595/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006596{
Victor Stinner8c62be82010-05-06 00:08:46 +00006597 if (plock(op) == -1)
6598 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006599 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006600}
Larry Hastings2f936352014-08-05 14:04:04 +10006601#endif /* HAVE_PLOCK */
6602
Guido van Rossumc0125471996-06-28 18:55:32 +00006603
Guido van Rossumb6775db1994-08-01 11:34:53 +00006604#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006605/*[clinic input]
6606os.setuid
6607
6608 uid: uid_t
6609 /
6610
6611Set the current process's user id.
6612[clinic start generated code]*/
6613
Larry Hastings2f936352014-08-05 14:04:04 +10006614static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006615os_setuid_impl(PyObject *module, uid_t uid)
6616/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006617{
Victor Stinner8c62be82010-05-06 00:08:46 +00006618 if (setuid(uid) < 0)
6619 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006620 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006621}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006622#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006623
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006624
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006625#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006626/*[clinic input]
6627os.seteuid
6628
6629 euid: uid_t
6630 /
6631
6632Set the current process's effective user id.
6633[clinic start generated code]*/
6634
Larry Hastings2f936352014-08-05 14:04:04 +10006635static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006636os_seteuid_impl(PyObject *module, uid_t euid)
6637/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006638{
6639 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006640 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006641 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006642}
6643#endif /* HAVE_SETEUID */
6644
Larry Hastings2f936352014-08-05 14:04:04 +10006645
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006646#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006647/*[clinic input]
6648os.setegid
6649
6650 egid: gid_t
6651 /
6652
6653Set the current process's effective group id.
6654[clinic start generated code]*/
6655
Larry Hastings2f936352014-08-05 14:04:04 +10006656static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006657os_setegid_impl(PyObject *module, gid_t egid)
6658/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006659{
6660 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006661 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006662 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006663}
6664#endif /* HAVE_SETEGID */
6665
Larry Hastings2f936352014-08-05 14:04:04 +10006666
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006667#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006668/*[clinic input]
6669os.setreuid
6670
6671 ruid: uid_t
6672 euid: uid_t
6673 /
6674
6675Set the current process's real and effective user ids.
6676[clinic start generated code]*/
6677
Larry Hastings2f936352014-08-05 14:04:04 +10006678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006679os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6680/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006681{
Victor Stinner8c62be82010-05-06 00:08:46 +00006682 if (setreuid(ruid, euid) < 0) {
6683 return posix_error();
6684 } else {
6685 Py_INCREF(Py_None);
6686 return Py_None;
6687 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006688}
6689#endif /* HAVE_SETREUID */
6690
Larry Hastings2f936352014-08-05 14:04:04 +10006691
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006692#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006693/*[clinic input]
6694os.setregid
6695
6696 rgid: gid_t
6697 egid: gid_t
6698 /
6699
6700Set the current process's real and effective group ids.
6701[clinic start generated code]*/
6702
Larry Hastings2f936352014-08-05 14:04:04 +10006703static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006704os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6705/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006706{
6707 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006708 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006709 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006710}
6711#endif /* HAVE_SETREGID */
6712
Larry Hastings2f936352014-08-05 14:04:04 +10006713
Guido van Rossumb6775db1994-08-01 11:34:53 +00006714#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006715/*[clinic input]
6716os.setgid
6717 gid: gid_t
6718 /
6719
6720Set the current process's group id.
6721[clinic start generated code]*/
6722
Larry Hastings2f936352014-08-05 14:04:04 +10006723static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006724os_setgid_impl(PyObject *module, gid_t gid)
6725/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006726{
Victor Stinner8c62be82010-05-06 00:08:46 +00006727 if (setgid(gid) < 0)
6728 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006729 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006730}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006731#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006732
Larry Hastings2f936352014-08-05 14:04:04 +10006733
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006734#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006735/*[clinic input]
6736os.setgroups
6737
6738 groups: object
6739 /
6740
6741Set the groups of the current process to list.
6742[clinic start generated code]*/
6743
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006745os_setgroups(PyObject *module, PyObject *groups)
6746/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006747{
Victor Stinner8c62be82010-05-06 00:08:46 +00006748 int i, len;
6749 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006750
Victor Stinner8c62be82010-05-06 00:08:46 +00006751 if (!PySequence_Check(groups)) {
6752 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6753 return NULL;
6754 }
6755 len = PySequence_Size(groups);
6756 if (len > MAX_GROUPS) {
6757 PyErr_SetString(PyExc_ValueError, "too many groups");
6758 return NULL;
6759 }
6760 for(i = 0; i < len; i++) {
6761 PyObject *elem;
6762 elem = PySequence_GetItem(groups, i);
6763 if (!elem)
6764 return NULL;
6765 if (!PyLong_Check(elem)) {
6766 PyErr_SetString(PyExc_TypeError,
6767 "groups must be integers");
6768 Py_DECREF(elem);
6769 return NULL;
6770 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006771 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006772 Py_DECREF(elem);
6773 return NULL;
6774 }
6775 }
6776 Py_DECREF(elem);
6777 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006778
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 if (setgroups(len, grouplist) < 0)
6780 return posix_error();
6781 Py_INCREF(Py_None);
6782 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006783}
6784#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006785
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006786#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6787static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006788wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006789{
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 PyObject *result;
6791 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006792 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 if (pid == -1)
6795 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006796
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 if (struct_rusage == NULL) {
6798 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6799 if (m == NULL)
6800 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006801 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 Py_DECREF(m);
6803 if (struct_rusage == NULL)
6804 return NULL;
6805 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006806
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6808 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6809 if (!result)
6810 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006811
6812#ifndef doubletime
6813#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6814#endif
6815
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006817 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006818 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006819 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006820#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6822 SET_INT(result, 2, ru->ru_maxrss);
6823 SET_INT(result, 3, ru->ru_ixrss);
6824 SET_INT(result, 4, ru->ru_idrss);
6825 SET_INT(result, 5, ru->ru_isrss);
6826 SET_INT(result, 6, ru->ru_minflt);
6827 SET_INT(result, 7, ru->ru_majflt);
6828 SET_INT(result, 8, ru->ru_nswap);
6829 SET_INT(result, 9, ru->ru_inblock);
6830 SET_INT(result, 10, ru->ru_oublock);
6831 SET_INT(result, 11, ru->ru_msgsnd);
6832 SET_INT(result, 12, ru->ru_msgrcv);
6833 SET_INT(result, 13, ru->ru_nsignals);
6834 SET_INT(result, 14, ru->ru_nvcsw);
6835 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836#undef SET_INT
6837
Victor Stinner8c62be82010-05-06 00:08:46 +00006838 if (PyErr_Occurred()) {
6839 Py_DECREF(result);
6840 return NULL;
6841 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842
Victor Stinner8c62be82010-05-06 00:08:46 +00006843 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006844}
6845#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6846
Larry Hastings2f936352014-08-05 14:04:04 +10006847
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006848#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006849/*[clinic input]
6850os.wait3
6851
6852 options: int
6853Wait for completion of a child process.
6854
6855Returns a tuple of information about the child process:
6856 (pid, status, rusage)
6857[clinic start generated code]*/
6858
Larry Hastings2f936352014-08-05 14:04:04 +10006859static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006860os_wait3_impl(PyObject *module, int options)
6861/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006862{
Victor Stinner8c62be82010-05-06 00:08:46 +00006863 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006865 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006866 WAIT_TYPE status;
6867 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006868
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006869 do {
6870 Py_BEGIN_ALLOW_THREADS
6871 pid = wait3(&status, options, &ru);
6872 Py_END_ALLOW_THREADS
6873 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6874 if (pid < 0)
6875 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876
Victor Stinner4195b5c2012-02-08 23:03:19 +01006877 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006878}
6879#endif /* HAVE_WAIT3 */
6880
Larry Hastings2f936352014-08-05 14:04:04 +10006881
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006883/*[clinic input]
6884
6885os.wait4
6886
6887 pid: pid_t
6888 options: int
6889
6890Wait for completion of a specific child process.
6891
6892Returns a tuple of information about the child process:
6893 (pid, status, rusage)
6894[clinic start generated code]*/
6895
Larry Hastings2f936352014-08-05 14:04:04 +10006896static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006897os_wait4_impl(PyObject *module, pid_t pid, int options)
6898/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006899{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006900 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006902 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006903 WAIT_TYPE status;
6904 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006905
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006906 do {
6907 Py_BEGIN_ALLOW_THREADS
6908 res = wait4(pid, &status, options, &ru);
6909 Py_END_ALLOW_THREADS
6910 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6911 if (res < 0)
6912 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006914 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915}
6916#endif /* HAVE_WAIT4 */
6917
Larry Hastings2f936352014-08-05 14:04:04 +10006918
Ross Lagerwall7807c352011-03-17 20:20:30 +02006919#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006920/*[clinic input]
6921os.waitid
6922
6923 idtype: idtype_t
6924 Must be one of be P_PID, P_PGID or P_ALL.
6925 id: id_t
6926 The id to wait on.
6927 options: int
6928 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6929 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6930 /
6931
6932Returns the result of waiting for a process or processes.
6933
6934Returns either waitid_result or None if WNOHANG is specified and there are
6935no children in a waitable state.
6936[clinic start generated code]*/
6937
Larry Hastings2f936352014-08-05 14:04:04 +10006938static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006939os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6940/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006941{
6942 PyObject *result;
6943 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006944 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006945 siginfo_t si;
6946 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006947
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006948 do {
6949 Py_BEGIN_ALLOW_THREADS
6950 res = waitid(idtype, id, &si, options);
6951 Py_END_ALLOW_THREADS
6952 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6953 if (res < 0)
6954 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006955
6956 if (si.si_pid == 0)
6957 Py_RETURN_NONE;
6958
6959 result = PyStructSequence_New(&WaitidResultType);
6960 if (!result)
6961 return NULL;
6962
6963 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006964 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006965 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6966 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6967 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6968 if (PyErr_Occurred()) {
6969 Py_DECREF(result);
6970 return NULL;
6971 }
6972
6973 return result;
6974}
Larry Hastings2f936352014-08-05 14:04:04 +10006975#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006976
Larry Hastings2f936352014-08-05 14:04:04 +10006977
6978#if defined(HAVE_WAITPID)
6979/*[clinic input]
6980os.waitpid
6981 pid: pid_t
6982 options: int
6983 /
6984
6985Wait for completion of a given child process.
6986
6987Returns a tuple of information regarding the child process:
6988 (pid, status)
6989
6990The options argument is ignored on Windows.
6991[clinic start generated code]*/
6992
Larry Hastings2f936352014-08-05 14:04:04 +10006993static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006994os_waitpid_impl(PyObject *module, pid_t pid, int options)
6995/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006996{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006997 pid_t res;
6998 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006999 WAIT_TYPE status;
7000 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007001
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007002 do {
7003 Py_BEGIN_ALLOW_THREADS
7004 res = waitpid(pid, &status, options);
7005 Py_END_ALLOW_THREADS
7006 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7007 if (res < 0)
7008 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007009
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007010 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007011}
Tim Petersab034fa2002-02-01 11:27:43 +00007012#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007013/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007014/*[clinic input]
7015os.waitpid
7016 pid: Py_intptr_t
7017 options: int
7018 /
7019
7020Wait for completion of a given process.
7021
7022Returns a tuple of information regarding the process:
7023 (pid, status << 8)
7024
7025The options argument is ignored on Windows.
7026[clinic start generated code]*/
7027
Larry Hastings2f936352014-08-05 14:04:04 +10007028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007029os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7030/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007031{
7032 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007033 Py_intptr_t res;
7034 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007035
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007036 do {
7037 Py_BEGIN_ALLOW_THREADS
7038 res = _cwait(&status, pid, options);
7039 Py_END_ALLOW_THREADS
7040 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007041 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007042 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007043
Victor Stinner8c62be82010-05-06 00:08:46 +00007044 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007045 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007046}
Larry Hastings2f936352014-08-05 14:04:04 +10007047#endif
7048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007049
Guido van Rossumad0ee831995-03-01 10:34:45 +00007050#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007051/*[clinic input]
7052os.wait
7053
7054Wait for completion of a child process.
7055
7056Returns a tuple of information about the child process:
7057 (pid, status)
7058[clinic start generated code]*/
7059
Larry Hastings2f936352014-08-05 14:04:04 +10007060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007061os_wait_impl(PyObject *module)
7062/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007063{
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007065 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 WAIT_TYPE status;
7067 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007068
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007069 do {
7070 Py_BEGIN_ALLOW_THREADS
7071 pid = wait(&status);
7072 Py_END_ALLOW_THREADS
7073 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7074 if (pid < 0)
7075 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007076
Victor Stinner8c62be82010-05-06 00:08:46 +00007077 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007078}
Larry Hastings2f936352014-08-05 14:04:04 +10007079#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007080
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007081
Larry Hastings9cf065c2012-06-22 16:30:09 -07007082#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7083PyDoc_STRVAR(readlink__doc__,
7084"readlink(path, *, dir_fd=None) -> path\n\n\
7085Return a string representing the path to which the symbolic link points.\n\
7086\n\
7087If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7088 and path should be relative; path will then be relative to that directory.\n\
7089dir_fd may not be implemented on your platform.\n\
7090 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007091#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007092
Guido van Rossumb6775db1994-08-01 11:34:53 +00007093#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007094
Larry Hastings2f936352014-08-05 14:04:04 +10007095/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007096static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007098{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099 path_t path;
7100 int dir_fd = DEFAULT_DIR_FD;
7101 char buffer[MAXPATHLEN];
7102 ssize_t length;
7103 PyObject *return_value = NULL;
7104 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007105
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007107 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007108 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7109 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007110 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007112
Victor Stinner8c62be82010-05-06 00:08:46 +00007113 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007114#ifdef HAVE_READLINKAT
7115 if (dir_fd != DEFAULT_DIR_FD)
7116 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007117 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118#endif
7119 length = readlink(path.narrow, buffer, sizeof(buffer));
7120 Py_END_ALLOW_THREADS
7121
7122 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007123 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124 goto exit;
7125 }
7126
7127 if (PyUnicode_Check(path.object))
7128 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7129 else
7130 return_value = PyBytes_FromStringAndSize(buffer, length);
7131exit:
7132 path_cleanup(&path);
7133 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007134}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007135
Guido van Rossumb6775db1994-08-01 11:34:53 +00007136#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007137
Larry Hastings2f936352014-08-05 14:04:04 +10007138#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7139
7140static PyObject *
7141win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7142{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007143 const wchar_t *path;
Larry Hastings2f936352014-08-05 14:04:04 +10007144 DWORD n_bytes_returned;
7145 DWORD io_result;
7146 PyObject *po, *result;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007147 int dir_fd;
Larry Hastings2f936352014-08-05 14:04:04 +10007148 HANDLE reparse_point_handle;
7149
7150 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7151 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007152 const wchar_t *print_name;
Larry Hastings2f936352014-08-05 14:04:04 +10007153
7154 static char *keywords[] = {"path", "dir_fd", NULL};
7155
7156 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7157 &po,
7158 dir_fd_unavailable, &dir_fd
7159 ))
7160 return NULL;
7161
7162 path = PyUnicode_AsUnicode(po);
7163 if (path == NULL)
7164 return NULL;
7165
7166 /* First get a handle to the reparse point */
7167 Py_BEGIN_ALLOW_THREADS
7168 reparse_point_handle = CreateFileW(
7169 path,
7170 0,
7171 0,
7172 0,
7173 OPEN_EXISTING,
7174 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7175 0);
7176 Py_END_ALLOW_THREADS
7177
7178 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7179 return win32_error_object("readlink", po);
7180
7181 Py_BEGIN_ALLOW_THREADS
7182 /* New call DeviceIoControl to read the reparse point */
7183 io_result = DeviceIoControl(
7184 reparse_point_handle,
7185 FSCTL_GET_REPARSE_POINT,
7186 0, 0, /* in buffer */
7187 target_buffer, sizeof(target_buffer),
7188 &n_bytes_returned,
7189 0 /* we're not using OVERLAPPED_IO */
7190 );
7191 CloseHandle(reparse_point_handle);
7192 Py_END_ALLOW_THREADS
7193
7194 if (io_result==0)
7195 return win32_error_object("readlink", po);
7196
7197 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7198 {
7199 PyErr_SetString(PyExc_ValueError,
7200 "not a symbolic link");
7201 return NULL;
7202 }
7203 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7204 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7205
7206 result = PyUnicode_FromWideChar(print_name,
7207 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7208 return result;
7209}
7210
7211#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7212
7213
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007214
Larry Hastings9cf065c2012-06-22 16:30:09 -07007215#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007216
7217#if defined(MS_WINDOWS)
7218
7219/* Grab CreateSymbolicLinkW dynamically from kernel32 */
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007220static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPCWSTR, LPCWSTR, DWORD) = NULL;
7221static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPCSTR, LPCSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007222
Larry Hastings9cf065c2012-06-22 16:30:09 -07007223static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007224check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007225{
7226 HINSTANCE hKernel32;
7227 /* only recheck */
7228 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7229 return 1;
7230 hKernel32 = GetModuleHandleW(L"KERNEL32");
7231 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7232 "CreateSymbolicLinkW");
7233 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7234 "CreateSymbolicLinkA");
7235 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7236}
7237
Victor Stinner31b3b922013-06-05 01:49:17 +02007238/* Remove the last portion of the path */
7239static void
7240_dirnameW(WCHAR *path)
7241{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007242 WCHAR *ptr;
7243
7244 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007245 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007246 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007247 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007248 }
7249 *ptr = 0;
7250}
7251
Victor Stinner31b3b922013-06-05 01:49:17 +02007252/* Remove the last portion of the path */
7253static void
7254_dirnameA(char *path)
7255{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007256 char *ptr;
7257
7258 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007259 for(ptr = path + strlen(path); ptr != path; ptr--) {
7260 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007261 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007262 }
7263 *ptr = 0;
7264}
7265
Victor Stinner31b3b922013-06-05 01:49:17 +02007266/* Is this path absolute? */
7267static int
7268_is_absW(const WCHAR *path)
7269{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007270 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7271
7272}
7273
Victor Stinner31b3b922013-06-05 01:49:17 +02007274/* Is this path absolute? */
7275static int
7276_is_absA(const char *path)
7277{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007278 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7279
7280}
7281
Victor Stinner31b3b922013-06-05 01:49:17 +02007282/* join root and rest with a backslash */
7283static void
7284_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7285{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007286 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007287
Victor Stinner31b3b922013-06-05 01:49:17 +02007288 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289 wcscpy(dest_path, rest);
7290 return;
7291 }
7292
7293 root_len = wcslen(root);
7294
7295 wcscpy(dest_path, root);
7296 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007297 dest_path[root_len] = L'\\';
7298 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007299 }
7300 wcscpy(dest_path+root_len, rest);
7301}
7302
Victor Stinner31b3b922013-06-05 01:49:17 +02007303/* join root and rest with a backslash */
7304static void
7305_joinA(char *dest_path, const char *root, const char *rest)
7306{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007307 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308
Victor Stinner31b3b922013-06-05 01:49:17 +02007309 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007310 strcpy(dest_path, rest);
7311 return;
7312 }
7313
7314 root_len = strlen(root);
7315
7316 strcpy(dest_path, root);
7317 if(root_len) {
7318 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007319 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007320 }
7321 strcpy(dest_path+root_len, rest);
7322}
7323
Victor Stinner31b3b922013-06-05 01:49:17 +02007324/* Return True if the path at src relative to dest is a directory */
7325static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007326_check_dirW(LPCWSTR src, LPCWSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007327{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007328 WIN32_FILE_ATTRIBUTE_DATA src_info;
7329 WCHAR dest_parent[MAX_PATH];
7330 WCHAR src_resolved[MAX_PATH] = L"";
7331
7332 /* dest_parent = os.path.dirname(dest) */
7333 wcscpy(dest_parent, dest);
7334 _dirnameW(dest_parent);
7335 /* src_resolved = os.path.join(dest_parent, src) */
7336 _joinW(src_resolved, dest_parent, src);
7337 return (
7338 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7339 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7340 );
7341}
7342
Victor Stinner31b3b922013-06-05 01:49:17 +02007343/* Return True if the path at src relative to dest is a directory */
7344static int
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03007345_check_dirA(LPCSTR src, LPCSTR dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007346{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007347 WIN32_FILE_ATTRIBUTE_DATA src_info;
7348 char dest_parent[MAX_PATH];
7349 char src_resolved[MAX_PATH] = "";
7350
7351 /* dest_parent = os.path.dirname(dest) */
7352 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007353 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007354 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007355 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007356 return (
7357 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7358 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7359 );
7360}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007361#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007362
Larry Hastings2f936352014-08-05 14:04:04 +10007363
7364/*[clinic input]
7365os.symlink
7366 src: path_t
7367 dst: path_t
7368 target_is_directory: bool = False
7369 *
7370 dir_fd: dir_fd(requires='symlinkat')=None
7371
7372# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7373
7374Create a symbolic link pointing to src named dst.
7375
7376target_is_directory is required on Windows if the target is to be
7377 interpreted as a directory. (On Windows, symlink requires
7378 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7379 target_is_directory is ignored on non-Windows platforms.
7380
7381If dir_fd is not None, it should be a file descriptor open to a directory,
7382 and path should be relative; path will then be relative to that directory.
7383dir_fd may not be implemented on your platform.
7384 If it is unavailable, using it will raise a NotImplementedError.
7385
7386[clinic start generated code]*/
7387
Larry Hastings2f936352014-08-05 14:04:04 +10007388static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007389os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007390 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007391/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007392{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007393#ifdef MS_WINDOWS
7394 DWORD result;
7395#else
7396 int result;
7397#endif
7398
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399#ifdef MS_WINDOWS
7400 if (!check_CreateSymbolicLink()) {
7401 PyErr_SetString(PyExc_NotImplementedError,
7402 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007403 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007404 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 if (!win32_can_symlink) {
7406 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007407 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007408 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409#endif
7410
Larry Hastings2f936352014-08-05 14:04:04 +10007411 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007412 PyErr_SetString(PyExc_ValueError,
7413 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007414 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007415 }
7416
7417#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007418
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007420 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007421 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007422 target_is_directory |= _check_dirW(src->wide, dst->wide);
7423 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007424 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007425 }
7426 else {
7427 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007428 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7429 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007431 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007432 Py_END_ALLOW_THREADS
7433
Larry Hastings2f936352014-08-05 14:04:04 +10007434 if (!result)
7435 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007436
7437#else
7438
7439 Py_BEGIN_ALLOW_THREADS
7440#if HAVE_SYMLINKAT
7441 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007442 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007443 else
7444#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007445 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007446 Py_END_ALLOW_THREADS
7447
Larry Hastings2f936352014-08-05 14:04:04 +10007448 if (result)
7449 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007450#endif
7451
Larry Hastings2f936352014-08-05 14:04:04 +10007452 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007453}
7454#endif /* HAVE_SYMLINK */
7455
Larry Hastings9cf065c2012-06-22 16:30:09 -07007456
Brian Curtind40e6f72010-07-08 21:39:08 +00007457
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007458
Larry Hastings605a62d2012-06-24 04:33:36 -07007459static PyStructSequence_Field times_result_fields[] = {
7460 {"user", "user time"},
7461 {"system", "system time"},
7462 {"children_user", "user time of children"},
7463 {"children_system", "system time of children"},
7464 {"elapsed", "elapsed time since an arbitrary point in the past"},
7465 {NULL}
7466};
7467
7468PyDoc_STRVAR(times_result__doc__,
7469"times_result: Result from os.times().\n\n\
7470This object may be accessed either as a tuple of\n\
7471 (user, system, children_user, children_system, elapsed),\n\
7472or via the attributes user, system, children_user, children_system,\n\
7473and elapsed.\n\
7474\n\
7475See os.times for more information.");
7476
7477static PyStructSequence_Desc times_result_desc = {
7478 "times_result", /* name */
7479 times_result__doc__, /* doc */
7480 times_result_fields,
7481 5
7482};
7483
7484static PyTypeObject TimesResultType;
7485
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007486#ifdef MS_WINDOWS
7487#define HAVE_TIMES /* mandatory, for the method table */
7488#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007489
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007490#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007491
7492static PyObject *
7493build_times_result(double user, double system,
7494 double children_user, double children_system,
7495 double elapsed)
7496{
7497 PyObject *value = PyStructSequence_New(&TimesResultType);
7498 if (value == NULL)
7499 return NULL;
7500
7501#define SET(i, field) \
7502 { \
7503 PyObject *o = PyFloat_FromDouble(field); \
7504 if (!o) { \
7505 Py_DECREF(value); \
7506 return NULL; \
7507 } \
7508 PyStructSequence_SET_ITEM(value, i, o); \
7509 } \
7510
7511 SET(0, user);
7512 SET(1, system);
7513 SET(2, children_user);
7514 SET(3, children_system);
7515 SET(4, elapsed);
7516
7517#undef SET
7518
7519 return value;
7520}
7521
Larry Hastings605a62d2012-06-24 04:33:36 -07007522
Larry Hastings2f936352014-08-05 14:04:04 +10007523#ifndef MS_WINDOWS
7524#define NEED_TICKS_PER_SECOND
7525static long ticks_per_second = -1;
7526#endif /* MS_WINDOWS */
7527
7528/*[clinic input]
7529os.times
7530
7531Return a collection containing process timing information.
7532
7533The object returned behaves like a named tuple with these fields:
7534 (utime, stime, cutime, cstime, elapsed_time)
7535All fields are floating point numbers.
7536[clinic start generated code]*/
7537
Larry Hastings2f936352014-08-05 14:04:04 +10007538static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007539os_times_impl(PyObject *module)
7540/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007541#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007542{
Victor Stinner8c62be82010-05-06 00:08:46 +00007543 FILETIME create, exit, kernel, user;
7544 HANDLE hProc;
7545 hProc = GetCurrentProcess();
7546 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7547 /* The fields of a FILETIME structure are the hi and lo part
7548 of a 64-bit value expressed in 100 nanosecond units.
7549 1e7 is one second in such units; 1e-7 the inverse.
7550 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7551 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007552 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007553 (double)(user.dwHighDateTime*429.4967296 +
7554 user.dwLowDateTime*1e-7),
7555 (double)(kernel.dwHighDateTime*429.4967296 +
7556 kernel.dwLowDateTime*1e-7),
7557 (double)0,
7558 (double)0,
7559 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007560}
Larry Hastings2f936352014-08-05 14:04:04 +10007561#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007562{
Larry Hastings2f936352014-08-05 14:04:04 +10007563
7564
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007565 struct tms t;
7566 clock_t c;
7567 errno = 0;
7568 c = times(&t);
7569 if (c == (clock_t) -1)
7570 return posix_error();
7571 return build_times_result(
7572 (double)t.tms_utime / ticks_per_second,
7573 (double)t.tms_stime / ticks_per_second,
7574 (double)t.tms_cutime / ticks_per_second,
7575 (double)t.tms_cstime / ticks_per_second,
7576 (double)c / ticks_per_second);
7577}
Larry Hastings2f936352014-08-05 14:04:04 +10007578#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007579#endif /* HAVE_TIMES */
7580
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007581
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007582#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007583/*[clinic input]
7584os.getsid
7585
7586 pid: pid_t
7587 /
7588
7589Call the system call getsid(pid) and return the result.
7590[clinic start generated code]*/
7591
Larry Hastings2f936352014-08-05 14:04:04 +10007592static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007593os_getsid_impl(PyObject *module, pid_t pid)
7594/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007595{
Victor Stinner8c62be82010-05-06 00:08:46 +00007596 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 sid = getsid(pid);
7598 if (sid < 0)
7599 return posix_error();
7600 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007601}
7602#endif /* HAVE_GETSID */
7603
7604
Guido van Rossumb6775db1994-08-01 11:34:53 +00007605#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007606/*[clinic input]
7607os.setsid
7608
7609Call the system call setsid().
7610[clinic start generated code]*/
7611
Larry Hastings2f936352014-08-05 14:04:04 +10007612static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007613os_setsid_impl(PyObject *module)
7614/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007615{
Victor Stinner8c62be82010-05-06 00:08:46 +00007616 if (setsid() < 0)
7617 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007618 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007619}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007620#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007621
Larry Hastings2f936352014-08-05 14:04:04 +10007622
Guido van Rossumb6775db1994-08-01 11:34:53 +00007623#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007624/*[clinic input]
7625os.setpgid
7626
7627 pid: pid_t
7628 pgrp: pid_t
7629 /
7630
7631Call the system call setpgid(pid, pgrp).
7632[clinic start generated code]*/
7633
Larry Hastings2f936352014-08-05 14:04:04 +10007634static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007635os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7636/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007637{
Victor Stinner8c62be82010-05-06 00:08:46 +00007638 if (setpgid(pid, pgrp) < 0)
7639 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007640 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007641}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007642#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007643
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007644
Guido van Rossumb6775db1994-08-01 11:34:53 +00007645#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007646/*[clinic input]
7647os.tcgetpgrp
7648
7649 fd: int
7650 /
7651
7652Return the process group associated with the terminal specified by fd.
7653[clinic start generated code]*/
7654
Larry Hastings2f936352014-08-05 14:04:04 +10007655static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007656os_tcgetpgrp_impl(PyObject *module, int fd)
7657/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007658{
7659 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007660 if (pgid < 0)
7661 return posix_error();
7662 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007663}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007664#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007665
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007666
Guido van Rossumb6775db1994-08-01 11:34:53 +00007667#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007668/*[clinic input]
7669os.tcsetpgrp
7670
7671 fd: int
7672 pgid: pid_t
7673 /
7674
7675Set the process group associated with the terminal specified by fd.
7676[clinic start generated code]*/
7677
Larry Hastings2f936352014-08-05 14:04:04 +10007678static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007679os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7680/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007681{
Victor Stinner8c62be82010-05-06 00:08:46 +00007682 if (tcsetpgrp(fd, pgid) < 0)
7683 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007684 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007685}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007686#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007687
Guido van Rossum687dd131993-05-17 08:34:16 +00007688/* Functions acting on file descriptors */
7689
Victor Stinnerdaf45552013-08-28 00:53:59 +02007690#ifdef O_CLOEXEC
7691extern int _Py_open_cloexec_works;
7692#endif
7693
Larry Hastings2f936352014-08-05 14:04:04 +10007694
7695/*[clinic input]
7696os.open -> int
7697 path: path_t
7698 flags: int
7699 mode: int = 0o777
7700 *
7701 dir_fd: dir_fd(requires='openat') = None
7702
7703# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7704
7705Open a file for low level IO. Returns a file descriptor (integer).
7706
7707If dir_fd is not None, it should be a file descriptor open to a directory,
7708 and path should be relative; path will then be relative to that directory.
7709dir_fd may not be implemented on your platform.
7710 If it is unavailable, using it will raise a NotImplementedError.
7711[clinic start generated code]*/
7712
Larry Hastings2f936352014-08-05 14:04:04 +10007713static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007714os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7715/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007716{
7717 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007718 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007719
Victor Stinnerdaf45552013-08-28 00:53:59 +02007720#ifdef O_CLOEXEC
7721 int *atomic_flag_works = &_Py_open_cloexec_works;
7722#elif !defined(MS_WINDOWS)
7723 int *atomic_flag_works = NULL;
7724#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007725
Victor Stinnerdaf45552013-08-28 00:53:59 +02007726#ifdef MS_WINDOWS
7727 flags |= O_NOINHERIT;
7728#elif defined(O_CLOEXEC)
7729 flags |= O_CLOEXEC;
7730#endif
7731
Steve Dower8fc89802015-04-12 00:26:27 -04007732 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007733 do {
7734 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007735#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007736 if (path->wide)
7737 fd = _wopen(path->wide, flags, mode);
7738 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007739#endif
7740#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007741 if (dir_fd != DEFAULT_DIR_FD)
7742 fd = openat(dir_fd, path->narrow, flags, mode);
7743 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007744#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007745 fd = open(path->narrow, flags, mode);
7746 Py_END_ALLOW_THREADS
7747 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007748 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007749
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007750 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007751 if (!async_err)
7752 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007753 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007754 }
7755
Victor Stinnerdaf45552013-08-28 00:53:59 +02007756#ifndef MS_WINDOWS
7757 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7758 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007759 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007760 }
7761#endif
7762
Larry Hastings2f936352014-08-05 14:04:04 +10007763 return fd;
7764}
7765
7766
7767/*[clinic input]
7768os.close
7769
7770 fd: int
7771
7772Close a file descriptor.
7773[clinic start generated code]*/
7774
Barry Warsaw53699e91996-12-10 23:23:01 +00007775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007776os_close_impl(PyObject *module, int fd)
7777/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007778{
Larry Hastings2f936352014-08-05 14:04:04 +10007779 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007780 if (!_PyVerify_fd(fd))
7781 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007782 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7783 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7784 * for more details.
7785 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007786 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007787 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007788 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007789 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007790 Py_END_ALLOW_THREADS
7791 if (res < 0)
7792 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007793 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007794}
7795
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007796
Larry Hastings2f936352014-08-05 14:04:04 +10007797/*[clinic input]
7798os.closerange
7799
7800 fd_low: int
7801 fd_high: int
7802 /
7803
7804Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7805[clinic start generated code]*/
7806
Larry Hastings2f936352014-08-05 14:04:04 +10007807static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007808os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7809/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007810{
7811 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007812 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007813 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007814 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007815 if (_PyVerify_fd(i))
7816 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007817 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007818 Py_END_ALLOW_THREADS
7819 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007820}
7821
7822
Larry Hastings2f936352014-08-05 14:04:04 +10007823/*[clinic input]
7824os.dup -> int
7825
7826 fd: int
7827 /
7828
7829Return a duplicate of a file descriptor.
7830[clinic start generated code]*/
7831
Larry Hastings2f936352014-08-05 14:04:04 +10007832static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007833os_dup_impl(PyObject *module, int fd)
7834/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007835{
7836 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007837}
7838
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007839
Larry Hastings2f936352014-08-05 14:04:04 +10007840/*[clinic input]
7841os.dup2
7842 fd: int
7843 fd2: int
7844 inheritable: bool=True
7845
7846Duplicate file descriptor.
7847[clinic start generated code]*/
7848
Larry Hastings2f936352014-08-05 14:04:04 +10007849static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007850os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7851/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007852{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007853 int res;
7854#if defined(HAVE_DUP3) && \
7855 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7856 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7857 int dup3_works = -1;
7858#endif
7859
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 if (!_PyVerify_fd_dup2(fd, fd2))
7861 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007862
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007863 /* dup2() can fail with EINTR if the target FD is already open, because it
7864 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7865 * upon close(), and therefore below.
7866 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007867#ifdef MS_WINDOWS
7868 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007869 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007870 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007871 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007872 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 if (res < 0)
7874 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875
7876 /* Character files like console cannot be make non-inheritable */
7877 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7878 close(fd2);
7879 return NULL;
7880 }
7881
7882#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7883 Py_BEGIN_ALLOW_THREADS
7884 if (!inheritable)
7885 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7886 else
7887 res = dup2(fd, fd2);
7888 Py_END_ALLOW_THREADS
7889 if (res < 0)
7890 return posix_error();
7891
7892#else
7893
7894#ifdef HAVE_DUP3
7895 if (!inheritable && dup3_works != 0) {
7896 Py_BEGIN_ALLOW_THREADS
7897 res = dup3(fd, fd2, O_CLOEXEC);
7898 Py_END_ALLOW_THREADS
7899 if (res < 0) {
7900 if (dup3_works == -1)
7901 dup3_works = (errno != ENOSYS);
7902 if (dup3_works)
7903 return posix_error();
7904 }
7905 }
7906
7907 if (inheritable || dup3_works == 0)
7908 {
7909#endif
7910 Py_BEGIN_ALLOW_THREADS
7911 res = dup2(fd, fd2);
7912 Py_END_ALLOW_THREADS
7913 if (res < 0)
7914 return posix_error();
7915
7916 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7917 close(fd2);
7918 return NULL;
7919 }
7920#ifdef HAVE_DUP3
7921 }
7922#endif
7923
7924#endif
7925
Larry Hastings2f936352014-08-05 14:04:04 +10007926 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007927}
7928
Larry Hastings2f936352014-08-05 14:04:04 +10007929
Ross Lagerwall7807c352011-03-17 20:20:30 +02007930#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007931/*[clinic input]
7932os.lockf
7933
7934 fd: int
7935 An open file descriptor.
7936 command: int
7937 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7938 length: Py_off_t
7939 The number of bytes to lock, starting at the current position.
7940 /
7941
7942Apply, test or remove a POSIX lock on an open file descriptor.
7943
7944[clinic start generated code]*/
7945
Larry Hastings2f936352014-08-05 14:04:04 +10007946static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007947os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7948/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007949{
7950 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951
7952 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007953 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007954 Py_END_ALLOW_THREADS
7955
7956 if (res < 0)
7957 return posix_error();
7958
7959 Py_RETURN_NONE;
7960}
Larry Hastings2f936352014-08-05 14:04:04 +10007961#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007962
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007963
Larry Hastings2f936352014-08-05 14:04:04 +10007964/*[clinic input]
7965os.lseek -> Py_off_t
7966
7967 fd: int
7968 position: Py_off_t
7969 how: int
7970 /
7971
7972Set the position of a file descriptor. Return the new position.
7973
7974Return the new cursor position in number of bytes
7975relative to the beginning of the file.
7976[clinic start generated code]*/
7977
Larry Hastings2f936352014-08-05 14:04:04 +10007978static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007979os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7980/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007981{
7982 Py_off_t result;
7983
7984 if (!_PyVerify_fd(fd)) {
7985 posix_error();
7986 return -1;
7987 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007988#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007989 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7990 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007991 case 0: how = SEEK_SET; break;
7992 case 1: how = SEEK_CUR; break;
7993 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007994 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007995#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007996
Victor Stinner8c62be82010-05-06 00:08:46 +00007997 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007998 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007999
Larry Hastings2f936352014-08-05 14:04:04 +10008000 if (!_PyVerify_fd(fd)) {
8001 posix_error();
8002 return -1;
8003 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008004 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008005 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008006#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008007 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008008#else
Larry Hastings2f936352014-08-05 14:04:04 +10008009 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008010#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008011 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008012 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008013 if (result < 0)
8014 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008015
Larry Hastings2f936352014-08-05 14:04:04 +10008016 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008017}
8018
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008019
Larry Hastings2f936352014-08-05 14:04:04 +10008020/*[clinic input]
8021os.read
8022 fd: int
8023 length: Py_ssize_t
8024 /
8025
8026Read from a file descriptor. Returns a bytes object.
8027[clinic start generated code]*/
8028
Larry Hastings2f936352014-08-05 14:04:04 +10008029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008030os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8031/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008032{
Victor Stinner8c62be82010-05-06 00:08:46 +00008033 Py_ssize_t n;
8034 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008035
8036 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 errno = EINVAL;
8038 return posix_error();
8039 }
Larry Hastings2f936352014-08-05 14:04:04 +10008040
8041#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008042 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008043 if (length > INT_MAX)
8044 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008045#endif
8046
8047 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008048 if (buffer == NULL)
8049 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008050
Victor Stinner66aab0c2015-03-19 22:53:20 +01008051 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8052 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008053 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008054 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008055 }
Larry Hastings2f936352014-08-05 14:04:04 +10008056
8057 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008058 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008059
Victor Stinner8c62be82010-05-06 00:08:46 +00008060 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008061}
8062
Ross Lagerwall7807c352011-03-17 20:20:30 +02008063#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8064 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008065static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8067{
8068 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008069 Py_ssize_t blen, total = 0;
8070
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071 *iov = PyMem_New(struct iovec, cnt);
8072 if (*iov == NULL) {
8073 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008074 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008076
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 *buf = PyMem_New(Py_buffer, cnt);
8078 if (*buf == NULL) {
8079 PyMem_Del(*iov);
8080 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008081 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008082 }
8083
8084 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008085 PyObject *item = PySequence_GetItem(seq, i);
8086 if (item == NULL)
8087 goto fail;
8088 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8089 Py_DECREF(item);
8090 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008092 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008093 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008094 blen = (*buf)[i].len;
8095 (*iov)[i].iov_len = blen;
8096 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008097 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008098 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008099
8100fail:
8101 PyMem_Del(*iov);
8102 for (j = 0; j < i; j++) {
8103 PyBuffer_Release(&(*buf)[j]);
8104 }
8105 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008106 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008107}
8108
8109static void
8110iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8111{
8112 int i;
8113 PyMem_Del(iov);
8114 for (i = 0; i < cnt; i++) {
8115 PyBuffer_Release(&buf[i]);
8116 }
8117 PyMem_Del(buf);
8118}
8119#endif
8120
Larry Hastings2f936352014-08-05 14:04:04 +10008121
Ross Lagerwall7807c352011-03-17 20:20:30 +02008122#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008123/*[clinic input]
8124os.readv -> Py_ssize_t
8125
8126 fd: int
8127 buffers: object
8128 /
8129
8130Read from a file descriptor fd into an iterable of buffers.
8131
8132The buffers should be mutable buffers accepting bytes.
8133readv will transfer data into each buffer until it is full
8134and then move on to the next buffer in the sequence to hold
8135the rest of the data.
8136
8137readv returns the total number of bytes read,
8138which may be less than the total capacity of all the buffers.
8139[clinic start generated code]*/
8140
Larry Hastings2f936352014-08-05 14:04:04 +10008141static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008142os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8143/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008144{
8145 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008146 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008147 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148 struct iovec *iov;
8149 Py_buffer *buf;
8150
Larry Hastings2f936352014-08-05 14:04:04 +10008151 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008152 PyErr_SetString(PyExc_TypeError,
8153 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008154 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008155 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008156
Larry Hastings2f936352014-08-05 14:04:04 +10008157 cnt = PySequence_Size(buffers);
8158
8159 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8160 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008161
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008162 do {
8163 Py_BEGIN_ALLOW_THREADS
8164 n = readv(fd, iov, cnt);
8165 Py_END_ALLOW_THREADS
8166 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008167
8168 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008169 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008170 if (!async_err)
8171 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008172 return -1;
8173 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008174
Larry Hastings2f936352014-08-05 14:04:04 +10008175 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008176}
Larry Hastings2f936352014-08-05 14:04:04 +10008177#endif /* HAVE_READV */
8178
Ross Lagerwall7807c352011-03-17 20:20:30 +02008179
8180#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008181/*[clinic input]
8182# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8183os.pread
8184
8185 fd: int
8186 length: int
8187 offset: Py_off_t
8188 /
8189
8190Read a number of bytes from a file descriptor starting at a particular offset.
8191
8192Read length bytes from file descriptor fd, starting at offset bytes from
8193the beginning of the file. The file offset remains unchanged.
8194[clinic start generated code]*/
8195
Larry Hastings2f936352014-08-05 14:04:04 +10008196static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008197os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8198/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008199{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008200 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008201 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008202 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008203
Larry Hastings2f936352014-08-05 14:04:04 +10008204 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008205 errno = EINVAL;
8206 return posix_error();
8207 }
Larry Hastings2f936352014-08-05 14:04:04 +10008208 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008209 if (buffer == NULL)
8210 return NULL;
8211 if (!_PyVerify_fd(fd)) {
8212 Py_DECREF(buffer);
8213 return posix_error();
8214 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008215
8216 do {
8217 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008218 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008219 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008220 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008221 Py_END_ALLOW_THREADS
8222 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8223
Ross Lagerwall7807c352011-03-17 20:20:30 +02008224 if (n < 0) {
8225 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008226 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008227 }
Larry Hastings2f936352014-08-05 14:04:04 +10008228 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008229 _PyBytes_Resize(&buffer, n);
8230 return buffer;
8231}
Larry Hastings2f936352014-08-05 14:04:04 +10008232#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008233
Larry Hastings2f936352014-08-05 14:04:04 +10008234
8235/*[clinic input]
8236os.write -> Py_ssize_t
8237
8238 fd: int
8239 data: Py_buffer
8240 /
8241
8242Write a bytes object to a file descriptor.
8243[clinic start generated code]*/
8244
Larry Hastings2f936352014-08-05 14:04:04 +10008245static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008246os_write_impl(PyObject *module, int fd, Py_buffer *data)
8247/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008248{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008249 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008250}
8251
8252#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008253PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008254"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008255sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008256 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008257Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008258
Larry Hastings2f936352014-08-05 14:04:04 +10008259/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008260static PyObject *
8261posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8262{
8263 int in, out;
8264 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008265 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008266 off_t offset;
8267
8268#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8269#ifndef __APPLE__
8270 Py_ssize_t len;
8271#endif
8272 PyObject *headers = NULL, *trailers = NULL;
8273 Py_buffer *hbuf, *tbuf;
8274 off_t sbytes;
8275 struct sf_hdtr sf;
8276 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008277 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008278 static char *keywords[] = {"out", "in",
8279 "offset", "count",
8280 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008281
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008282 sf.headers = NULL;
8283 sf.trailers = NULL;
8284
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008285#ifdef __APPLE__
8286 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008287 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008288#else
8289 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008290 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008291#endif
8292 &headers, &trailers, &flags))
8293 return NULL;
8294 if (headers != NULL) {
8295 if (!PySequence_Check(headers)) {
8296 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008297 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008298 return NULL;
8299 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008300 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008301 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008302 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008303 (i = iov_setup(&(sf.headers), &hbuf,
8304 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008306#ifdef __APPLE__
8307 sbytes += i;
8308#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309 }
8310 }
8311 if (trailers != NULL) {
8312 if (!PySequence_Check(trailers)) {
8313 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008314 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315 return NULL;
8316 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008317 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008319 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008320 (i = iov_setup(&(sf.trailers), &tbuf,
8321 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008323#ifdef __APPLE__
8324 sbytes += i;
8325#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008326 }
8327 }
8328
Steve Dower8fc89802015-04-12 00:26:27 -04008329 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008330 do {
8331 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008332#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008333 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008334#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008335 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008336#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008337 Py_END_ALLOW_THREADS
8338 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008339 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008340
8341 if (sf.headers != NULL)
8342 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8343 if (sf.trailers != NULL)
8344 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8345
8346 if (ret < 0) {
8347 if ((errno == EAGAIN) || (errno == EBUSY)) {
8348 if (sbytes != 0) {
8349 // some data has been sent
8350 goto done;
8351 }
8352 else {
8353 // no data has been sent; upper application is supposed
8354 // to retry on EAGAIN or EBUSY
8355 return posix_error();
8356 }
8357 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008358 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008359 }
8360 goto done;
8361
8362done:
8363 #if !defined(HAVE_LARGEFILE_SUPPORT)
8364 return Py_BuildValue("l", sbytes);
8365 #else
8366 return Py_BuildValue("L", sbytes);
8367 #endif
8368
8369#else
8370 Py_ssize_t count;
8371 PyObject *offobj;
8372 static char *keywords[] = {"out", "in",
8373 "offset", "count", NULL};
8374 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8375 keywords, &out, &in, &offobj, &count))
8376 return NULL;
8377#ifdef linux
8378 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008379 do {
8380 Py_BEGIN_ALLOW_THREADS
8381 ret = sendfile(out, in, NULL, count);
8382 Py_END_ALLOW_THREADS
8383 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008384 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008385 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008386 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008387 }
8388#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008389 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008390 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008391
8392 do {
8393 Py_BEGIN_ALLOW_THREADS
8394 ret = sendfile(out, in, &offset, count);
8395 Py_END_ALLOW_THREADS
8396 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008397 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008398 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008399 return Py_BuildValue("n", ret);
8400#endif
8401}
Larry Hastings2f936352014-08-05 14:04:04 +10008402#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008403
Larry Hastings2f936352014-08-05 14:04:04 +10008404
8405/*[clinic input]
8406os.fstat
8407
8408 fd : int
8409
8410Perform a stat system call on the given file descriptor.
8411
8412Like stat(), but for an open file descriptor.
8413Equivalent to os.stat(fd).
8414[clinic start generated code]*/
8415
Larry Hastings2f936352014-08-05 14:04:04 +10008416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008417os_fstat_impl(PyObject *module, int fd)
8418/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008419{
Victor Stinner8c62be82010-05-06 00:08:46 +00008420 STRUCT_STAT st;
8421 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008423
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008424 do {
8425 Py_BEGIN_ALLOW_THREADS
8426 res = FSTAT(fd, &st);
8427 Py_END_ALLOW_THREADS
8428 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008429 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008430#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008431 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008432#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008433 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008434#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008435 }
Tim Peters5aa91602002-01-30 05:46:57 +00008436
Victor Stinner4195b5c2012-02-08 23:03:19 +01008437 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008438}
8439
Larry Hastings2f936352014-08-05 14:04:04 +10008440
8441/*[clinic input]
8442os.isatty -> bool
8443 fd: int
8444 /
8445
8446Return True if the fd is connected to a terminal.
8447
8448Return True if the file descriptor is an open file descriptor
8449connected to the slave end of a terminal.
8450[clinic start generated code]*/
8451
Larry Hastings2f936352014-08-05 14:04:04 +10008452static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008453os_isatty_impl(PyObject *module, int fd)
8454/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008455{
Steve Dower8fc89802015-04-12 00:26:27 -04008456 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008457 if (!_PyVerify_fd(fd))
8458 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008459 _Py_BEGIN_SUPPRESS_IPH
8460 return_value = isatty(fd);
8461 _Py_END_SUPPRESS_IPH
8462 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008463}
8464
8465
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008466#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008467/*[clinic input]
8468os.pipe
8469
8470Create a pipe.
8471
8472Returns a tuple of two file descriptors:
8473 (read_fd, write_fd)
8474[clinic start generated code]*/
8475
Larry Hastings2f936352014-08-05 14:04:04 +10008476static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008477os_pipe_impl(PyObject *module)
8478/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008479{
Victor Stinner8c62be82010-05-06 00:08:46 +00008480 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008481#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008482 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008483 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008484 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008485#else
8486 int res;
8487#endif
8488
8489#ifdef MS_WINDOWS
8490 attr.nLength = sizeof(attr);
8491 attr.lpSecurityDescriptor = NULL;
8492 attr.bInheritHandle = FALSE;
8493
8494 Py_BEGIN_ALLOW_THREADS
8495 ok = CreatePipe(&read, &write, &attr, 0);
8496 if (ok) {
8497 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8498 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8499 if (fds[0] == -1 || fds[1] == -1) {
8500 CloseHandle(read);
8501 CloseHandle(write);
8502 ok = 0;
8503 }
8504 }
8505 Py_END_ALLOW_THREADS
8506
Victor Stinner8c62be82010-05-06 00:08:46 +00008507 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008508 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008509#else
8510
8511#ifdef HAVE_PIPE2
8512 Py_BEGIN_ALLOW_THREADS
8513 res = pipe2(fds, O_CLOEXEC);
8514 Py_END_ALLOW_THREADS
8515
8516 if (res != 0 && errno == ENOSYS)
8517 {
8518#endif
8519 Py_BEGIN_ALLOW_THREADS
8520 res = pipe(fds);
8521 Py_END_ALLOW_THREADS
8522
8523 if (res == 0) {
8524 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8525 close(fds[0]);
8526 close(fds[1]);
8527 return NULL;
8528 }
8529 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8530 close(fds[0]);
8531 close(fds[1]);
8532 return NULL;
8533 }
8534 }
8535#ifdef HAVE_PIPE2
8536 }
8537#endif
8538
8539 if (res != 0)
8540 return PyErr_SetFromErrno(PyExc_OSError);
8541#endif /* !MS_WINDOWS */
8542 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008543}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008544#endif /* HAVE_PIPE */
8545
Larry Hastings2f936352014-08-05 14:04:04 +10008546
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008547#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008548/*[clinic input]
8549os.pipe2
8550
8551 flags: int
8552 /
8553
8554Create a pipe with flags set atomically.
8555
8556Returns a tuple of two file descriptors:
8557 (read_fd, write_fd)
8558
8559flags can be constructed by ORing together one or more of these values:
8560O_NONBLOCK, O_CLOEXEC.
8561[clinic start generated code]*/
8562
Larry Hastings2f936352014-08-05 14:04:04 +10008563static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008564os_pipe2_impl(PyObject *module, int flags)
8565/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008566{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008567 int fds[2];
8568 int res;
8569
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008570 res = pipe2(fds, flags);
8571 if (res != 0)
8572 return posix_error();
8573 return Py_BuildValue("(ii)", fds[0], fds[1]);
8574}
8575#endif /* HAVE_PIPE2 */
8576
Larry Hastings2f936352014-08-05 14:04:04 +10008577
Ross Lagerwall7807c352011-03-17 20:20:30 +02008578#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008579/*[clinic input]
8580os.writev -> Py_ssize_t
8581 fd: int
8582 buffers: object
8583 /
8584
8585Iterate over buffers, and write the contents of each to a file descriptor.
8586
8587Returns the total number of bytes written.
8588buffers must be a sequence of bytes-like objects.
8589[clinic start generated code]*/
8590
Larry Hastings2f936352014-08-05 14:04:04 +10008591static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008592os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8593/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008594{
8595 int cnt;
8596 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008597 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008598 struct iovec *iov;
8599 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008600
8601 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008602 PyErr_SetString(PyExc_TypeError,
8603 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008604 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008605 }
Larry Hastings2f936352014-08-05 14:04:04 +10008606 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008607
Larry Hastings2f936352014-08-05 14:04:04 +10008608 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8609 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008610 }
8611
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008612 do {
8613 Py_BEGIN_ALLOW_THREADS
8614 result = writev(fd, iov, cnt);
8615 Py_END_ALLOW_THREADS
8616 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008617
8618 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008619 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008620 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008621
Georg Brandl306336b2012-06-24 12:55:33 +02008622 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008623}
Larry Hastings2f936352014-08-05 14:04:04 +10008624#endif /* HAVE_WRITEV */
8625
8626
8627#ifdef HAVE_PWRITE
8628/*[clinic input]
8629os.pwrite -> Py_ssize_t
8630
8631 fd: int
8632 buffer: Py_buffer
8633 offset: Py_off_t
8634 /
8635
8636Write bytes to a file descriptor starting at a particular offset.
8637
8638Write buffer to fd, starting at offset bytes from the beginning of
8639the file. Returns the number of bytes writte. Does not change the
8640current file offset.
8641[clinic start generated code]*/
8642
Larry Hastings2f936352014-08-05 14:04:04 +10008643static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008644os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8645/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008646{
8647 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008649
8650 if (!_PyVerify_fd(fd)) {
8651 posix_error();
8652 return -1;
8653 }
8654
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008655 do {
8656 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008657 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008658 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008659 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008660 Py_END_ALLOW_THREADS
8661 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008662
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008663 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008664 posix_error();
8665 return size;
8666}
8667#endif /* HAVE_PWRITE */
8668
8669
8670#ifdef HAVE_MKFIFO
8671/*[clinic input]
8672os.mkfifo
8673
8674 path: path_t
8675 mode: int=0o666
8676 *
8677 dir_fd: dir_fd(requires='mkfifoat')=None
8678
8679Create a "fifo" (a POSIX named pipe).
8680
8681If dir_fd is not None, it should be a file descriptor open to a directory,
8682 and path should be relative; path will then be relative to that directory.
8683dir_fd may not be implemented on your platform.
8684 If it is unavailable, using it will raise a NotImplementedError.
8685[clinic start generated code]*/
8686
Larry Hastings2f936352014-08-05 14:04:04 +10008687static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008688os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8689/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008690{
8691 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008693
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008694 do {
8695 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008696#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008697 if (dir_fd != DEFAULT_DIR_FD)
8698 result = mkfifoat(dir_fd, path->narrow, mode);
8699 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008700#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008701 result = mkfifo(path->narrow, mode);
8702 Py_END_ALLOW_THREADS
8703 } while (result != 0 && errno == EINTR &&
8704 !(async_err = PyErr_CheckSignals()));
8705 if (result != 0)
8706 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008707
8708 Py_RETURN_NONE;
8709}
8710#endif /* HAVE_MKFIFO */
8711
8712
8713#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8714/*[clinic input]
8715os.mknod
8716
8717 path: path_t
8718 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008719 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008720 *
8721 dir_fd: dir_fd(requires='mknodat')=None
8722
8723Create a node in the file system.
8724
8725Create a node in the file system (file, device special file or named pipe)
8726at path. mode specifies both the permissions to use and the
8727type of node to be created, being combined (bitwise OR) with one of
8728S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8729device defines the newly created device special file (probably using
8730os.makedev()). Otherwise device is ignored.
8731
8732If dir_fd is not None, it should be a file descriptor open to a directory,
8733 and path should be relative; path will then be relative to that directory.
8734dir_fd may not be implemented on your platform.
8735 If it is unavailable, using it will raise a NotImplementedError.
8736[clinic start generated code]*/
8737
Larry Hastings2f936352014-08-05 14:04:04 +10008738static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008739os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008740 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008741/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008742{
8743 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008744 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008745
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 do {
8747 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008748#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 if (dir_fd != DEFAULT_DIR_FD)
8750 result = mknodat(dir_fd, path->narrow, mode, device);
8751 else
Larry Hastings2f936352014-08-05 14:04:04 +10008752#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008753 result = mknod(path->narrow, mode, device);
8754 Py_END_ALLOW_THREADS
8755 } while (result != 0 && errno == EINTR &&
8756 !(async_err = PyErr_CheckSignals()));
8757 if (result != 0)
8758 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008759
8760 Py_RETURN_NONE;
8761}
8762#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8763
8764
8765#ifdef HAVE_DEVICE_MACROS
8766/*[clinic input]
8767os.major -> unsigned_int
8768
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008769 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008770 /
8771
8772Extracts a device major number from a raw device number.
8773[clinic start generated code]*/
8774
Larry Hastings2f936352014-08-05 14:04:04 +10008775static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008776os_major_impl(PyObject *module, dev_t device)
8777/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008778{
8779 return major(device);
8780}
8781
8782
8783/*[clinic input]
8784os.minor -> unsigned_int
8785
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008786 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008787 /
8788
8789Extracts a device minor number from a raw device number.
8790[clinic start generated code]*/
8791
Larry Hastings2f936352014-08-05 14:04:04 +10008792static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008793os_minor_impl(PyObject *module, dev_t device)
8794/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008795{
8796 return minor(device);
8797}
8798
8799
8800/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008801os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008802
8803 major: int
8804 minor: int
8805 /
8806
8807Composes a raw device number from the major and minor device numbers.
8808[clinic start generated code]*/
8809
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008810static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008811os_makedev_impl(PyObject *module, int major, int minor)
8812/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008813{
8814 return makedev(major, minor);
8815}
8816#endif /* HAVE_DEVICE_MACROS */
8817
8818
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008819#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008820/*[clinic input]
8821os.ftruncate
8822
8823 fd: int
8824 length: Py_off_t
8825 /
8826
8827Truncate a file, specified by file descriptor, to a specific length.
8828[clinic start generated code]*/
8829
Larry Hastings2f936352014-08-05 14:04:04 +10008830static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008831os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8832/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008833{
8834 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008835 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008836
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008837 if (!_PyVerify_fd(fd))
8838 return posix_error();
8839
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008840 do {
8841 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008842 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008843#ifdef MS_WINDOWS
8844 result = _chsize_s(fd, length);
8845#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008846 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008847#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008848 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008849 Py_END_ALLOW_THREADS
8850 } while (result != 0 && errno == EINTR &&
8851 !(async_err = PyErr_CheckSignals()));
8852 if (result != 0)
8853 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008854 Py_RETURN_NONE;
8855}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008856#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008857
8858
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008859#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008860/*[clinic input]
8861os.truncate
8862 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8863 length: Py_off_t
8864
8865Truncate a file, specified by path, to a specific length.
8866
8867On some platforms, path may also be specified as an open file descriptor.
8868 If this functionality is unavailable, using it raises an exception.
8869[clinic start generated code]*/
8870
Larry Hastings2f936352014-08-05 14:04:04 +10008871static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008872os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8873/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008874{
8875 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008876#ifdef MS_WINDOWS
8877 int fd;
8878#endif
8879
8880 if (path->fd != -1)
8881 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008882
8883 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008884 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008885#ifdef MS_WINDOWS
8886 if (path->wide)
8887 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008888 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008889 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008890 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008891 result = -1;
8892 else {
8893 result = _chsize_s(fd, length);
8894 close(fd);
8895 if (result < 0)
8896 errno = result;
8897 }
8898#else
8899 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008900#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008901 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008902 Py_END_ALLOW_THREADS
8903 if (result < 0)
8904 return path_error(path);
8905
8906 Py_RETURN_NONE;
8907}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008908#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008909
Ross Lagerwall7807c352011-03-17 20:20:30 +02008910
Victor Stinnerd6b17692014-09-30 12:20:05 +02008911/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8912 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8913 defined, which is the case in Python on AIX. AIX bug report:
8914 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8915#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8916# define POSIX_FADVISE_AIX_BUG
8917#endif
8918
Victor Stinnerec39e262014-09-30 12:35:58 +02008919
Victor Stinnerd6b17692014-09-30 12:20:05 +02008920#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008921/*[clinic input]
8922os.posix_fallocate
8923
8924 fd: int
8925 offset: Py_off_t
8926 length: Py_off_t
8927 /
8928
8929Ensure a file has allocated at least a particular number of bytes on disk.
8930
8931Ensure that the file specified by fd encompasses a range of bytes
8932starting at offset bytes from the beginning and continuing for length bytes.
8933[clinic start generated code]*/
8934
Larry Hastings2f936352014-08-05 14:04:04 +10008935static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008936os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008937 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008938/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008939{
8940 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008941 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008942
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008943 do {
8944 Py_BEGIN_ALLOW_THREADS
8945 result = posix_fallocate(fd, offset, length);
8946 Py_END_ALLOW_THREADS
8947 } while (result != 0 && errno == EINTR &&
8948 !(async_err = PyErr_CheckSignals()));
8949 if (result != 0)
8950 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008951 Py_RETURN_NONE;
8952}
Victor Stinnerec39e262014-09-30 12:35:58 +02008953#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008954
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955
Victor Stinnerd6b17692014-09-30 12:20:05 +02008956#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008957/*[clinic input]
8958os.posix_fadvise
8959
8960 fd: int
8961 offset: Py_off_t
8962 length: Py_off_t
8963 advice: int
8964 /
8965
8966Announce an intention to access data in a specific pattern.
8967
8968Announce an intention to access data in a specific pattern, thus allowing
8969the kernel to make optimizations.
8970The advice applies to the region of the file specified by fd starting at
8971offset and continuing for length bytes.
8972advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8973POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8974POSIX_FADV_DONTNEED.
8975[clinic start generated code]*/
8976
Larry Hastings2f936352014-08-05 14:04:04 +10008977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008978os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008979 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008980/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008981{
8982 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008983 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008984
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985 do {
8986 Py_BEGIN_ALLOW_THREADS
8987 result = posix_fadvise(fd, offset, length, advice);
8988 Py_END_ALLOW_THREADS
8989 } while (result != 0 && errno == EINTR &&
8990 !(async_err = PyErr_CheckSignals()));
8991 if (result != 0)
8992 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008993 Py_RETURN_NONE;
8994}
Victor Stinnerec39e262014-09-30 12:35:58 +02008995#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008996
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008997#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008998
Fred Drake762e2061999-08-26 17:23:54 +00008999/* Save putenv() parameters as values here, so we can collect them when they
9000 * get re-set with another call for the same key. */
9001static PyObject *posix_putenv_garbage;
9002
Larry Hastings2f936352014-08-05 14:04:04 +10009003static void
9004posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009005{
Larry Hastings2f936352014-08-05 14:04:04 +10009006 /* Install the first arg and newstr in posix_putenv_garbage;
9007 * this will cause previous value to be collected. This has to
9008 * happen after the real putenv() call because the old value
9009 * was still accessible until then. */
9010 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9011 /* really not much we can do; just leak */
9012 PyErr_Clear();
9013 else
9014 Py_DECREF(value);
9015}
9016
9017
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009018#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009019/*[clinic input]
9020os.putenv
9021
9022 name: unicode
9023 value: unicode
9024 /
9025
9026Change or add an environment variable.
9027[clinic start generated code]*/
9028
Larry Hastings2f936352014-08-05 14:04:04 +10009029static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009030os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9031/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009032{
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009033 const wchar_t *env;
Larry Hastings2f936352014-08-05 14:04:04 +10009034
9035 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9036 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009037 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009038 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009039 }
Larry Hastings2f936352014-08-05 14:04:04 +10009040 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009041 PyErr_Format(PyExc_ValueError,
9042 "the environment variable is longer than %u characters",
9043 _MAX_ENV);
9044 goto error;
9045 }
9046
Larry Hastings2f936352014-08-05 14:04:04 +10009047 env = PyUnicode_AsUnicode(unicode);
9048 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009049 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009050 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009052 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009054
Larry Hastings2f936352014-08-05 14:04:04 +10009055 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009056 Py_RETURN_NONE;
9057
9058error:
Larry Hastings2f936352014-08-05 14:04:04 +10009059 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009060 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009061}
Larry Hastings2f936352014-08-05 14:04:04 +10009062#else /* MS_WINDOWS */
9063/*[clinic input]
9064os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009065
Larry Hastings2f936352014-08-05 14:04:04 +10009066 name: FSConverter
9067 value: FSConverter
9068 /
9069
9070Change or add an environment variable.
9071[clinic start generated code]*/
9072
Larry Hastings2f936352014-08-05 14:04:04 +10009073static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009074os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9075/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009076{
9077 PyObject *bytes = NULL;
9078 char *env;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +03009079 const char *name_string = PyBytes_AsString(name);
9080 const char *value_string = PyBytes_AsString(value);
Larry Hastings2f936352014-08-05 14:04:04 +10009081
9082 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9083 if (bytes == NULL) {
9084 PyErr_NoMemory();
9085 return NULL;
9086 }
9087
9088 env = PyBytes_AS_STRING(bytes);
9089 if (putenv(env)) {
9090 Py_DECREF(bytes);
9091 return posix_error();
9092 }
9093
9094 posix_putenv_garbage_setitem(name, bytes);
9095 Py_RETURN_NONE;
9096}
9097#endif /* MS_WINDOWS */
9098#endif /* HAVE_PUTENV */
9099
9100
9101#ifdef HAVE_UNSETENV
9102/*[clinic input]
9103os.unsetenv
9104 name: FSConverter
9105 /
9106
9107Delete an environment variable.
9108[clinic start generated code]*/
9109
Larry Hastings2f936352014-08-05 14:04:04 +10009110static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009111os_unsetenv_impl(PyObject *module, PyObject *name)
9112/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009113{
Victor Stinner984890f2011-11-24 13:53:38 +01009114#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009115 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009116#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009117
Victor Stinner984890f2011-11-24 13:53:38 +01009118#ifdef HAVE_BROKEN_UNSETENV
9119 unsetenv(PyBytes_AS_STRING(name));
9120#else
Victor Stinner65170952011-11-22 22:16:17 +01009121 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009122 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009123 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009124#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 /* Remove the key from posix_putenv_garbage;
9127 * this will cause it to be collected. This has to
9128 * happen after the real unsetenv() call because the
9129 * old value was still accessible until then.
9130 */
Victor Stinner65170952011-11-22 22:16:17 +01009131 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 /* really not much we can do; just leak */
9133 PyErr_Clear();
9134 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009135 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009136}
Larry Hastings2f936352014-08-05 14:04:04 +10009137#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009138
Larry Hastings2f936352014-08-05 14:04:04 +10009139
9140/*[clinic input]
9141os.strerror
9142
9143 code: int
9144 /
9145
9146Translate an error code to a message string.
9147[clinic start generated code]*/
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009150os_strerror_impl(PyObject *module, int code)
9151/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009152{
9153 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 if (message == NULL) {
9155 PyErr_SetString(PyExc_ValueError,
9156 "strerror() argument out of range");
9157 return NULL;
9158 }
Victor Stinner1b579672011-12-17 05:47:23 +01009159 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009160}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009161
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009162
Guido van Rossumc9641791998-08-04 15:26:23 +00009163#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009164#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009165/*[clinic input]
9166os.WCOREDUMP -> bool
9167
9168 status: int
9169 /
9170
9171Return True if the process returning status was dumped to a core file.
9172[clinic start generated code]*/
9173
Larry Hastings2f936352014-08-05 14:04:04 +10009174static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009175os_WCOREDUMP_impl(PyObject *module, int status)
9176/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009177{
9178 WAIT_TYPE wait_status;
9179 WAIT_STATUS_INT(wait_status) = status;
9180 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009181}
9182#endif /* WCOREDUMP */
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184
Fred Drake106c1a02002-04-23 15:58:02 +00009185#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009186/*[clinic input]
9187os.WIFCONTINUED -> bool
9188
9189 status: int
9190
9191Return True if a particular process was continued from a job control stop.
9192
9193Return True if the process returning status was continued from a
9194job control stop.
9195[clinic start generated code]*/
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009198os_WIFCONTINUED_impl(PyObject *module, int status)
9199/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009200{
9201 WAIT_TYPE wait_status;
9202 WAIT_STATUS_INT(wait_status) = status;
9203 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009204}
9205#endif /* WIFCONTINUED */
9206
Larry Hastings2f936352014-08-05 14:04:04 +10009207
Guido van Rossumc9641791998-08-04 15:26:23 +00009208#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009209/*[clinic input]
9210os.WIFSTOPPED -> bool
9211
9212 status: int
9213
9214Return True if the process returning status was stopped.
9215[clinic start generated code]*/
9216
Larry Hastings2f936352014-08-05 14:04:04 +10009217static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009218os_WIFSTOPPED_impl(PyObject *module, int status)
9219/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009220{
9221 WAIT_TYPE wait_status;
9222 WAIT_STATUS_INT(wait_status) = status;
9223 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009224}
9225#endif /* WIFSTOPPED */
9226
Larry Hastings2f936352014-08-05 14:04:04 +10009227
Guido van Rossumc9641791998-08-04 15:26:23 +00009228#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009229/*[clinic input]
9230os.WIFSIGNALED -> bool
9231
9232 status: int
9233
9234Return True if the process returning status was terminated by a signal.
9235[clinic start generated code]*/
9236
Larry Hastings2f936352014-08-05 14:04:04 +10009237static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009238os_WIFSIGNALED_impl(PyObject *module, int status)
9239/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009240{
9241 WAIT_TYPE wait_status;
9242 WAIT_STATUS_INT(wait_status) = status;
9243 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009244}
9245#endif /* WIFSIGNALED */
9246
Larry Hastings2f936352014-08-05 14:04:04 +10009247
Guido van Rossumc9641791998-08-04 15:26:23 +00009248#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009249/*[clinic input]
9250os.WIFEXITED -> bool
9251
9252 status: int
9253
9254Return True if the process returning status exited via the exit() system call.
9255[clinic start generated code]*/
9256
Larry Hastings2f936352014-08-05 14:04:04 +10009257static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009258os_WIFEXITED_impl(PyObject *module, int status)
9259/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009260{
9261 WAIT_TYPE wait_status;
9262 WAIT_STATUS_INT(wait_status) = status;
9263 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009264}
9265#endif /* WIFEXITED */
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009268#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009269/*[clinic input]
9270os.WEXITSTATUS -> int
9271
9272 status: int
9273
9274Return the process return code from status.
9275[clinic start generated code]*/
9276
Larry Hastings2f936352014-08-05 14:04:04 +10009277static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009278os_WEXITSTATUS_impl(PyObject *module, int status)
9279/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009280{
9281 WAIT_TYPE wait_status;
9282 WAIT_STATUS_INT(wait_status) = status;
9283 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009284}
9285#endif /* WEXITSTATUS */
9286
Larry Hastings2f936352014-08-05 14:04:04 +10009287
Guido van Rossumc9641791998-08-04 15:26:23 +00009288#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009289/*[clinic input]
9290os.WTERMSIG -> int
9291
9292 status: int
9293
9294Return the signal that terminated the process that provided the status value.
9295[clinic start generated code]*/
9296
Larry Hastings2f936352014-08-05 14:04:04 +10009297static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009298os_WTERMSIG_impl(PyObject *module, int status)
9299/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009300{
9301 WAIT_TYPE wait_status;
9302 WAIT_STATUS_INT(wait_status) = status;
9303 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009304}
9305#endif /* WTERMSIG */
9306
Larry Hastings2f936352014-08-05 14:04:04 +10009307
Guido van Rossumc9641791998-08-04 15:26:23 +00009308#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009309/*[clinic input]
9310os.WSTOPSIG -> int
9311
9312 status: int
9313
9314Return the signal that stopped the process that provided the status value.
9315[clinic start generated code]*/
9316
Larry Hastings2f936352014-08-05 14:04:04 +10009317static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009318os_WSTOPSIG_impl(PyObject *module, int status)
9319/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009320{
9321 WAIT_TYPE wait_status;
9322 WAIT_STATUS_INT(wait_status) = status;
9323 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009324}
9325#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009326#endif /* HAVE_SYS_WAIT_H */
9327
9328
Thomas Wouters477c8d52006-05-27 19:21:47 +00009329#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009330#ifdef _SCO_DS
9331/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9332 needed definitions in sys/statvfs.h */
9333#define _SVID3
9334#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009335#include <sys/statvfs.h>
9336
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009337static PyObject*
9338_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9340 if (v == NULL)
9341 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009342
9343#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9345 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9346 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9347 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9348 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9349 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9350 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9351 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9352 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9353 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009354#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9356 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9357 PyStructSequence_SET_ITEM(v, 2,
9358 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9359 PyStructSequence_SET_ITEM(v, 3,
9360 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9361 PyStructSequence_SET_ITEM(v, 4,
9362 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9363 PyStructSequence_SET_ITEM(v, 5,
9364 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9365 PyStructSequence_SET_ITEM(v, 6,
9366 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9367 PyStructSequence_SET_ITEM(v, 7,
9368 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9369 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9370 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009371#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009372 if (PyErr_Occurred()) {
9373 Py_DECREF(v);
9374 return NULL;
9375 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009376
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009378}
9379
Larry Hastings2f936352014-08-05 14:04:04 +10009380
9381/*[clinic input]
9382os.fstatvfs
9383 fd: int
9384 /
9385
9386Perform an fstatvfs system call on the given fd.
9387
9388Equivalent to statvfs(fd).
9389[clinic start generated code]*/
9390
Larry Hastings2f936352014-08-05 14:04:04 +10009391static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009392os_fstatvfs_impl(PyObject *module, int fd)
9393/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009394{
9395 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009396 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009398
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009399 do {
9400 Py_BEGIN_ALLOW_THREADS
9401 result = fstatvfs(fd, &st);
9402 Py_END_ALLOW_THREADS
9403 } while (result != 0 && errno == EINTR &&
9404 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009405 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009406 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009407
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009409}
Larry Hastings2f936352014-08-05 14:04:04 +10009410#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009411
9412
Thomas Wouters477c8d52006-05-27 19:21:47 +00009413#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009414#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009415/*[clinic input]
9416os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009417
Larry Hastings2f936352014-08-05 14:04:04 +10009418 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9419
9420Perform a statvfs system call on the given path.
9421
9422path may always be specified as a string.
9423On some platforms, path may also be specified as an open file descriptor.
9424 If this functionality is unavailable, using it raises an exception.
9425[clinic start generated code]*/
9426
Larry Hastings2f936352014-08-05 14:04:04 +10009427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009428os_statvfs_impl(PyObject *module, path_t *path)
9429/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009430{
9431 int result;
9432 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009433
9434 Py_BEGIN_ALLOW_THREADS
9435#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009436 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009437#ifdef __APPLE__
9438 /* handle weak-linking on Mac OS X 10.3 */
9439 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009440 fd_specified("statvfs", path->fd);
9441 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009442 }
9443#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009444 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009445 }
9446 else
9447#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009448 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009449 Py_END_ALLOW_THREADS
9450
9451 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009452 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009453 }
9454
Larry Hastings2f936352014-08-05 14:04:04 +10009455 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009456}
Larry Hastings2f936352014-08-05 14:04:04 +10009457#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9458
Guido van Rossum94f6f721999-01-06 18:42:14 +00009459
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009460#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009461/*[clinic input]
9462os._getdiskusage
9463
9464 path: Py_UNICODE
9465
9466Return disk usage statistics about the given path as a (total, free) tuple.
9467[clinic start generated code]*/
9468
Larry Hastings2f936352014-08-05 14:04:04 +10009469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009470os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9471/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009472{
9473 BOOL retval;
9474 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009475
9476 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009477 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009478 Py_END_ALLOW_THREADS
9479 if (retval == 0)
9480 return PyErr_SetFromWindowsErr(0);
9481
9482 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9483}
Larry Hastings2f936352014-08-05 14:04:04 +10009484#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009485
9486
Fred Drakec9680921999-12-13 16:37:25 +00009487/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9488 * It maps strings representing configuration variable names to
9489 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009490 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009491 * rarely-used constants. There are three separate tables that use
9492 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009493 *
9494 * This code is always included, even if none of the interfaces that
9495 * need it are included. The #if hackery needed to avoid it would be
9496 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009497 */
9498struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009499 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009500 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009501};
9502
Fred Drake12c6e2d1999-12-14 21:25:03 +00009503static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009504conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009505 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009506{
Christian Heimes217cfd12007-12-02 14:31:20 +00009507 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009508 int value = _PyLong_AsInt(arg);
9509 if (value == -1 && PyErr_Occurred())
9510 return 0;
9511 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009512 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009513 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009514 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009515 /* look up the value in the table using a binary search */
9516 size_t lo = 0;
9517 size_t mid;
9518 size_t hi = tablesize;
9519 int cmp;
9520 const char *confname;
9521 if (!PyUnicode_Check(arg)) {
9522 PyErr_SetString(PyExc_TypeError,
9523 "configuration names must be strings or integers");
9524 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009526 confname = _PyUnicode_AsString(arg);
9527 if (confname == NULL)
9528 return 0;
9529 while (lo < hi) {
9530 mid = (lo + hi) / 2;
9531 cmp = strcmp(confname, table[mid].name);
9532 if (cmp < 0)
9533 hi = mid;
9534 else if (cmp > 0)
9535 lo = mid + 1;
9536 else {
9537 *valuep = table[mid].value;
9538 return 1;
9539 }
9540 }
9541 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9542 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009544}
9545
9546
9547#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9548static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009549#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009551#endif
9552#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009554#endif
Fred Drakec9680921999-12-13 16:37:25 +00009555#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009600#ifdef _PC_ACL_ENABLED
9601 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9602#endif
9603#ifdef _PC_MIN_HOLE_SIZE
9604 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9605#endif
9606#ifdef _PC_ALLOC_SIZE_MIN
9607 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9608#endif
9609#ifdef _PC_REC_INCR_XFER_SIZE
9610 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9611#endif
9612#ifdef _PC_REC_MAX_XFER_SIZE
9613 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9614#endif
9615#ifdef _PC_REC_MIN_XFER_SIZE
9616 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9617#endif
9618#ifdef _PC_REC_XFER_ALIGN
9619 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9620#endif
9621#ifdef _PC_SYMLINK_MAX
9622 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9623#endif
9624#ifdef _PC_XATTR_ENABLED
9625 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9626#endif
9627#ifdef _PC_XATTR_EXISTS
9628 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9629#endif
9630#ifdef _PC_TIMESTAMP_RESOLUTION
9631 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9632#endif
Fred Drakec9680921999-12-13 16:37:25 +00009633};
9634
Fred Drakec9680921999-12-13 16:37:25 +00009635static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009636conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009637{
9638 return conv_confname(arg, valuep, posix_constants_pathconf,
9639 sizeof(posix_constants_pathconf)
9640 / sizeof(struct constdef));
9641}
9642#endif
9643
Larry Hastings2f936352014-08-05 14:04:04 +10009644
Fred Drakec9680921999-12-13 16:37:25 +00009645#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009646/*[clinic input]
9647os.fpathconf -> long
9648
9649 fd: int
9650 name: path_confname
9651 /
9652
9653Return the configuration limit name for the file descriptor fd.
9654
9655If there is no limit, return -1.
9656[clinic start generated code]*/
9657
Larry Hastings2f936352014-08-05 14:04:04 +10009658static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009659os_fpathconf_impl(PyObject *module, int fd, int name)
9660/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009661{
9662 long limit;
9663
9664 errno = 0;
9665 limit = fpathconf(fd, name);
9666 if (limit == -1 && errno != 0)
9667 posix_error();
9668
9669 return limit;
9670}
9671#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009672
9673
9674#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009675/*[clinic input]
9676os.pathconf -> long
9677 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9678 name: path_confname
9679
9680Return the configuration limit name for the file or directory path.
9681
9682If there is no limit, return -1.
9683On some platforms, path may also be specified as an open file descriptor.
9684 If this functionality is unavailable, using it raises an exception.
9685[clinic start generated code]*/
9686
Larry Hastings2f936352014-08-05 14:04:04 +10009687static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009688os_pathconf_impl(PyObject *module, path_t *path, int name)
9689/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009690{
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009692
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009694#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009695 if (path->fd != -1)
9696 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009697 else
9698#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009699 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 if (limit == -1 && errno != 0) {
9701 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009702 /* could be a path or name problem */
9703 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009704 else
Larry Hastings2f936352014-08-05 14:04:04 +10009705 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 }
Larry Hastings2f936352014-08-05 14:04:04 +10009707
9708 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009709}
Larry Hastings2f936352014-08-05 14:04:04 +10009710#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009711
9712#ifdef HAVE_CONFSTR
9713static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009714#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009717#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009719#endif
9720#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009722#endif
Fred Draked86ed291999-12-15 15:34:33 +00009723#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009725#endif
9726#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009728#endif
9729#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009731#endif
9732#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009734#endif
Fred Drakec9680921999-12-13 16:37:25 +00009735#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
Fred Draked86ed291999-12-15 15:34:33 +00009759#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009761#endif
Fred Drakec9680921999-12-13 16:37:25 +00009762#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
Fred Draked86ed291999-12-15 15:34:33 +00009765#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009767#endif
9768#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009770#endif
9771#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009773#endif
9774#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009776#endif
Fred Drakec9680921999-12-13 16:37:25 +00009777#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
Fred Draked86ed291999-12-15 15:34:33 +00009825#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009827#endif
9828#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009830#endif
9831#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009833#endif
9834#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009836#endif
9837#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009839#endif
9840#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009842#endif
9843#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009845#endif
9846#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009848#endif
9849#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009851#endif
9852#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009854#endif
9855#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009857#endif
9858#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009860#endif
9861#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009863#endif
Fred Drakec9680921999-12-13 16:37:25 +00009864};
9865
9866static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009867conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009868{
9869 return conv_confname(arg, valuep, posix_constants_confstr,
9870 sizeof(posix_constants_confstr)
9871 / sizeof(struct constdef));
9872}
9873
Larry Hastings2f936352014-08-05 14:04:04 +10009874
9875/*[clinic input]
9876os.confstr
9877
9878 name: confstr_confname
9879 /
9880
9881Return a string-valued system configuration variable.
9882[clinic start generated code]*/
9883
Larry Hastings2f936352014-08-05 14:04:04 +10009884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009885os_confstr_impl(PyObject *module, int name)
9886/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009887{
9888 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009889 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009890 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009891
Victor Stinnercb043522010-09-10 23:49:04 +00009892 errno = 0;
9893 len = confstr(name, buffer, sizeof(buffer));
9894 if (len == 0) {
9895 if (errno) {
9896 posix_error();
9897 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009898 }
9899 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009900 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009901 }
9902 }
Victor Stinnercb043522010-09-10 23:49:04 +00009903
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009904 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009905 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009906 char *buf = PyMem_Malloc(len);
9907 if (buf == NULL)
9908 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009909 len2 = confstr(name, buf, len);
9910 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009911 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009912 PyMem_Free(buf);
9913 }
9914 else
9915 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009916 return result;
9917}
Larry Hastings2f936352014-08-05 14:04:04 +10009918#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009919
9920
9921#ifdef HAVE_SYSCONF
9922static struct constdef posix_constants_sysconf[] = {
9923#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
Fred Draked86ed291999-12-15 15:34:33 +00009953#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009955#endif
9956#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009958#endif
Fred Drakec9680921999-12-13 16:37:25 +00009959#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
Fred Drakec9680921999-12-13 16:37:25 +00009962#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
Fred Draked86ed291999-12-15 15:34:33 +00009977#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009979#endif
Fred Drakec9680921999-12-13 16:37:25 +00009980#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
Fred Draked86ed291999-12-15 15:34:33 +00009995#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009997#endif
Fred Drakec9680921999-12-13 16:37:25 +00009998#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
Fred Draked86ed291999-12-15 15:34:33 +000010067#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010069#endif
Fred Drakec9680921999-12-13 16:37:25 +000010070#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
Fred Draked86ed291999-12-15 15:34:33 +000010079#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010081#endif
Fred Drakec9680921999-12-13 16:37:25 +000010082#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
Fred Draked86ed291999-12-15 15:34:33 +000010085#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010087#endif
10088#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010090#endif
Fred Drakec9680921999-12-13 16:37:25 +000010091#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
Fred Draked86ed291999-12-15 15:34:33 +000010103#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010105#endif
Fred Drakec9680921999-12-13 16:37:25 +000010106#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
Fred Draked86ed291999-12-15 15:34:33 +000010127#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010129#endif
Fred Drakec9680921999-12-13 16:37:25 +000010130#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
Fred Draked86ed291999-12-15 15:34:33 +000010136#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010138#endif
Fred Drakec9680921999-12-13 16:37:25 +000010139#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
Fred Draked86ed291999-12-15 15:34:33 +000010166#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010168#endif
10169#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010171#endif
Fred Drakec9680921999-12-13 16:37:25 +000010172#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
Fred Draked86ed291999-12-15 15:34:33 +000010277#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010279#endif
Fred Drakec9680921999-12-13 16:37:25 +000010280#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415};
10416
10417static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010418conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010419{
10420 return conv_confname(arg, valuep, posix_constants_sysconf,
10421 sizeof(posix_constants_sysconf)
10422 / sizeof(struct constdef));
10423}
10424
Larry Hastings2f936352014-08-05 14:04:04 +100010425
10426/*[clinic input]
10427os.sysconf -> long
10428 name: sysconf_confname
10429 /
10430
10431Return an integer-valued system configuration variable.
10432[clinic start generated code]*/
10433
Larry Hastings2f936352014-08-05 14:04:04 +100010434static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010435os_sysconf_impl(PyObject *module, int name)
10436/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010437{
10438 long value;
10439
10440 errno = 0;
10441 value = sysconf(name);
10442 if (value == -1 && errno != 0)
10443 posix_error();
10444 return value;
10445}
10446#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010447
10448
Fred Drakebec628d1999-12-15 18:31:10 +000010449/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010450 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010451 * the exported dictionaries that are used to publish information about the
10452 * names available on the host platform.
10453 *
10454 * Sorting the table at runtime ensures that the table is properly ordered
10455 * when used, even for platforms we're not able to test on. It also makes
10456 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010457 */
Fred Drakebec628d1999-12-15 18:31:10 +000010458
10459static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010460cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010461{
10462 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010464 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010466
10467 return strcmp(c1->name, c2->name);
10468}
10469
10470static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010471setup_confname_table(struct constdef *table, size_t tablesize,
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010472 const char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010473{
Fred Drakebec628d1999-12-15 18:31:10 +000010474 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010475 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010476
10477 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10478 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010479 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010481
Barry Warsaw3155db32000-04-13 15:20:40 +000010482 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 PyObject *o = PyLong_FromLong(table[i].value);
10484 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10485 Py_XDECREF(o);
10486 Py_DECREF(d);
10487 return -1;
10488 }
10489 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010490 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010491 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010492}
10493
Fred Drakebec628d1999-12-15 18:31:10 +000010494/* Return -1 on failure, 0 on success. */
10495static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010496setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010497{
10498#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010499 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010500 sizeof(posix_constants_pathconf)
10501 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010502 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010503 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010504#endif
10505#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010506 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010507 sizeof(posix_constants_confstr)
10508 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010509 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010510 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010511#endif
10512#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010513 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010514 sizeof(posix_constants_sysconf)
10515 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010516 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010517 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010518#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010519 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010520}
Fred Draked86ed291999-12-15 15:34:33 +000010521
10522
Larry Hastings2f936352014-08-05 14:04:04 +100010523/*[clinic input]
10524os.abort
10525
10526Abort the interpreter immediately.
10527
10528This function 'dumps core' or otherwise fails in the hardest way possible
10529on the hosting operating system. This function never returns.
10530[clinic start generated code]*/
10531
Larry Hastings2f936352014-08-05 14:04:04 +100010532static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010533os_abort_impl(PyObject *module)
10534/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010535{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010536 abort();
10537 /*NOTREACHED*/
10538 Py_FatalError("abort() called from Python code didn't abort!");
10539 return NULL;
10540}
Fred Drakebec628d1999-12-15 18:31:10 +000010541
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010542#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010543/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010544PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010545"startfile(filepath [, operation])\n\
10546\n\
10547Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010548\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010549When \"operation\" is not specified or \"open\", this acts like\n\
10550double-clicking the file in Explorer, or giving the file name as an\n\
10551argument to the DOS \"start\" command: the file is opened with whatever\n\
10552application (if any) its extension is associated.\n\
10553When another \"operation\" is given, it specifies what should be done with\n\
10554the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010555\n\
10556startfile returns as soon as the associated application is launched.\n\
10557There is no option to wait for the application to close, and no way\n\
10558to retrieve the application's exit status.\n\
10559\n\
10560The filepath is relative to the current directory. If you want to use\n\
10561an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010562the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010563
Steve Dower7d0e0c92015-01-24 08:18:24 -080010564/* Grab ShellExecute dynamically from shell32 */
10565static int has_ShellExecute = -1;
10566static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10567 LPCSTR, INT);
10568static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10569 LPCWSTR, INT);
10570static int
10571check_ShellExecute()
10572{
10573 HINSTANCE hShell32;
10574
10575 /* only recheck */
10576 if (-1 == has_ShellExecute) {
10577 Py_BEGIN_ALLOW_THREADS
10578 hShell32 = LoadLibraryW(L"SHELL32");
10579 Py_END_ALLOW_THREADS
10580 if (hShell32) {
10581 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10582 "ShellExecuteA");
10583 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10584 "ShellExecuteW");
10585 has_ShellExecute = Py_ShellExecuteA &&
10586 Py_ShellExecuteW;
10587 } else {
10588 has_ShellExecute = 0;
10589 }
10590 }
10591 return has_ShellExecute;
10592}
10593
10594
Tim Petersf58a7aa2000-09-22 10:05:54 +000010595static PyObject *
10596win32_startfile(PyObject *self, PyObject *args)
10597{
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 PyObject *ofilepath;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030010599 const char *filepath;
10600 const char *operation = NULL;
10601 const wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010603
Victor Stinnereb5657a2011-09-30 01:44:27 +020010604 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010605
10606 if(!check_ShellExecute()) {
10607 /* If the OS doesn't have ShellExecute, return a
10608 NotImplementedError. */
10609 return PyErr_Format(PyExc_NotImplementedError,
10610 "startfile not available on this platform");
10611 }
10612
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 if (!PyArg_ParseTuple(args, "U|s:startfile",
10614 &unipath, &operation)) {
10615 PyErr_Clear();
10616 goto normal;
10617 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010618
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010620 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010622 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 PyErr_Clear();
10624 operation = NULL;
10625 goto normal;
10626 }
10627 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010628
Victor Stinnereb5657a2011-09-30 01:44:27 +020010629 wpath = PyUnicode_AsUnicode(unipath);
10630 if (wpath == NULL)
10631 goto normal;
10632 if (uoperation) {
10633 woperation = PyUnicode_AsUnicode(uoperation);
10634 if (woperation == NULL)
10635 goto normal;
10636 }
10637 else
10638 woperation = NULL;
10639
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010641 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10642 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 Py_END_ALLOW_THREADS
10644
Victor Stinnereb5657a2011-09-30 01:44:27 +020010645 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010647 win32_error_object("startfile", unipath);
10648 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 }
10650 Py_INCREF(Py_None);
10651 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010652
10653normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10655 PyUnicode_FSConverter, &ofilepath,
10656 &operation))
10657 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010658 if (win32_warn_bytes_api()) {
10659 Py_DECREF(ofilepath);
10660 return NULL;
10661 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 filepath = PyBytes_AsString(ofilepath);
10663 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010664 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10665 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 Py_END_ALLOW_THREADS
10667 if (rc <= (HINSTANCE)32) {
10668 PyObject *errval = win32_error("startfile", filepath);
10669 Py_DECREF(ofilepath);
10670 return errval;
10671 }
10672 Py_DECREF(ofilepath);
10673 Py_INCREF(Py_None);
10674 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010675}
Larry Hastings2f936352014-08-05 14:04:04 +100010676#endif /* MS_WINDOWS */
10677
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010678
Martin v. Löwis438b5342002-12-27 10:16:42 +000010679#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010680/*[clinic input]
10681os.getloadavg
10682
10683Return average recent system load information.
10684
10685Return the number of processes in the system run queue averaged over
10686the last 1, 5, and 15 minutes as a tuple of three floats.
10687Raises OSError if the load average was unobtainable.
10688[clinic start generated code]*/
10689
Larry Hastings2f936352014-08-05 14:04:04 +100010690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010691os_getloadavg_impl(PyObject *module)
10692/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010693{
10694 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010695 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010696 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10697 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010698 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010699 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010700}
Larry Hastings2f936352014-08-05 14:04:04 +100010701#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010702
Larry Hastings2f936352014-08-05 14:04:04 +100010703
10704/*[clinic input]
10705os.device_encoding
10706 fd: int
10707
10708Return a string describing the encoding of a terminal's file descriptor.
10709
10710The file descriptor must be attached to a terminal.
10711If the device is not a terminal, return None.
10712[clinic start generated code]*/
10713
Larry Hastings2f936352014-08-05 14:04:04 +100010714static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010715os_device_encoding_impl(PyObject *module, int fd)
10716/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010717{
Brett Cannonefb00c02012-02-29 18:31:31 -050010718 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010719}
10720
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010721
Larry Hastings2f936352014-08-05 14:04:04 +100010722#ifdef HAVE_SETRESUID
10723/*[clinic input]
10724os.setresuid
10725
10726 ruid: uid_t
10727 euid: uid_t
10728 suid: uid_t
10729 /
10730
10731Set the current process's real, effective, and saved user ids.
10732[clinic start generated code]*/
10733
Larry Hastings2f936352014-08-05 14:04:04 +100010734static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010735os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10736/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010737{
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 if (setresuid(ruid, euid, suid) < 0)
10739 return posix_error();
10740 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010741}
Larry Hastings2f936352014-08-05 14:04:04 +100010742#endif /* HAVE_SETRESUID */
10743
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010744
10745#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010746/*[clinic input]
10747os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010748
Larry Hastings2f936352014-08-05 14:04:04 +100010749 rgid: gid_t
10750 egid: gid_t
10751 sgid: gid_t
10752 /
10753
10754Set the current process's real, effective, and saved group ids.
10755[clinic start generated code]*/
10756
Larry Hastings2f936352014-08-05 14:04:04 +100010757static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010758os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10759/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010760{
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 if (setresgid(rgid, egid, sgid) < 0)
10762 return posix_error();
10763 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010764}
Larry Hastings2f936352014-08-05 14:04:04 +100010765#endif /* HAVE_SETRESGID */
10766
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010767
10768#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010769/*[clinic input]
10770os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010771
Larry Hastings2f936352014-08-05 14:04:04 +100010772Return a tuple of the current process's real, effective, and saved user ids.
10773[clinic start generated code]*/
10774
Larry Hastings2f936352014-08-05 14:04:04 +100010775static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010776os_getresuid_impl(PyObject *module)
10777/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010778{
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 if (getresuid(&ruid, &euid, &suid) < 0)
10781 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010782 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10783 _PyLong_FromUid(euid),
10784 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010785}
Larry Hastings2f936352014-08-05 14:04:04 +100010786#endif /* HAVE_GETRESUID */
10787
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010788
10789#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010790/*[clinic input]
10791os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010792
Larry Hastings2f936352014-08-05 14:04:04 +100010793Return a tuple of the current process's real, effective, and saved group ids.
10794[clinic start generated code]*/
10795
Larry Hastings2f936352014-08-05 14:04:04 +100010796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010797os_getresgid_impl(PyObject *module)
10798/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010799{
10800 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 if (getresgid(&rgid, &egid, &sgid) < 0)
10802 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010803 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10804 _PyLong_FromGid(egid),
10805 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010806}
Larry Hastings2f936352014-08-05 14:04:04 +100010807#endif /* HAVE_GETRESGID */
10808
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010809
Benjamin Peterson9428d532011-09-14 11:45:52 -040010810#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010811/*[clinic input]
10812os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010813
Larry Hastings2f936352014-08-05 14:04:04 +100010814 path: path_t(allow_fd=True)
10815 attribute: path_t
10816 *
10817 follow_symlinks: bool = True
10818
10819Return the value of extended attribute attribute on path.
10820
10821path may be either a string or an open file descriptor.
10822If follow_symlinks is False, and the last element of the path is a symbolic
10823 link, getxattr will examine the symbolic link itself instead of the file
10824 the link points to.
10825
10826[clinic start generated code]*/
10827
Larry Hastings2f936352014-08-05 14:04:04 +100010828static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010829os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010830 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010831/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010832{
10833 Py_ssize_t i;
10834 PyObject *buffer = NULL;
10835
10836 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10837 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010838
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 for (i = 0; ; i++) {
10840 void *ptr;
10841 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010842 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 Py_ssize_t buffer_size = buffer_sizes[i];
10844 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010845 path_error(path);
10846 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010847 }
10848 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10849 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010850 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010851 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010852
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010854 if (path->fd >= 0)
10855 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010856 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010857 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858 else
Larry Hastings2f936352014-08-05 14:04:04 +100010859 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010861
Larry Hastings9cf065c2012-06-22 16:30:09 -070010862 if (result < 0) {
10863 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 if (errno == ERANGE)
10865 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010866 path_error(path);
10867 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010868 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010869
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 if (result != buffer_size) {
10871 /* Can only shrink. */
10872 _PyBytes_Resize(&buffer, result);
10873 }
10874 break;
10875 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010876
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010878}
10879
Larry Hastings2f936352014-08-05 14:04:04 +100010880
10881/*[clinic input]
10882os.setxattr
10883
10884 path: path_t(allow_fd=True)
10885 attribute: path_t
10886 value: Py_buffer
10887 flags: int = 0
10888 *
10889 follow_symlinks: bool = True
10890
10891Set extended attribute attribute on path to value.
10892
10893path may be either a string or an open file descriptor.
10894If follow_symlinks is False, and the last element of the path is a symbolic
10895 link, setxattr will modify the symbolic link itself instead of the file
10896 the link points to.
10897
10898[clinic start generated code]*/
10899
Benjamin Peterson799bd802011-08-31 22:15:17 -040010900static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010901os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010902 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010903/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904{
Larry Hastings2f936352014-08-05 14:04:04 +100010905 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010906
Larry Hastings2f936352014-08-05 14:04:04 +100010907 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010909
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010911 if (path->fd > -1)
10912 result = fsetxattr(path->fd, attribute->narrow,
10913 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010914 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010915 result = setxattr(path->narrow, attribute->narrow,
10916 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010917 else
Larry Hastings2f936352014-08-05 14:04:04 +100010918 result = lsetxattr(path->narrow, attribute->narrow,
10919 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010920 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010921
Larry Hastings9cf065c2012-06-22 16:30:09 -070010922 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010923 path_error(path);
10924 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010925 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010926
Larry Hastings2f936352014-08-05 14:04:04 +100010927 Py_RETURN_NONE;
10928}
10929
10930
10931/*[clinic input]
10932os.removexattr
10933
10934 path: path_t(allow_fd=True)
10935 attribute: path_t
10936 *
10937 follow_symlinks: bool = True
10938
10939Remove extended attribute attribute on path.
10940
10941path may be either a string or an open file descriptor.
10942If follow_symlinks is False, and the last element of the path is a symbolic
10943 link, removexattr will modify the symbolic link itself instead of the file
10944 the link points to.
10945
10946[clinic start generated code]*/
10947
Larry Hastings2f936352014-08-05 14:04:04 +100010948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010949os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010950 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010951/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010952{
10953 ssize_t result;
10954
10955 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10956 return NULL;
10957
10958 Py_BEGIN_ALLOW_THREADS;
10959 if (path->fd > -1)
10960 result = fremovexattr(path->fd, attribute->narrow);
10961 else if (follow_symlinks)
10962 result = removexattr(path->narrow, attribute->narrow);
10963 else
10964 result = lremovexattr(path->narrow, attribute->narrow);
10965 Py_END_ALLOW_THREADS;
10966
10967 if (result) {
10968 return path_error(path);
10969 }
10970
10971 Py_RETURN_NONE;
10972}
10973
10974
10975/*[clinic input]
10976os.listxattr
10977
10978 path: path_t(allow_fd=True, nullable=True) = None
10979 *
10980 follow_symlinks: bool = True
10981
10982Return a list of extended attributes on path.
10983
10984path may be either None, a string, or an open file descriptor.
10985if path is None, listxattr will examine the current directory.
10986If follow_symlinks is False, and the last element of the path is a symbolic
10987 link, listxattr will examine the symbolic link itself instead of the file
10988 the link points to.
10989[clinic start generated code]*/
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010992os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10993/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010994{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 Py_ssize_t i;
10996 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010997 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010999
Larry Hastings2f936352014-08-05 14:04:04 +100011000 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011002
Larry Hastings2f936352014-08-05 14:04:04 +100011003 name = path->narrow ? path->narrow : ".";
11004
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 for (i = 0; ; i++) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011006 const char *start, *trace, *end;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011008 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 Py_ssize_t buffer_size = buffer_sizes[i];
11010 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011011 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011012 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 break;
11014 }
11015 buffer = PyMem_MALLOC(buffer_size);
11016 if (!buffer) {
11017 PyErr_NoMemory();
11018 break;
11019 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011020
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011022 if (path->fd > -1)
11023 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 else if (follow_symlinks)
11025 length = listxattr(name, buffer, buffer_size);
11026 else
11027 length = llistxattr(name, buffer, buffer_size);
11028 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029
Larry Hastings9cf065c2012-06-22 16:30:09 -070011030 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011031 if (errno == ERANGE) {
11032 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011033 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011034 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011035 }
Larry Hastings2f936352014-08-05 14:04:04 +100011036 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011037 break;
11038 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011039
Larry Hastings9cf065c2012-06-22 16:30:09 -070011040 result = PyList_New(0);
11041 if (!result) {
11042 goto exit;
11043 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011044
Larry Hastings9cf065c2012-06-22 16:30:09 -070011045 end = buffer + length;
11046 for (trace = start = buffer; trace != end; trace++) {
11047 if (!*trace) {
11048 int error;
11049 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11050 trace - start);
11051 if (!attribute) {
11052 Py_DECREF(result);
11053 result = NULL;
11054 goto exit;
11055 }
11056 error = PyList_Append(result, attribute);
11057 Py_DECREF(attribute);
11058 if (error) {
11059 Py_DECREF(result);
11060 result = NULL;
11061 goto exit;
11062 }
11063 start = trace + 1;
11064 }
11065 }
11066 break;
11067 }
11068exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011069 if (buffer)
11070 PyMem_FREE(buffer);
11071 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011072}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011073#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011074
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011075
Larry Hastings2f936352014-08-05 14:04:04 +100011076/*[clinic input]
11077os.urandom
11078
11079 size: Py_ssize_t
11080 /
11081
11082Return a bytes object containing random bytes suitable for cryptographic use.
11083[clinic start generated code]*/
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011086os_urandom_impl(PyObject *module, Py_ssize_t size)
11087/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011088{
11089 PyObject *bytes;
11090 int result;
11091
Georg Brandl2fb477c2012-02-21 00:33:36 +010011092 if (size < 0)
11093 return PyErr_Format(PyExc_ValueError,
11094 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011095 bytes = PyBytes_FromStringAndSize(NULL, size);
11096 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011097 return NULL;
11098
Larry Hastings2f936352014-08-05 14:04:04 +100011099 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11100 PyBytes_GET_SIZE(bytes));
11101 if (result == -1) {
11102 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011103 return NULL;
11104 }
Larry Hastings2f936352014-08-05 14:04:04 +100011105 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011106}
11107
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011108/* Terminal size querying */
11109
11110static PyTypeObject TerminalSizeType;
11111
11112PyDoc_STRVAR(TerminalSize_docstring,
11113 "A tuple of (columns, lines) for holding terminal window size");
11114
11115static PyStructSequence_Field TerminalSize_fields[] = {
11116 {"columns", "width of the terminal window in characters"},
11117 {"lines", "height of the terminal window in characters"},
11118 {NULL, NULL}
11119};
11120
11121static PyStructSequence_Desc TerminalSize_desc = {
11122 "os.terminal_size",
11123 TerminalSize_docstring,
11124 TerminalSize_fields,
11125 2,
11126};
11127
11128#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011129/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011130PyDoc_STRVAR(termsize__doc__,
11131 "Return the size of the terminal window as (columns, lines).\n" \
11132 "\n" \
11133 "The optional argument fd (default standard output) specifies\n" \
11134 "which file descriptor should be queried.\n" \
11135 "\n" \
11136 "If the file descriptor is not connected to a terminal, an OSError\n" \
11137 "is thrown.\n" \
11138 "\n" \
11139 "This function will only be defined if an implementation is\n" \
11140 "available for this system.\n" \
11141 "\n" \
11142 "shutil.get_terminal_size is the high-level function which should \n" \
11143 "normally be used, os.get_terminal_size is the low-level implementation.");
11144
11145static PyObject*
11146get_terminal_size(PyObject *self, PyObject *args)
11147{
11148 int columns, lines;
11149 PyObject *termsize;
11150
11151 int fd = fileno(stdout);
11152 /* Under some conditions stdout may not be connected and
11153 * fileno(stdout) may point to an invalid file descriptor. For example
11154 * GUI apps don't have valid standard streams by default.
11155 *
11156 * If this happens, and the optional fd argument is not present,
11157 * the ioctl below will fail returning EBADF. This is what we want.
11158 */
11159
11160 if (!PyArg_ParseTuple(args, "|i", &fd))
11161 return NULL;
11162
11163#ifdef TERMSIZE_USE_IOCTL
11164 {
11165 struct winsize w;
11166 if (ioctl(fd, TIOCGWINSZ, &w))
11167 return PyErr_SetFromErrno(PyExc_OSError);
11168 columns = w.ws_col;
11169 lines = w.ws_row;
11170 }
11171#endif /* TERMSIZE_USE_IOCTL */
11172
11173#ifdef TERMSIZE_USE_CONIO
11174 {
11175 DWORD nhandle;
11176 HANDLE handle;
11177 CONSOLE_SCREEN_BUFFER_INFO csbi;
11178 switch (fd) {
11179 case 0: nhandle = STD_INPUT_HANDLE;
11180 break;
11181 case 1: nhandle = STD_OUTPUT_HANDLE;
11182 break;
11183 case 2: nhandle = STD_ERROR_HANDLE;
11184 break;
11185 default:
11186 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11187 }
11188 handle = GetStdHandle(nhandle);
11189 if (handle == NULL)
11190 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11191 if (handle == INVALID_HANDLE_VALUE)
11192 return PyErr_SetFromWindowsErr(0);
11193
11194 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11195 return PyErr_SetFromWindowsErr(0);
11196
11197 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11198 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11199 }
11200#endif /* TERMSIZE_USE_CONIO */
11201
11202 termsize = PyStructSequence_New(&TerminalSizeType);
11203 if (termsize == NULL)
11204 return NULL;
11205 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11206 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11207 if (PyErr_Occurred()) {
11208 Py_DECREF(termsize);
11209 return NULL;
11210 }
11211 return termsize;
11212}
11213#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11214
Larry Hastings2f936352014-08-05 14:04:04 +100011215
11216/*[clinic input]
11217os.cpu_count
11218
Charles-François Natali80d62e62015-08-13 20:37:08 +010011219Return the number of CPUs in the system; return None if indeterminable.
11220
11221This number is not equivalent to the number of CPUs the current process can
11222use. The number of usable CPUs can be obtained with
11223``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011224[clinic start generated code]*/
11225
Larry Hastings2f936352014-08-05 14:04:04 +100011226static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011227os_cpu_count_impl(PyObject *module)
Serhiy Storchaka2954f832016-07-07 18:20:03 +030011228/*[clinic end generated code: output=5fc29463c3936a9c input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011229{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011230 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011231#ifdef MS_WINDOWS
11232 SYSTEM_INFO sysinfo;
11233 GetSystemInfo(&sysinfo);
11234 ncpu = sysinfo.dwNumberOfProcessors;
11235#elif defined(__hpux)
11236 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11237#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11238 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011239#elif defined(__DragonFly__) || \
11240 defined(__OpenBSD__) || \
11241 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011242 defined(__NetBSD__) || \
11243 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011244 int mib[2];
11245 size_t len = sizeof(ncpu);
11246 mib[0] = CTL_HW;
11247 mib[1] = HW_NCPU;
11248 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11249 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011250#endif
11251 if (ncpu >= 1)
11252 return PyLong_FromLong(ncpu);
11253 else
11254 Py_RETURN_NONE;
11255}
11256
Victor Stinnerdaf45552013-08-28 00:53:59 +020011257
Larry Hastings2f936352014-08-05 14:04:04 +100011258/*[clinic input]
11259os.get_inheritable -> bool
11260
11261 fd: int
11262 /
11263
11264Get the close-on-exe flag of the specified file descriptor.
11265[clinic start generated code]*/
11266
Larry Hastings2f936352014-08-05 14:04:04 +100011267static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011268os_get_inheritable_impl(PyObject *module, int fd)
11269/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011270{
Steve Dower8fc89802015-04-12 00:26:27 -040011271 int return_value;
11272 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011273 posix_error();
11274 return -1;
11275 }
11276
Steve Dower8fc89802015-04-12 00:26:27 -040011277 _Py_BEGIN_SUPPRESS_IPH
11278 return_value = _Py_get_inheritable(fd);
11279 _Py_END_SUPPRESS_IPH
11280 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011281}
11282
11283
11284/*[clinic input]
11285os.set_inheritable
11286 fd: int
11287 inheritable: int
11288 /
11289
11290Set the inheritable flag of the specified file descriptor.
11291[clinic start generated code]*/
11292
Larry Hastings2f936352014-08-05 14:04:04 +100011293static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011294os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11295/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011296{
Steve Dower8fc89802015-04-12 00:26:27 -040011297 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011298 if (!_PyVerify_fd(fd))
11299 return posix_error();
11300
Steve Dower8fc89802015-04-12 00:26:27 -040011301 _Py_BEGIN_SUPPRESS_IPH
11302 result = _Py_set_inheritable(fd, inheritable, NULL);
11303 _Py_END_SUPPRESS_IPH
11304 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011305 return NULL;
11306 Py_RETURN_NONE;
11307}
11308
11309
11310#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011311/*[clinic input]
11312os.get_handle_inheritable -> bool
11313 handle: Py_intptr_t
11314 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011315
Larry Hastings2f936352014-08-05 14:04:04 +100011316Get the close-on-exe flag of the specified file descriptor.
11317[clinic start generated code]*/
11318
Larry Hastings2f936352014-08-05 14:04:04 +100011319static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011320os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11321/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011322{
11323 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011324
11325 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11326 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011327 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011328 }
11329
Larry Hastings2f936352014-08-05 14:04:04 +100011330 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011331}
11332
Victor Stinnerdaf45552013-08-28 00:53:59 +020011333
Larry Hastings2f936352014-08-05 14:04:04 +100011334/*[clinic input]
11335os.set_handle_inheritable
11336 handle: Py_intptr_t
11337 inheritable: bool
11338 /
11339
11340Set the inheritable flag of the specified handle.
11341[clinic start generated code]*/
11342
Larry Hastings2f936352014-08-05 14:04:04 +100011343static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011344os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011345 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011346/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011347{
11348 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011349 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11350 PyErr_SetFromWindowsErr(0);
11351 return NULL;
11352 }
11353 Py_RETURN_NONE;
11354}
Larry Hastings2f936352014-08-05 14:04:04 +100011355#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011356
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011357#ifndef MS_WINDOWS
11358PyDoc_STRVAR(get_blocking__doc__,
11359 "get_blocking(fd) -> bool\n" \
11360 "\n" \
11361 "Get the blocking mode of the file descriptor:\n" \
11362 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11363
11364static PyObject*
11365posix_get_blocking(PyObject *self, PyObject *args)
11366{
11367 int fd;
11368 int blocking;
11369
11370 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11371 return NULL;
11372
11373 if (!_PyVerify_fd(fd))
11374 return posix_error();
11375
Steve Dower8fc89802015-04-12 00:26:27 -040011376 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011377 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011378 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011379 if (blocking < 0)
11380 return NULL;
11381 return PyBool_FromLong(blocking);
11382}
11383
11384PyDoc_STRVAR(set_blocking__doc__,
11385 "set_blocking(fd, blocking)\n" \
11386 "\n" \
11387 "Set the blocking mode of the specified file descriptor.\n" \
11388 "Set the O_NONBLOCK flag if blocking is False,\n" \
11389 "clear the O_NONBLOCK flag otherwise.");
11390
11391static PyObject*
11392posix_set_blocking(PyObject *self, PyObject *args)
11393{
Steve Dower8fc89802015-04-12 00:26:27 -040011394 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011395
11396 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11397 return NULL;
11398
11399 if (!_PyVerify_fd(fd))
11400 return posix_error();
11401
Steve Dower8fc89802015-04-12 00:26:27 -040011402 _Py_BEGIN_SUPPRESS_IPH
11403 result = _Py_set_blocking(fd, blocking);
11404 _Py_END_SUPPRESS_IPH
11405 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011406 return NULL;
11407 Py_RETURN_NONE;
11408}
11409#endif /* !MS_WINDOWS */
11410
11411
Victor Stinner6036e442015-03-08 01:58:04 +010011412PyDoc_STRVAR(posix_scandir__doc__,
11413"scandir(path='.') -> iterator of DirEntry objects for given path");
11414
11415static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11416
11417typedef struct {
11418 PyObject_HEAD
11419 PyObject *name;
11420 PyObject *path;
11421 PyObject *stat;
11422 PyObject *lstat;
11423#ifdef MS_WINDOWS
11424 struct _Py_stat_struct win32_lstat;
11425 __int64 win32_file_index;
11426 int got_file_index;
11427#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011428#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011429 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011430#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011431 ino_t d_ino;
11432#endif
11433} DirEntry;
11434
11435static void
11436DirEntry_dealloc(DirEntry *entry)
11437{
11438 Py_XDECREF(entry->name);
11439 Py_XDECREF(entry->path);
11440 Py_XDECREF(entry->stat);
11441 Py_XDECREF(entry->lstat);
11442 Py_TYPE(entry)->tp_free((PyObject *)entry);
11443}
11444
11445/* Forward reference */
11446static int
11447DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11448
11449/* Set exception and return -1 on error, 0 for False, 1 for True */
11450static int
11451DirEntry_is_symlink(DirEntry *self)
11452{
11453#ifdef MS_WINDOWS
11454 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011455#elif defined(HAVE_DIRENT_D_TYPE)
11456 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011457 if (self->d_type != DT_UNKNOWN)
11458 return self->d_type == DT_LNK;
11459 else
11460 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011461#else
11462 /* POSIX without d_type */
11463 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011464#endif
11465}
11466
11467static PyObject *
11468DirEntry_py_is_symlink(DirEntry *self)
11469{
11470 int result;
11471
11472 result = DirEntry_is_symlink(self);
11473 if (result == -1)
11474 return NULL;
11475 return PyBool_FromLong(result);
11476}
11477
11478static PyObject *
11479DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11480{
11481 int result;
11482 struct _Py_stat_struct st;
11483
11484#ifdef MS_WINDOWS
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011485 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011486
11487 path = PyUnicode_AsUnicode(self->path);
11488 if (!path)
11489 return NULL;
11490
11491 if (follow_symlinks)
11492 result = win32_stat_w(path, &st);
11493 else
11494 result = win32_lstat_w(path, &st);
11495
11496 if (result != 0) {
11497 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11498 0, self->path);
11499 }
11500#else /* POSIX */
11501 PyObject *bytes;
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011502 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011503
11504 if (!PyUnicode_FSConverter(self->path, &bytes))
11505 return NULL;
11506 path = PyBytes_AS_STRING(bytes);
11507
11508 if (follow_symlinks)
11509 result = STAT(path, &st);
11510 else
11511 result = LSTAT(path, &st);
11512 Py_DECREF(bytes);
11513
11514 if (result != 0)
11515 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11516#endif
11517
11518 return _pystat_fromstructstat(&st);
11519}
11520
11521static PyObject *
11522DirEntry_get_lstat(DirEntry *self)
11523{
11524 if (!self->lstat) {
11525#ifdef MS_WINDOWS
11526 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11527#else /* POSIX */
11528 self->lstat = DirEntry_fetch_stat(self, 0);
11529#endif
11530 }
11531 Py_XINCREF(self->lstat);
11532 return self->lstat;
11533}
11534
11535static PyObject *
11536DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11537{
11538 if (!follow_symlinks)
11539 return DirEntry_get_lstat(self);
11540
11541 if (!self->stat) {
11542 int result = DirEntry_is_symlink(self);
11543 if (result == -1)
11544 return NULL;
11545 else if (result)
11546 self->stat = DirEntry_fetch_stat(self, 1);
11547 else
11548 self->stat = DirEntry_get_lstat(self);
11549 }
11550
11551 Py_XINCREF(self->stat);
11552 return self->stat;
11553}
11554
11555static PyObject *
11556DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11557{
11558 int follow_symlinks = 1;
11559
11560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11561 follow_symlinks_keywords, &follow_symlinks))
11562 return NULL;
11563
11564 return DirEntry_get_stat(self, follow_symlinks);
11565}
11566
11567/* Set exception and return -1 on error, 0 for False, 1 for True */
11568static int
11569DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11570{
11571 PyObject *stat = NULL;
11572 PyObject *st_mode = NULL;
11573 long mode;
11574 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011575#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011576 int is_symlink;
11577 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011578#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011579#ifdef MS_WINDOWS
11580 unsigned long dir_bits;
11581#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011582 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011583
11584#ifdef MS_WINDOWS
11585 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11586 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011587#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011588 is_symlink = self->d_type == DT_LNK;
11589 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11590#endif
11591
Victor Stinner35a97c02015-03-08 02:59:09 +010011592#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011593 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011594#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011595 stat = DirEntry_get_stat(self, follow_symlinks);
11596 if (!stat) {
11597 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11598 /* If file doesn't exist (anymore), then return False
11599 (i.e., say it's not a file/directory) */
11600 PyErr_Clear();
11601 return 0;
11602 }
11603 goto error;
11604 }
11605 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11606 if (!st_mode)
11607 goto error;
11608
11609 mode = PyLong_AsLong(st_mode);
11610 if (mode == -1 && PyErr_Occurred())
11611 goto error;
11612 Py_CLEAR(st_mode);
11613 Py_CLEAR(stat);
11614 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011615#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011616 }
11617 else if (is_symlink) {
11618 assert(mode_bits != S_IFLNK);
11619 result = 0;
11620 }
11621 else {
11622 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11623#ifdef MS_WINDOWS
11624 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11625 if (mode_bits == S_IFDIR)
11626 result = dir_bits != 0;
11627 else
11628 result = dir_bits == 0;
11629#else /* POSIX */
11630 if (mode_bits == S_IFDIR)
11631 result = self->d_type == DT_DIR;
11632 else
11633 result = self->d_type == DT_REG;
11634#endif
11635 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011636#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011637
11638 return result;
11639
11640error:
11641 Py_XDECREF(st_mode);
11642 Py_XDECREF(stat);
11643 return -1;
11644}
11645
11646static PyObject *
11647DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11648{
11649 int result;
11650
11651 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11652 if (result == -1)
11653 return NULL;
11654 return PyBool_FromLong(result);
11655}
11656
11657static PyObject *
11658DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11659{
11660 int follow_symlinks = 1;
11661
11662 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11663 follow_symlinks_keywords, &follow_symlinks))
11664 return NULL;
11665
11666 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11667}
11668
11669static PyObject *
11670DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11671{
11672 int follow_symlinks = 1;
11673
11674 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11675 follow_symlinks_keywords, &follow_symlinks))
11676 return NULL;
11677
11678 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11679}
11680
11681static PyObject *
11682DirEntry_inode(DirEntry *self)
11683{
11684#ifdef MS_WINDOWS
11685 if (!self->got_file_index) {
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011686 const wchar_t *path;
Victor Stinner6036e442015-03-08 01:58:04 +010011687 struct _Py_stat_struct stat;
11688
11689 path = PyUnicode_AsUnicode(self->path);
11690 if (!path)
11691 return NULL;
11692
11693 if (win32_lstat_w(path, &stat) != 0) {
11694 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11695 0, self->path);
11696 }
11697
11698 self->win32_file_index = stat.st_ino;
11699 self->got_file_index = 1;
11700 }
11701 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11702#else /* POSIX */
11703#ifdef HAVE_LARGEFILE_SUPPORT
11704 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11705#else
11706 return PyLong_FromLong((long)self->d_ino);
11707#endif
11708#endif
11709}
11710
11711static PyObject *
11712DirEntry_repr(DirEntry *self)
11713{
11714 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11715}
11716
Brett Cannon96881cd2016-06-10 14:37:21 -070011717static PyObject *
11718DirEntry_fspath(DirEntry *self)
11719{
11720 Py_INCREF(self->path);
11721 return self->path;
11722}
11723
Victor Stinner6036e442015-03-08 01:58:04 +010011724static PyMemberDef DirEntry_members[] = {
11725 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11726 "the entry's base filename, relative to scandir() \"path\" argument"},
11727 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11728 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11729 {NULL}
11730};
11731
11732static PyMethodDef DirEntry_methods[] = {
11733 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11734 "return True if the entry is a directory; cached per entry"
11735 },
11736 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11737 "return True if the entry is a file; cached per entry"
11738 },
11739 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11740 "return True if the entry is a symbolic link; cached per entry"
11741 },
11742 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11743 "return stat_result object for the entry; cached per entry"
11744 },
11745 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11746 "return inode of the entry; cached per entry",
11747 },
Brett Cannon96881cd2016-06-10 14:37:21 -070011748 {"__fspath__", (PyCFunction)DirEntry_fspath, METH_NOARGS,
11749 "returns the path for the entry",
11750 },
Victor Stinner6036e442015-03-08 01:58:04 +010011751 {NULL}
11752};
11753
Benjamin Peterson5646de42015-04-12 17:56:34 -040011754static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011755 PyVarObject_HEAD_INIT(NULL, 0)
11756 MODNAME ".DirEntry", /* tp_name */
11757 sizeof(DirEntry), /* tp_basicsize */
11758 0, /* tp_itemsize */
11759 /* methods */
11760 (destructor)DirEntry_dealloc, /* tp_dealloc */
11761 0, /* tp_print */
11762 0, /* tp_getattr */
11763 0, /* tp_setattr */
11764 0, /* tp_compare */
11765 (reprfunc)DirEntry_repr, /* tp_repr */
11766 0, /* tp_as_number */
11767 0, /* tp_as_sequence */
11768 0, /* tp_as_mapping */
11769 0, /* tp_hash */
11770 0, /* tp_call */
11771 0, /* tp_str */
11772 0, /* tp_getattro */
11773 0, /* tp_setattro */
11774 0, /* tp_as_buffer */
11775 Py_TPFLAGS_DEFAULT, /* tp_flags */
11776 0, /* tp_doc */
11777 0, /* tp_traverse */
11778 0, /* tp_clear */
11779 0, /* tp_richcompare */
11780 0, /* tp_weaklistoffset */
11781 0, /* tp_iter */
11782 0, /* tp_iternext */
11783 DirEntry_methods, /* tp_methods */
11784 DirEntry_members, /* tp_members */
11785};
11786
11787#ifdef MS_WINDOWS
11788
11789static wchar_t *
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030011790join_path_filenameW(const wchar_t *path_wide, const wchar_t *filename)
Victor Stinner6036e442015-03-08 01:58:04 +010011791{
11792 Py_ssize_t path_len;
11793 Py_ssize_t size;
11794 wchar_t *result;
11795 wchar_t ch;
11796
11797 if (!path_wide) { /* Default arg: "." */
11798 path_wide = L".";
11799 path_len = 1;
11800 }
11801 else {
11802 path_len = wcslen(path_wide);
11803 }
11804
11805 /* The +1's are for the path separator and the NUL */
11806 size = path_len + 1 + wcslen(filename) + 1;
11807 result = PyMem_New(wchar_t, size);
11808 if (!result) {
11809 PyErr_NoMemory();
11810 return NULL;
11811 }
11812 wcscpy(result, path_wide);
11813 if (path_len > 0) {
11814 ch = result[path_len - 1];
11815 if (ch != SEP && ch != ALTSEP && ch != L':')
11816 result[path_len++] = SEP;
11817 wcscpy(result + path_len, filename);
11818 }
11819 return result;
11820}
11821
11822static PyObject *
11823DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11824{
11825 DirEntry *entry;
11826 BY_HANDLE_FILE_INFORMATION file_info;
11827 ULONG reparse_tag;
11828 wchar_t *joined_path;
11829
11830 entry = PyObject_New(DirEntry, &DirEntryType);
11831 if (!entry)
11832 return NULL;
11833 entry->name = NULL;
11834 entry->path = NULL;
11835 entry->stat = NULL;
11836 entry->lstat = NULL;
11837 entry->got_file_index = 0;
11838
11839 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11840 if (!entry->name)
11841 goto error;
11842
11843 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11844 if (!joined_path)
11845 goto error;
11846
11847 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11848 PyMem_Free(joined_path);
11849 if (!entry->path)
11850 goto error;
11851
11852 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11853 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11854
11855 return (PyObject *)entry;
11856
11857error:
11858 Py_DECREF(entry);
11859 return NULL;
11860}
11861
11862#else /* POSIX */
11863
11864static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011865join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011866{
11867 Py_ssize_t path_len;
11868 Py_ssize_t size;
11869 char *result;
11870
11871 if (!path_narrow) { /* Default arg: "." */
11872 path_narrow = ".";
11873 path_len = 1;
11874 }
11875 else {
11876 path_len = strlen(path_narrow);
11877 }
11878
11879 if (filename_len == -1)
11880 filename_len = strlen(filename);
11881
11882 /* The +1's are for the path separator and the NUL */
11883 size = path_len + 1 + filename_len + 1;
11884 result = PyMem_New(char, size);
11885 if (!result) {
11886 PyErr_NoMemory();
11887 return NULL;
11888 }
11889 strcpy(result, path_narrow);
11890 if (path_len > 0 && result[path_len - 1] != '/')
11891 result[path_len++] = '/';
11892 strcpy(result + path_len, filename);
11893 return result;
11894}
11895
11896static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011897DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011898 ino_t d_ino
11899#ifdef HAVE_DIRENT_D_TYPE
11900 , unsigned char d_type
11901#endif
11902 )
Victor Stinner6036e442015-03-08 01:58:04 +010011903{
11904 DirEntry *entry;
11905 char *joined_path;
11906
11907 entry = PyObject_New(DirEntry, &DirEntryType);
11908 if (!entry)
11909 return NULL;
11910 entry->name = NULL;
11911 entry->path = NULL;
11912 entry->stat = NULL;
11913 entry->lstat = NULL;
11914
11915 joined_path = join_path_filename(path->narrow, name, name_len);
11916 if (!joined_path)
11917 goto error;
11918
11919 if (!path->narrow || !PyBytes_Check(path->object)) {
11920 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11921 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11922 }
11923 else {
11924 entry->name = PyBytes_FromStringAndSize(name, name_len);
11925 entry->path = PyBytes_FromString(joined_path);
11926 }
11927 PyMem_Free(joined_path);
11928 if (!entry->name || !entry->path)
11929 goto error;
11930
Victor Stinner35a97c02015-03-08 02:59:09 +010011931#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011932 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011933#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011934 entry->d_ino = d_ino;
11935
11936 return (PyObject *)entry;
11937
11938error:
11939 Py_XDECREF(entry);
11940 return NULL;
11941}
11942
11943#endif
11944
11945
11946typedef struct {
11947 PyObject_HEAD
11948 path_t path;
11949#ifdef MS_WINDOWS
11950 HANDLE handle;
11951 WIN32_FIND_DATAW file_data;
11952 int first_time;
11953#else /* POSIX */
11954 DIR *dirp;
11955#endif
11956} ScandirIterator;
11957
11958#ifdef MS_WINDOWS
11959
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011960static int
11961ScandirIterator_is_closed(ScandirIterator *iterator)
11962{
11963 return iterator->handle == INVALID_HANDLE_VALUE;
11964}
11965
Victor Stinner6036e442015-03-08 01:58:04 +010011966static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011967ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011968{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011969 HANDLE handle = iterator->handle;
11970
11971 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011972 return;
11973
Victor Stinner6036e442015-03-08 01:58:04 +010011974 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011975 Py_BEGIN_ALLOW_THREADS
11976 FindClose(handle);
11977 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011978}
11979
11980static PyObject *
11981ScandirIterator_iternext(ScandirIterator *iterator)
11982{
11983 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11984 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011985 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011986
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011987 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011988 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011989 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011990
11991 while (1) {
11992 if (!iterator->first_time) {
11993 Py_BEGIN_ALLOW_THREADS
11994 success = FindNextFileW(iterator->handle, file_data);
11995 Py_END_ALLOW_THREADS
11996 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011997 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011998 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011999 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012000 break;
12001 }
12002 }
12003 iterator->first_time = 0;
12004
12005 /* Skip over . and .. */
12006 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012007 wcscmp(file_data->cFileName, L"..") != 0) {
12008 entry = DirEntry_from_find_data(&iterator->path, file_data);
12009 if (!entry)
12010 break;
12011 return entry;
12012 }
Victor Stinner6036e442015-03-08 01:58:04 +010012013
12014 /* Loop till we get a non-dot directory or finish iterating */
12015 }
12016
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012017 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012018 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012019 return NULL;
12020}
12021
12022#else /* POSIX */
12023
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012024static int
12025ScandirIterator_is_closed(ScandirIterator *iterator)
12026{
12027 return !iterator->dirp;
12028}
12029
Victor Stinner6036e442015-03-08 01:58:04 +010012030static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012031ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012032{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012033 DIR *dirp = iterator->dirp;
12034
12035 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012036 return;
12037
Victor Stinner6036e442015-03-08 01:58:04 +010012038 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012039 Py_BEGIN_ALLOW_THREADS
12040 closedir(dirp);
12041 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012042 return;
12043}
12044
12045static PyObject *
12046ScandirIterator_iternext(ScandirIterator *iterator)
12047{
12048 struct dirent *direntp;
12049 Py_ssize_t name_len;
12050 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012051 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012052
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012053 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012054 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012055 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012056
12057 while (1) {
12058 errno = 0;
12059 Py_BEGIN_ALLOW_THREADS
12060 direntp = readdir(iterator->dirp);
12061 Py_END_ALLOW_THREADS
12062
12063 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012064 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012065 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012066 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012067 break;
12068 }
12069
12070 /* Skip over . and .. */
12071 name_len = NAMLEN(direntp);
12072 is_dot = direntp->d_name[0] == '.' &&
12073 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12074 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012075 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012076 name_len, direntp->d_ino
12077#ifdef HAVE_DIRENT_D_TYPE
12078 , direntp->d_type
12079#endif
12080 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012081 if (!entry)
12082 break;
12083 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012084 }
12085
12086 /* Loop till we get a non-dot directory or finish iterating */
12087 }
12088
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012089 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012090 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012091 return NULL;
12092}
12093
12094#endif
12095
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012096static PyObject *
12097ScandirIterator_close(ScandirIterator *self, PyObject *args)
12098{
12099 ScandirIterator_closedir(self);
12100 Py_RETURN_NONE;
12101}
12102
12103static PyObject *
12104ScandirIterator_enter(PyObject *self, PyObject *args)
12105{
12106 Py_INCREF(self);
12107 return self;
12108}
12109
12110static PyObject *
12111ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12112{
12113 ScandirIterator_closedir(self);
12114 Py_RETURN_NONE;
12115}
12116
Victor Stinner6036e442015-03-08 01:58:04 +010012117static void
Victor Stinner7bfa4092016-03-23 00:43:54 +010012118ScandirIterator_finalize(ScandirIterator *iterator)
12119{
12120 PyObject *error_type, *error_value, *error_traceback;
12121
12122 /* Save the current exception, if any. */
12123 PyErr_Fetch(&error_type, &error_value, &error_traceback);
12124
12125 if (!ScandirIterator_is_closed(iterator)) {
12126 ScandirIterator_closedir(iterator);
12127
12128 if (PyErr_ResourceWarning((PyObject *)iterator, 1,
12129 "unclosed scandir iterator %R", iterator)) {
12130 /* Spurious errors can appear at shutdown */
12131 if (PyErr_ExceptionMatches(PyExc_Warning)) {
12132 PyErr_WriteUnraisable((PyObject *) iterator);
12133 }
12134 }
12135 }
12136
12137 Py_CLEAR(iterator->path.object);
12138 path_cleanup(&iterator->path);
12139
12140 /* Restore the saved exception. */
12141 PyErr_Restore(error_type, error_value, error_traceback);
12142}
12143
12144static void
Victor Stinner6036e442015-03-08 01:58:04 +010012145ScandirIterator_dealloc(ScandirIterator *iterator)
12146{
Victor Stinner7bfa4092016-03-23 00:43:54 +010012147 if (PyObject_CallFinalizerFromDealloc((PyObject *)iterator) < 0)
12148 return;
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012149
Victor Stinner6036e442015-03-08 01:58:04 +010012150 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12151}
12152
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012153static PyMethodDef ScandirIterator_methods[] = {
12154 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12155 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12156 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12157 {NULL}
12158};
12159
Benjamin Peterson5646de42015-04-12 17:56:34 -040012160static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012161 PyVarObject_HEAD_INIT(NULL, 0)
12162 MODNAME ".ScandirIterator", /* tp_name */
12163 sizeof(ScandirIterator), /* tp_basicsize */
12164 0, /* tp_itemsize */
12165 /* methods */
12166 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12167 0, /* tp_print */
12168 0, /* tp_getattr */
12169 0, /* tp_setattr */
12170 0, /* tp_compare */
12171 0, /* tp_repr */
12172 0, /* tp_as_number */
12173 0, /* tp_as_sequence */
12174 0, /* tp_as_mapping */
12175 0, /* tp_hash */
12176 0, /* tp_call */
12177 0, /* tp_str */
12178 0, /* tp_getattro */
12179 0, /* tp_setattro */
12180 0, /* tp_as_buffer */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012181 Py_TPFLAGS_DEFAULT
12182 | Py_TPFLAGS_HAVE_FINALIZE, /* tp_flags */
Victor Stinner6036e442015-03-08 01:58:04 +010012183 0, /* tp_doc */
12184 0, /* tp_traverse */
12185 0, /* tp_clear */
12186 0, /* tp_richcompare */
12187 0, /* tp_weaklistoffset */
12188 PyObject_SelfIter, /* tp_iter */
12189 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012190 ScandirIterator_methods, /* tp_methods */
Victor Stinner7bfa4092016-03-23 00:43:54 +010012191 0, /* tp_members */
12192 0, /* tp_getset */
12193 0, /* tp_base */
12194 0, /* tp_dict */
12195 0, /* tp_descr_get */
12196 0, /* tp_descr_set */
12197 0, /* tp_dictoffset */
12198 0, /* tp_init */
12199 0, /* tp_alloc */
12200 0, /* tp_new */
12201 0, /* tp_free */
12202 0, /* tp_is_gc */
12203 0, /* tp_bases */
12204 0, /* tp_mro */
12205 0, /* tp_cache */
12206 0, /* tp_subclasses */
12207 0, /* tp_weaklist */
12208 0, /* tp_del */
12209 0, /* tp_version_tag */
12210 (destructor)ScandirIterator_finalize, /* tp_finalize */
Victor Stinner6036e442015-03-08 01:58:04 +010012211};
12212
12213static PyObject *
12214posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12215{
12216 ScandirIterator *iterator;
12217 static char *keywords[] = {"path", NULL};
12218#ifdef MS_WINDOWS
12219 wchar_t *path_strW;
12220#else
Serhiy Storchakadeab18d2016-05-07 16:45:18 +030012221 const char *path;
Victor Stinner6036e442015-03-08 01:58:04 +010012222#endif
12223
12224 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12225 if (!iterator)
12226 return NULL;
12227 memset(&iterator->path, 0, sizeof(path_t));
12228 iterator->path.function_name = "scandir";
12229 iterator->path.nullable = 1;
12230
12231#ifdef MS_WINDOWS
12232 iterator->handle = INVALID_HANDLE_VALUE;
12233#else
12234 iterator->dirp = NULL;
12235#endif
12236
12237 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12238 path_converter, &iterator->path))
12239 goto error;
12240
12241 /* path_converter doesn't keep path.object around, so do it
12242 manually for the lifetime of the iterator here (the refcount
12243 is decremented in ScandirIterator_dealloc)
12244 */
12245 Py_XINCREF(iterator->path.object);
12246
12247#ifdef MS_WINDOWS
12248 if (iterator->path.narrow) {
12249 PyErr_SetString(PyExc_TypeError,
12250 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12251 goto error;
12252 }
12253 iterator->first_time = 1;
12254
12255 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12256 if (!path_strW)
12257 goto error;
12258
12259 Py_BEGIN_ALLOW_THREADS
12260 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12261 Py_END_ALLOW_THREADS
12262
12263 PyMem_Free(path_strW);
12264
12265 if (iterator->handle == INVALID_HANDLE_VALUE) {
12266 path_error(&iterator->path);
12267 goto error;
12268 }
12269#else /* POSIX */
12270 if (iterator->path.narrow)
12271 path = iterator->path.narrow;
12272 else
12273 path = ".";
12274
12275 errno = 0;
12276 Py_BEGIN_ALLOW_THREADS
12277 iterator->dirp = opendir(path);
12278 Py_END_ALLOW_THREADS
12279
12280 if (!iterator->dirp) {
12281 path_error(&iterator->path);
12282 goto error;
12283 }
12284#endif
12285
12286 return (PyObject *)iterator;
12287
12288error:
12289 Py_DECREF(iterator);
12290 return NULL;
12291}
12292
Ethan Furman410ef8e2016-06-04 12:06:26 -070012293/*
12294 Return the file system path representation of the object.
12295
12296 If the object is str or bytes, then allow it to pass through with
12297 an incremented refcount. If the object defines __fspath__(), then
12298 return the result of that method. All other types raise a TypeError.
12299*/
12300PyObject *
12301PyOS_FSPath(PyObject *path)
12302{
12303 _Py_IDENTIFIER(__fspath__);
12304 PyObject *func = NULL;
12305 PyObject *path_repr = NULL;
12306
12307 if (PyUnicode_Check(path) || PyBytes_Check(path)) {
12308 Py_INCREF(path);
12309 return path;
12310 }
12311
12312 func = _PyObject_LookupSpecial(path, &PyId___fspath__);
12313 if (NULL == func) {
12314 return PyErr_Format(PyExc_TypeError,
12315 "expected str, bytes or os.PathLike object, "
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012316 "not %.200s",
12317 Py_TYPE(path)->tp_name);
Ethan Furman410ef8e2016-06-04 12:06:26 -070012318 }
12319
12320 path_repr = PyObject_CallFunctionObjArgs(func, NULL);
12321 Py_DECREF(func);
Brett Cannonc78ca1e2016-06-24 12:03:43 -070012322 if (!(PyUnicode_Check(path_repr) || PyBytes_Check(path_repr))) {
12323 PyErr_Format(PyExc_TypeError,
12324 "expected %.200s.__fspath__() to return str or bytes, "
12325 "not %.200s", Py_TYPE(path)->tp_name,
12326 Py_TYPE(path_repr)->tp_name);
12327 Py_DECREF(path_repr);
12328 return NULL;
12329 }
12330
Ethan Furman410ef8e2016-06-04 12:06:26 -070012331 return path_repr;
12332}
12333
12334/*[clinic input]
12335os.fspath
12336
12337 path: object
12338
12339Return the file system path representation of the object.
12340
Brett Cannonb4f43e92016-06-09 14:32:08 -070012341If the object is str or bytes, then allow it to pass through as-is. If the
12342object defines __fspath__(), then return the result of that method. All other
12343types raise a TypeError.
Ethan Furman410ef8e2016-06-04 12:06:26 -070012344[clinic start generated code]*/
12345
12346static PyObject *
Serhiy Storchaka2954f832016-07-07 18:20:03 +030012347os_fspath_impl(PyObject *module, PyObject *path)
12348/*[clinic end generated code: output=c3c3b78ecff2914f input=e357165f7b22490f]*/
Ethan Furman410ef8e2016-06-04 12:06:26 -070012349{
12350 return PyOS_FSPath(path);
12351}
Victor Stinner6036e442015-03-08 01:58:04 +010012352
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012353#include "clinic/posixmodule.c.h"
12354
Larry Hastings7726ac92014-01-31 22:03:12 -080012355/*[clinic input]
12356dump buffer
12357[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012358/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012359
Larry Hastings31826802013-10-19 00:09:25 -070012360
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012361static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012362
12363 OS_STAT_METHODDEF
12364 OS_ACCESS_METHODDEF
12365 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012366 OS_CHDIR_METHODDEF
12367 OS_CHFLAGS_METHODDEF
12368 OS_CHMOD_METHODDEF
12369 OS_FCHMOD_METHODDEF
12370 OS_LCHMOD_METHODDEF
12371 OS_CHOWN_METHODDEF
12372 OS_FCHOWN_METHODDEF
12373 OS_LCHOWN_METHODDEF
12374 OS_LCHFLAGS_METHODDEF
12375 OS_CHROOT_METHODDEF
12376 OS_CTERMID_METHODDEF
12377 OS_GETCWD_METHODDEF
12378 OS_GETCWDB_METHODDEF
12379 OS_LINK_METHODDEF
12380 OS_LISTDIR_METHODDEF
12381 OS_LSTAT_METHODDEF
12382 OS_MKDIR_METHODDEF
12383 OS_NICE_METHODDEF
12384 OS_GETPRIORITY_METHODDEF
12385 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012386#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012387 {"readlink", (PyCFunction)posix_readlink,
12388 METH_VARARGS | METH_KEYWORDS,
12389 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012390#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012391#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012392 {"readlink", (PyCFunction)win_readlink,
12393 METH_VARARGS | METH_KEYWORDS,
12394 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012395#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012396 OS_RENAME_METHODDEF
12397 OS_REPLACE_METHODDEF
12398 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012399 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012400 OS_SYMLINK_METHODDEF
12401 OS_SYSTEM_METHODDEF
12402 OS_UMASK_METHODDEF
12403 OS_UNAME_METHODDEF
12404 OS_UNLINK_METHODDEF
12405 OS_REMOVE_METHODDEF
12406 OS_UTIME_METHODDEF
12407 OS_TIMES_METHODDEF
12408 OS__EXIT_METHODDEF
12409 OS_EXECV_METHODDEF
12410 OS_EXECVE_METHODDEF
12411 OS_SPAWNV_METHODDEF
12412 OS_SPAWNVE_METHODDEF
12413 OS_FORK1_METHODDEF
12414 OS_FORK_METHODDEF
12415 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12416 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12417 OS_SCHED_GETPARAM_METHODDEF
12418 OS_SCHED_GETSCHEDULER_METHODDEF
12419 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12420 OS_SCHED_SETPARAM_METHODDEF
12421 OS_SCHED_SETSCHEDULER_METHODDEF
12422 OS_SCHED_YIELD_METHODDEF
12423 OS_SCHED_SETAFFINITY_METHODDEF
12424 OS_SCHED_GETAFFINITY_METHODDEF
12425 OS_OPENPTY_METHODDEF
12426 OS_FORKPTY_METHODDEF
12427 OS_GETEGID_METHODDEF
12428 OS_GETEUID_METHODDEF
12429 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012430#ifdef HAVE_GETGROUPLIST
12431 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12432#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012433 OS_GETGROUPS_METHODDEF
12434 OS_GETPID_METHODDEF
12435 OS_GETPGRP_METHODDEF
12436 OS_GETPPID_METHODDEF
12437 OS_GETUID_METHODDEF
12438 OS_GETLOGIN_METHODDEF
12439 OS_KILL_METHODDEF
12440 OS_KILLPG_METHODDEF
12441 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012442#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012443 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012444#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012445 OS_SETUID_METHODDEF
12446 OS_SETEUID_METHODDEF
12447 OS_SETREUID_METHODDEF
12448 OS_SETGID_METHODDEF
12449 OS_SETEGID_METHODDEF
12450 OS_SETREGID_METHODDEF
12451 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012452#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012453 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012454#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012455 OS_GETPGID_METHODDEF
12456 OS_SETPGRP_METHODDEF
12457 OS_WAIT_METHODDEF
12458 OS_WAIT3_METHODDEF
12459 OS_WAIT4_METHODDEF
12460 OS_WAITID_METHODDEF
12461 OS_WAITPID_METHODDEF
12462 OS_GETSID_METHODDEF
12463 OS_SETSID_METHODDEF
12464 OS_SETPGID_METHODDEF
12465 OS_TCGETPGRP_METHODDEF
12466 OS_TCSETPGRP_METHODDEF
12467 OS_OPEN_METHODDEF
12468 OS_CLOSE_METHODDEF
12469 OS_CLOSERANGE_METHODDEF
12470 OS_DEVICE_ENCODING_METHODDEF
12471 OS_DUP_METHODDEF
12472 OS_DUP2_METHODDEF
12473 OS_LOCKF_METHODDEF
12474 OS_LSEEK_METHODDEF
12475 OS_READ_METHODDEF
12476 OS_READV_METHODDEF
12477 OS_PREAD_METHODDEF
12478 OS_WRITE_METHODDEF
12479 OS_WRITEV_METHODDEF
12480 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012481#ifdef HAVE_SENDFILE
12482 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12483 posix_sendfile__doc__},
12484#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012485 OS_FSTAT_METHODDEF
12486 OS_ISATTY_METHODDEF
12487 OS_PIPE_METHODDEF
12488 OS_PIPE2_METHODDEF
12489 OS_MKFIFO_METHODDEF
12490 OS_MKNOD_METHODDEF
12491 OS_MAJOR_METHODDEF
12492 OS_MINOR_METHODDEF
12493 OS_MAKEDEV_METHODDEF
12494 OS_FTRUNCATE_METHODDEF
12495 OS_TRUNCATE_METHODDEF
12496 OS_POSIX_FALLOCATE_METHODDEF
12497 OS_POSIX_FADVISE_METHODDEF
12498 OS_PUTENV_METHODDEF
12499 OS_UNSETENV_METHODDEF
12500 OS_STRERROR_METHODDEF
12501 OS_FCHDIR_METHODDEF
12502 OS_FSYNC_METHODDEF
12503 OS_SYNC_METHODDEF
12504 OS_FDATASYNC_METHODDEF
12505 OS_WCOREDUMP_METHODDEF
12506 OS_WIFCONTINUED_METHODDEF
12507 OS_WIFSTOPPED_METHODDEF
12508 OS_WIFSIGNALED_METHODDEF
12509 OS_WIFEXITED_METHODDEF
12510 OS_WEXITSTATUS_METHODDEF
12511 OS_WTERMSIG_METHODDEF
12512 OS_WSTOPSIG_METHODDEF
12513 OS_FSTATVFS_METHODDEF
12514 OS_STATVFS_METHODDEF
12515 OS_CONFSTR_METHODDEF
12516 OS_SYSCONF_METHODDEF
12517 OS_FPATHCONF_METHODDEF
12518 OS_PATHCONF_METHODDEF
12519 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012520 OS__GETFULLPATHNAME_METHODDEF
12521 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012522 OS__GETDISKUSAGE_METHODDEF
12523 OS__GETFINALPATHNAME_METHODDEF
12524 OS__GETVOLUMEPATHNAME_METHODDEF
12525 OS_GETLOADAVG_METHODDEF
12526 OS_URANDOM_METHODDEF
12527 OS_SETRESUID_METHODDEF
12528 OS_SETRESGID_METHODDEF
12529 OS_GETRESUID_METHODDEF
12530 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012531
Larry Hastings2f936352014-08-05 14:04:04 +100012532 OS_GETXATTR_METHODDEF
12533 OS_SETXATTR_METHODDEF
12534 OS_REMOVEXATTR_METHODDEF
12535 OS_LISTXATTR_METHODDEF
12536
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012537#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12538 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12539#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012540 OS_CPU_COUNT_METHODDEF
12541 OS_GET_INHERITABLE_METHODDEF
12542 OS_SET_INHERITABLE_METHODDEF
12543 OS_GET_HANDLE_INHERITABLE_METHODDEF
12544 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012545#ifndef MS_WINDOWS
12546 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12547 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12548#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012549 {"scandir", (PyCFunction)posix_scandir,
12550 METH_VARARGS | METH_KEYWORDS,
12551 posix_scandir__doc__},
Ethan Furman410ef8e2016-06-04 12:06:26 -070012552 OS_FSPATH_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012553 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012554};
12555
12556
Brian Curtin52173d42010-12-02 18:29:18 +000012557#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012558static int
Brian Curtin52173d42010-12-02 18:29:18 +000012559enable_symlink()
12560{
12561 HANDLE tok;
12562 TOKEN_PRIVILEGES tok_priv;
12563 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012564
12565 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012566 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012567
12568 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012569 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012570
12571 tok_priv.PrivilegeCount = 1;
12572 tok_priv.Privileges[0].Luid = luid;
12573 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12574
12575 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12576 sizeof(TOKEN_PRIVILEGES),
12577 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012578 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012579
Brian Curtin3b4499c2010-12-28 14:31:47 +000012580 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12581 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012582}
12583#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12584
Barry Warsaw4a342091996-12-19 23:50:02 +000012585static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012587{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012588#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012589 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012590#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012591#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012592 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012593#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012594#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012595 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012596#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012597#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012599#endif
Fred Drakec9680921999-12-13 16:37:25 +000012600#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012602#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012603#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012605#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012606#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012608#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012609#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012611#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012612#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012614#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012615#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012617#endif
12618#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012620#endif
12621#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012623#endif
12624#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012626#endif
12627#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012629#endif
12630#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012631 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012632#endif
12633#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012635#endif
12636#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012637 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012638#endif
12639#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012641#endif
12642#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012644#endif
12645#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012647#endif
12648#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012649 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012650#endif
12651#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012653#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012654#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012656#endif
12657#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012659#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012660#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012662#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012663#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012665#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012666#ifndef __GNU__
Skip Montanaro5ff14922005-05-16 02:42:22 +000012667#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012669#endif
12670#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012672#endif
doko@ubuntu.comfcff4372016-06-13 16:33:04 +020012673#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012674#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012676#endif
12677#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012679#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012680#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012682#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012683#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012685#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012686#ifdef O_TMPFILE
12687 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12688#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012689#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012691#endif
12692#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012694#endif
12695#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012697#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012698#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012699 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012700#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012701#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012702 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012703#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012704
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012705
Jesus Cea94363612012-06-22 18:32:07 +020012706#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012708#endif
12709#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012710 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012711#endif
12712
Tim Peters5aa91602002-01-30 05:46:57 +000012713/* MS Windows */
12714#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012715 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012717#endif
12718#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012719 /* Optimize for short life (keep in memory). */
12720 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012721 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012722#endif
12723#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012724 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012726#endif
12727#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012728 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012730#endif
12731#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012732 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012733 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012734#endif
12735
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012736/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012737#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012738 /* Send a SIGIO signal whenever input or output
12739 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012741#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012742#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012743 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012744 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012745#endif
12746#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012747 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012748 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012749#endif
12750#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012751 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012753#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012754#ifdef O_NOLINKS
12755 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012757#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012758#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012759 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012761#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012762
Victor Stinner8c62be82010-05-06 00:08:46 +000012763 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012764#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012766#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012767#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012769#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012770#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012772#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012773#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012775#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012776#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012778#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012779#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012781#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012782#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012783 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012784#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012785#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012787#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012788#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012790#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012791#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012792 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012793#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012794#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012796#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012797#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012798 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012799#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012800#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012801 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012802#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012803#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012805#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012806#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012807 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012808#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012809#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012810 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012811#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012812#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012813 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012814#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012815
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012816 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012817#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012818 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012819#endif /* ST_RDONLY */
12820#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012821 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012822#endif /* ST_NOSUID */
12823
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012824 /* GNU extensions */
12825#ifdef ST_NODEV
12826 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12827#endif /* ST_NODEV */
12828#ifdef ST_NOEXEC
12829 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12830#endif /* ST_NOEXEC */
12831#ifdef ST_SYNCHRONOUS
12832 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12833#endif /* ST_SYNCHRONOUS */
12834#ifdef ST_MANDLOCK
12835 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12836#endif /* ST_MANDLOCK */
12837#ifdef ST_WRITE
12838 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12839#endif /* ST_WRITE */
12840#ifdef ST_APPEND
12841 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12842#endif /* ST_APPEND */
12843#ifdef ST_NOATIME
12844 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12845#endif /* ST_NOATIME */
12846#ifdef ST_NODIRATIME
12847 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12848#endif /* ST_NODIRATIME */
12849#ifdef ST_RELATIME
12850 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12851#endif /* ST_RELATIME */
12852
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012853 /* FreeBSD sendfile() constants */
12854#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012855 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012856#endif
12857#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012858 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012859#endif
12860#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012861 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012862#endif
12863
Ross Lagerwall7807c352011-03-17 20:20:30 +020012864 /* constants for posix_fadvise */
12865#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012866 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012867#endif
12868#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012869 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012870#endif
12871#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012872 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012873#endif
12874#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012875 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012876#endif
12877#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012878 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012879#endif
12880#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012881 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012882#endif
12883
12884 /* constants for waitid */
12885#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012886 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12887 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12888 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012889#endif
12890#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012891 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012892#endif
12893#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012894 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012895#endif
12896#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012897 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012898#endif
12899#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012900 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012901#endif
12902#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012903 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012904#endif
12905#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012906 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012907#endif
12908#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012909 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012910#endif
12911
12912 /* constants for lockf */
12913#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012914 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012915#endif
12916#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012917 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012918#endif
12919#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012920 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012921#endif
12922#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012923 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012924#endif
12925
Guido van Rossum246bc171999-02-01 23:54:31 +000012926#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012927 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12928 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12929 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12930 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12931 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012932#endif
12933
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012934#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012935 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12936 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12937 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012938#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012939 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012940#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012941#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012942 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012943#endif
12944#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012945 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012946#endif
12947#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012948 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012949#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012950#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012951 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012952#endif
12953#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012954 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012955#endif
12956#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012957 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012958#endif
12959#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012960 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012961#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012962#endif
12963
Benjamin Peterson9428d532011-09-14 11:45:52 -040012964#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012965 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12966 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12967 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012968#endif
12969
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012970#if HAVE_DECL_RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012971 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012972#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012973#if HAVE_DECL_RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012974 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012975#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012976#if HAVE_DECL_RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012977 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012978#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012979#if HAVE_DECL_RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012980 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012981#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012982#if HAVE_DECL_RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012983 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012984#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012985#if HAVE_DECL_RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012986 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012987#endif
Serhiy Storchakac2f7d872016-05-04 09:44:44 +030012988#if HAVE_DECL_RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012989 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012990#endif
12991
Victor Stinner8c62be82010-05-06 00:08:46 +000012992 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012993}
12994
12995
Martin v. Löwis1a214512008-06-11 05:26:20 +000012996static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 PyModuleDef_HEAD_INIT,
12998 MODNAME,
12999 posix__doc__,
13000 -1,
13001 posix_methods,
13002 NULL,
13003 NULL,
13004 NULL,
13005 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000013006};
13007
13008
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013009static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070013010
13011#ifdef HAVE_FACCESSAT
13012 "HAVE_FACCESSAT",
13013#endif
13014
13015#ifdef HAVE_FCHDIR
13016 "HAVE_FCHDIR",
13017#endif
13018
13019#ifdef HAVE_FCHMOD
13020 "HAVE_FCHMOD",
13021#endif
13022
13023#ifdef HAVE_FCHMODAT
13024 "HAVE_FCHMODAT",
13025#endif
13026
13027#ifdef HAVE_FCHOWN
13028 "HAVE_FCHOWN",
13029#endif
13030
Larry Hastings00964ed2013-08-12 13:49:30 -040013031#ifdef HAVE_FCHOWNAT
13032 "HAVE_FCHOWNAT",
13033#endif
13034
Larry Hastings9cf065c2012-06-22 16:30:09 -070013035#ifdef HAVE_FEXECVE
13036 "HAVE_FEXECVE",
13037#endif
13038
13039#ifdef HAVE_FDOPENDIR
13040 "HAVE_FDOPENDIR",
13041#endif
13042
Georg Brandl306336b2012-06-24 12:55:33 +020013043#ifdef HAVE_FPATHCONF
13044 "HAVE_FPATHCONF",
13045#endif
13046
Larry Hastings9cf065c2012-06-22 16:30:09 -070013047#ifdef HAVE_FSTATAT
13048 "HAVE_FSTATAT",
13049#endif
13050
13051#ifdef HAVE_FSTATVFS
13052 "HAVE_FSTATVFS",
13053#endif
13054
Steve Dowerfe0a41a2015-03-20 19:50:46 -070013055#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020013056 "HAVE_FTRUNCATE",
13057#endif
13058
Larry Hastings9cf065c2012-06-22 16:30:09 -070013059#ifdef HAVE_FUTIMENS
13060 "HAVE_FUTIMENS",
13061#endif
13062
13063#ifdef HAVE_FUTIMES
13064 "HAVE_FUTIMES",
13065#endif
13066
13067#ifdef HAVE_FUTIMESAT
13068 "HAVE_FUTIMESAT",
13069#endif
13070
13071#ifdef HAVE_LINKAT
13072 "HAVE_LINKAT",
13073#endif
13074
13075#ifdef HAVE_LCHFLAGS
13076 "HAVE_LCHFLAGS",
13077#endif
13078
13079#ifdef HAVE_LCHMOD
13080 "HAVE_LCHMOD",
13081#endif
13082
13083#ifdef HAVE_LCHOWN
13084 "HAVE_LCHOWN",
13085#endif
13086
13087#ifdef HAVE_LSTAT
13088 "HAVE_LSTAT",
13089#endif
13090
13091#ifdef HAVE_LUTIMES
13092 "HAVE_LUTIMES",
13093#endif
13094
13095#ifdef HAVE_MKDIRAT
13096 "HAVE_MKDIRAT",
13097#endif
13098
13099#ifdef HAVE_MKFIFOAT
13100 "HAVE_MKFIFOAT",
13101#endif
13102
13103#ifdef HAVE_MKNODAT
13104 "HAVE_MKNODAT",
13105#endif
13106
13107#ifdef HAVE_OPENAT
13108 "HAVE_OPENAT",
13109#endif
13110
13111#ifdef HAVE_READLINKAT
13112 "HAVE_READLINKAT",
13113#endif
13114
13115#ifdef HAVE_RENAMEAT
13116 "HAVE_RENAMEAT",
13117#endif
13118
13119#ifdef HAVE_SYMLINKAT
13120 "HAVE_SYMLINKAT",
13121#endif
13122
13123#ifdef HAVE_UNLINKAT
13124 "HAVE_UNLINKAT",
13125#endif
13126
13127#ifdef HAVE_UTIMENSAT
13128 "HAVE_UTIMENSAT",
13129#endif
13130
13131#ifdef MS_WINDOWS
13132 "MS_WINDOWS",
13133#endif
13134
13135 NULL
13136};
13137
13138
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013139PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013140INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013141{
Victor Stinner8c62be82010-05-06 00:08:46 +000013142 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013143 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013144 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013145
Brian Curtin52173d42010-12-02 18:29:18 +000013146#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013147 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013148#endif
13149
Victor Stinner8c62be82010-05-06 00:08:46 +000013150 m = PyModule_Create(&posixmodule);
13151 if (m == NULL)
13152 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013153
Victor Stinner8c62be82010-05-06 00:08:46 +000013154 /* Initialize environ dictionary */
13155 v = convertenviron();
13156 Py_XINCREF(v);
13157 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13158 return NULL;
13159 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013160
Victor Stinner8c62be82010-05-06 00:08:46 +000013161 if (all_ins(m))
13162 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013163
Victor Stinner8c62be82010-05-06 00:08:46 +000013164 if (setup_confname_tables(m))
13165 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013166
Victor Stinner8c62be82010-05-06 00:08:46 +000013167 Py_INCREF(PyExc_OSError);
13168 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013169
Guido van Rossumb3d39562000-01-31 18:41:26 +000013170#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013171 if (posix_putenv_garbage == NULL)
13172 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013173#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013174
Victor Stinner8c62be82010-05-06 00:08:46 +000013175 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013176#if defined(HAVE_WAITID) && !defined(__APPLE__)
13177 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013178 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13179 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013180#endif
13181
Christian Heimes25827622013-10-12 01:27:08 +020013182 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013183 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13184 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13185 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013186 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13187 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013188 structseq_new = StatResultType.tp_new;
13189 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013190
Christian Heimes25827622013-10-12 01:27:08 +020013191 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013192 if (PyStructSequence_InitType2(&StatVFSResultType,
13193 &statvfs_result_desc) < 0)
13194 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013195#ifdef NEED_TICKS_PER_SECOND
13196# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013197 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013198# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013199 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013200# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013201 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013202# endif
13203#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013204
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013205#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013206 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013207 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13208 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013209 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013210#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013211
13212 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013213 if (PyStructSequence_InitType2(&TerminalSizeType,
13214 &TerminalSize_desc) < 0)
13215 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013216
13217 /* initialize scandir types */
13218 if (PyType_Ready(&ScandirIteratorType) < 0)
13219 return NULL;
13220 if (PyType_Ready(&DirEntryType) < 0)
13221 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013222 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013223#if defined(HAVE_WAITID) && !defined(__APPLE__)
13224 Py_INCREF((PyObject*) &WaitidResultType);
13225 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13226#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013227 Py_INCREF((PyObject*) &StatResultType);
13228 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13229 Py_INCREF((PyObject*) &StatVFSResultType);
13230 PyModule_AddObject(m, "statvfs_result",
13231 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013232
13233#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013234 Py_INCREF(&SchedParamType);
13235 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013236#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013237
Larry Hastings605a62d2012-06-24 04:33:36 -070013238 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013239 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13240 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013241 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13242
13243 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013244 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13245 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013246 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13247
Thomas Wouters477c8d52006-05-27 19:21:47 +000013248#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013249 /*
13250 * Step 2 of weak-linking support on Mac OS X.
13251 *
13252 * The code below removes functions that are not available on the
13253 * currently active platform.
13254 *
13255 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013256 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013257 * OSX 10.4.
13258 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013259#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013260 if (fstatvfs == NULL) {
13261 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13262 return NULL;
13263 }
13264 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013265#endif /* HAVE_FSTATVFS */
13266
13267#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013268 if (statvfs == NULL) {
13269 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13270 return NULL;
13271 }
13272 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013273#endif /* HAVE_STATVFS */
13274
13275# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013276 if (lchown == NULL) {
13277 if (PyObject_DelAttrString(m, "lchown") == -1) {
13278 return NULL;
13279 }
13280 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013281#endif /* HAVE_LCHOWN */
13282
13283
13284#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013285
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013286 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013287 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13288
Larry Hastings6fe20b32012-04-19 15:07:49 -070013289 billion = PyLong_FromLong(1000000000);
13290 if (!billion)
13291 return NULL;
13292
Larry Hastings9cf065c2012-06-22 16:30:09 -070013293 /* suppress "function not used" warnings */
13294 {
13295 int ignored;
13296 fd_specified("", -1);
13297 follow_symlinks_specified("", 1);
13298 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13299 dir_fd_converter(Py_None, &ignored);
13300 dir_fd_unavailable(Py_None, &ignored);
13301 }
13302
13303 /*
13304 * provide list of locally available functions
13305 * so os.py can populate support_* lists
13306 */
13307 list = PyList_New(0);
13308 if (!list)
13309 return NULL;
13310 for (trace = have_functions; *trace; trace++) {
13311 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13312 if (!unicode)
13313 return NULL;
13314 if (PyList_Append(list, unicode))
13315 return NULL;
13316 Py_DECREF(unicode);
13317 }
13318 PyModule_AddObject(m, "_have_functions", list);
Brett Cannona32c4d02016-06-24 14:14:44 -070013319 PyModule_AddObject(m, "DirEntry", (PyObject *)&DirEntryType);
Larry Hastings9cf065c2012-06-22 16:30:09 -070013320
13321 initialized = 1;
13322
Victor Stinner8c62be82010-05-06 00:08:46 +000013323 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013324}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013325
13326#ifdef __cplusplus
13327}
13328#endif