blob: c993fb6b64ef3b8c351cfedcec7ff0ebb3320a62 [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
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000035#include <stdio.h> /* needed for ctermid() */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Ross Lagerwall4d076da2011-03-18 06:56:53 +020048#ifdef HAVE_SYS_UIO_H
49#include <sys/uio.h>
50#endif
51
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000053#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054#endif /* HAVE_SYS_TYPES_H */
55
56#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000057#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000059
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000061#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000062#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000065#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000067
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#ifdef HAVE_FCNTL_H
69#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000070#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000071
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072#ifdef HAVE_GRP_H
73#include <grp.h>
74#endif
75
Barry Warsaw5676bd12003-01-07 20:57:09 +000076#ifdef HAVE_SYSEXITS_H
77#include <sysexits.h>
78#endif /* HAVE_SYSEXITS_H */
79
Anthony Baxter8a560de2004-10-13 15:30:56 +000080#ifdef HAVE_SYS_LOADAVG_H
81#include <sys/loadavg.h>
82#endif
83
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000084#ifdef HAVE_LANGINFO_H
85#include <langinfo.h>
86#endif
87
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000088#ifdef HAVE_SYS_SENDFILE_H
89#include <sys/sendfile.h>
90#endif
91
Benjamin Peterson94b580d2011-08-02 17:30:04 -050092#ifdef HAVE_SCHED_H
93#include <sched.h>
94#endif
95
Benjamin Peterson2dbda072012-03-16 10:12:55 -050096#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050097#undef HAVE_SCHED_SETAFFINITY
98#endif
99
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200100#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400101#define USE_XATTRS
102#endif
103
104#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400105#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
109#ifdef HAVE_SYS_SOCKET_H
110#include <sys/socket.h>
111#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000112#endif
113
Victor Stinner8b905bd2011-10-25 13:34:04 +0200114#ifdef HAVE_DLFCN_H
115#include <dlfcn.h>
116#endif
117
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200118#ifdef __hpux
119#include <sys/mpctl.h>
120#endif
121
122#if defined(__DragonFly__) || \
123 defined(__OpenBSD__) || \
124 defined(__FreeBSD__) || \
125 defined(__NetBSD__) || \
126 defined(__APPLE__)
127#include <sys/sysctl.h>
128#endif
129
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100130#if defined(MS_WINDOWS)
131# define TERMSIZE_USE_CONIO
132#elif defined(HAVE_SYS_IOCTL_H)
133# include <sys/ioctl.h>
134# if defined(HAVE_TERMIOS_H)
135# include <termios.h>
136# endif
137# if defined(TIOCGWINSZ)
138# define TERMSIZE_USE_IOCTL
139# endif
140#endif /* MS_WINDOWS */
141
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000143/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000146#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000150#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000151#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_EXECV 1
154#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SYSTEM 1
156#define HAVE_CWAIT 1
157#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000158#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000159#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160/* Unix functions that the configure script doesn't check for */
161#define HAVE_EXECV 1
162#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000163#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000164#define HAVE_FORK1 1
165#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_GETEGID 1
167#define HAVE_GETEUID 1
168#define HAVE_GETGID 1
169#define HAVE_GETPPID 1
170#define HAVE_GETUID 1
171#define HAVE_KILL 1
172#define HAVE_OPENDIR 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000178#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000179
Victor Stinnera2f7c002012-02-08 03:36:25 +0100180
Larry Hastings61272b72014-01-07 12:41:53 -0800181/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000182# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800183module os
Larry Hastings61272b72014-01-07 12:41:53 -0800184[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000185/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100186
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000188
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000189#if defined(__sgi)&&_COMPILER_VERSION>=700
190/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
191 (default) */
192extern char *ctermid_r(char *);
193#endif
194
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000195#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000199#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif
205#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int chdir(char *);
207extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int chdir(const char *);
210extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000213/*#ifdef HAVE_FCHMOD
214extern int fchmod(int, mode_t);
215#endif*/
216/*#ifdef HAVE_LCHMOD
217extern int lchmod(const char *, mode_t);
218#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chown(const char *, uid_t, gid_t);
220extern char *getcwd(char *, int);
221extern char *strerror(int);
222extern int link(const char *, const char *);
223extern int rename(const char *, const char *);
224extern int stat(const char *, struct stat *);
225extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000228#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000230extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000233
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_UTIME_H
237#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000240#ifdef HAVE_SYS_UTIME_H
241#include <sys/utime.h>
242#define HAVE_UTIME_H /* pretend we do for the rest of this file */
243#endif /* HAVE_SYS_UTIME_H */
244
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#ifdef HAVE_SYS_TIMES_H
246#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000247#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248
249#ifdef HAVE_SYS_PARAM_H
250#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000251#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252
253#ifdef HAVE_SYS_UTSNAME_H
254#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000255#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#define NAMLEN(dirent) strlen((dirent)->d_name)
260#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000261#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000262#include <direct.h>
263#define NAMLEN(dirent) strlen((dirent)->d_name)
264#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000267#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#endif
271#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#endif
274#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000280#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282#endif
283#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000285#endif
286#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000289#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000290#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000291#endif
292#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000293#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000294#endif
295#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100298#ifndef IO_REPARSE_TAG_MOUNT_POINT
299#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
300#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000301#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000302#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000303#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000304#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000305#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000306#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
307#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000308static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000309#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000310#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000311
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313#if defined(PATH_MAX) && PATH_MAX > 1024
314#define MAXPATHLEN PATH_MAX
315#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000318#endif /* MAXPATHLEN */
319
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000320#ifdef UNION_WAIT
321/* Emulate some macros on systems that have a union instead of macros */
322
323#ifndef WIFEXITED
324#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
325#endif
326
327#ifndef WEXITSTATUS
328#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
329#endif
330
331#ifndef WTERMSIG
332#define WTERMSIG(u_wait) ((u_wait).w_termsig)
333#endif
334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335#define WAIT_TYPE union wait
336#define WAIT_STATUS_INT(s) (s.w_status)
337
338#else /* !UNION_WAIT */
339#define WAIT_TYPE int
340#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000341#endif /* UNION_WAIT */
342
Greg Wardb48bc172000-03-01 21:51:56 +0000343/* Don't use the "_r" form if we don't need it (also, won't have a
344 prototype for it, at least on Solaris -- maybe others as well?). */
345#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
346#define USE_CTERMID_R
347#endif
348
Fred Drake699f3522000-06-29 21:12:41 +0000349/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000350#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000351#undef FSTAT
352#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200353#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000354# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700355# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200356# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800357# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000358#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700360# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define FSTAT fstat
362# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000363#endif
364
Tim Peters11b23062003-04-23 02:39:17 +0000365#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000366#include <sys/mkdev.h>
367#else
368#if defined(MAJOR_IN_SYSMACROS)
369#include <sys/sysmacros.h>
370#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000371#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
372#include <sys/mkdev.h>
373#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000374#endif
Fred Drake699f3522000-06-29 21:12:41 +0000375
Victor Stinner6edddfa2013-11-24 19:22:57 +0100376#define DWORD_MAX 4294967295U
377
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200378#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100379#define INITFUNC PyInit_nt
380#define MODNAME "nt"
381#else
382#define INITFUNC PyInit_posix
383#define MODNAME "posix"
384#endif
385
386#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200387/* defined in fileutils.c */
388PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
389PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
390 ULONG, struct _Py_stat_struct *);
391#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700392
393#ifdef MS_WINDOWS
394static int
395win32_warn_bytes_api()
396{
397 return PyErr_WarnEx(PyExc_DeprecationWarning,
398 "The Windows bytes API has been deprecated, "
399 "use Unicode filenames instead",
400 1);
401}
402#endif
403
404
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200405#ifndef MS_WINDOWS
406PyObject *
407_PyLong_FromUid(uid_t uid)
408{
409 if (uid == (uid_t)-1)
410 return PyLong_FromLong(-1);
411 return PyLong_FromUnsignedLong(uid);
412}
413
414PyObject *
415_PyLong_FromGid(gid_t gid)
416{
417 if (gid == (gid_t)-1)
418 return PyLong_FromLong(-1);
419 return PyLong_FromUnsignedLong(gid);
420}
421
422int
423_Py_Uid_Converter(PyObject *obj, void *p)
424{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700425 uid_t uid;
426 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200427 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200428 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700429 unsigned long uresult;
430
431 index = PyNumber_Index(obj);
432 if (index == NULL) {
433 PyErr_Format(PyExc_TypeError,
434 "uid should be integer, not %.200s",
435 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200436 return 0;
437 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700438
439 /*
440 * Handling uid_t is complicated for two reasons:
441 * * Although uid_t is (always?) unsigned, it still
442 * accepts -1.
443 * * We don't know its size in advance--it may be
444 * bigger than an int, or it may be smaller than
445 * a long.
446 *
447 * So a bit of defensive programming is in order.
448 * Start with interpreting the value passed
449 * in as a signed long and see if it works.
450 */
451
452 result = PyLong_AsLongAndOverflow(index, &overflow);
453
454 if (!overflow) {
455 uid = (uid_t)result;
456
457 if (result == -1) {
458 if (PyErr_Occurred())
459 goto fail;
460 /* It's a legitimate -1, we're done. */
461 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463
464 /* Any other negative number is disallowed. */
465 if (result < 0)
466 goto underflow;
467
468 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200469 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700470 (long)uid != result)
471 goto underflow;
472 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200473 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700474
475 if (overflow < 0)
476 goto underflow;
477
478 /*
479 * Okay, the value overflowed a signed long. If it
480 * fits in an *unsigned* long, it may still be okay,
481 * as uid_t may be unsigned long on this platform.
482 */
483 uresult = PyLong_AsUnsignedLong(index);
484 if (PyErr_Occurred()) {
485 if (PyErr_ExceptionMatches(PyExc_OverflowError))
486 goto overflow;
487 goto fail;
488 }
489
490 uid = (uid_t)uresult;
491
492 /*
493 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
494 * but this value would get interpreted as (uid_t)-1 by chown
495 * and its siblings. That's not what the user meant! So we
496 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100497 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700498 */
499 if (uid == (uid_t)-1)
500 goto overflow;
501
502 /* Ensure the value wasn't truncated. */
503 if (sizeof(uid_t) < sizeof(long) &&
504 (unsigned long)uid != uresult)
505 goto overflow;
506 /* fallthrough */
507
508success:
509 Py_DECREF(index);
510 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200511 return 1;
512
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700515 "uid is less than minimum");
516 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200519 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 "uid is greater than maximum");
521 /* fallthrough */
522
523fail:
524 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200525 return 0;
526}
527
528int
529_Py_Gid_Converter(PyObject *obj, void *p)
530{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700531 gid_t gid;
532 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200533 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200534 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 unsigned long uresult;
536
537 index = PyNumber_Index(obj);
538 if (index == NULL) {
539 PyErr_Format(PyExc_TypeError,
540 "gid should be integer, not %.200s",
541 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200542 return 0;
543 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544
545 /*
546 * Handling gid_t is complicated for two reasons:
547 * * Although gid_t is (always?) unsigned, it still
548 * accepts -1.
549 * * We don't know its size in advance--it may be
550 * bigger than an int, or it may be smaller than
551 * a long.
552 *
553 * So a bit of defensive programming is in order.
554 * Start with interpreting the value passed
555 * in as a signed long and see if it works.
556 */
557
558 result = PyLong_AsLongAndOverflow(index, &overflow);
559
560 if (!overflow) {
561 gid = (gid_t)result;
562
563 if (result == -1) {
564 if (PyErr_Occurred())
565 goto fail;
566 /* It's a legitimate -1, we're done. */
567 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569
570 /* Any other negative number is disallowed. */
571 if (result < 0) {
572 goto underflow;
573 }
574
575 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700577 (long)gid != result)
578 goto underflow;
579 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200580 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700581
582 if (overflow < 0)
583 goto underflow;
584
585 /*
586 * Okay, the value overflowed a signed long. If it
587 * fits in an *unsigned* long, it may still be okay,
588 * as gid_t may be unsigned long on this platform.
589 */
590 uresult = PyLong_AsUnsignedLong(index);
591 if (PyErr_Occurred()) {
592 if (PyErr_ExceptionMatches(PyExc_OverflowError))
593 goto overflow;
594 goto fail;
595 }
596
597 gid = (gid_t)uresult;
598
599 /*
600 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
601 * but this value would get interpreted as (gid_t)-1 by chown
602 * and its siblings. That's not what the user meant! So we
603 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100604 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700605 */
606 if (gid == (gid_t)-1)
607 goto overflow;
608
609 /* Ensure the value wasn't truncated. */
610 if (sizeof(gid_t) < sizeof(long) &&
611 (unsigned long)gid != uresult)
612 goto overflow;
613 /* fallthrough */
614
615success:
616 Py_DECREF(index);
617 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618 return 1;
619
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700622 "gid is less than minimum");
623 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700627 "gid is greater than maximum");
628 /* fallthrough */
629
630fail:
631 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 return 0;
633}
634#endif /* MS_WINDOWS */
635
636
Gregory P. Smith702dada2015-01-28 16:07:52 -0800637#ifdef HAVE_LONG_LONG
638# define _PyLong_FromDev PyLong_FromLongLong
639#else
640# define _PyLong_FromDev PyLong_FromLong
641#endif
642
643
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200644#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
645static int
646_Py_Dev_Converter(PyObject *obj, void *p)
647{
648#ifdef HAVE_LONG_LONG
649 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
650#else
651 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
652#endif
653 if (PyErr_Occurred())
654 return 0;
655 return 1;
656}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800657#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200658
659
Larry Hastings9cf065c2012-06-22 16:30:09 -0700660#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400661/*
662 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
663 * without the int cast, the value gets interpreted as uint (4291925331),
664 * which doesn't play nicely with all the initializer lines in this file that
665 * look like this:
666 * int dir_fd = DEFAULT_DIR_FD;
667 */
668#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700669#else
670#define DEFAULT_DIR_FD (-100)
671#endif
672
673static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200674_fd_converter(PyObject *o, int *p, const char *allowed)
675{
676 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700677 long long_value;
678
679 PyObject *index = PyNumber_Index(o);
680 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200681 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682 "argument should be %s, not %.200s",
683 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684 return 0;
685 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700686
687 long_value = PyLong_AsLongAndOverflow(index, &overflow);
688 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200689 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700691 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700692 return 0;
693 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700697 return 0;
698 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700699
Larry Hastings9cf065c2012-06-22 16:30:09 -0700700 *p = (int)long_value;
701 return 1;
702}
703
704static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200705dir_fd_converter(PyObject *o, void *p)
706{
707 if (o == Py_None) {
708 *(int *)p = DEFAULT_DIR_FD;
709 return 1;
710 }
711 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700712}
713
714
Larry Hastings9cf065c2012-06-22 16:30:09 -0700715/*
716 * A PyArg_ParseTuple "converter" function
717 * that handles filesystem paths in the manner
718 * preferred by the os module.
719 *
720 * path_converter accepts (Unicode) strings and their
721 * subclasses, and bytes and their subclasses. What
722 * it does with the argument depends on the platform:
723 *
724 * * On Windows, if we get a (Unicode) string we
725 * extract the wchar_t * and return it; if we get
726 * bytes we extract the char * and return that.
727 *
728 * * On all other platforms, strings are encoded
729 * to bytes using PyUnicode_FSConverter, then we
730 * extract the char * from the bytes object and
731 * return that.
732 *
733 * path_converter also optionally accepts signed
734 * integers (representing open file descriptors) instead
735 * of path strings.
736 *
737 * Input fields:
738 * path.nullable
739 * If nonzero, the path is permitted to be None.
740 * path.allow_fd
741 * If nonzero, the path is permitted to be a file handle
742 * (a signed int) instead of a string.
743 * path.function_name
744 * If non-NULL, path_converter will use that as the name
745 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700746 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747 * path.argument_name
748 * If non-NULL, path_converter will use that as the name
749 * of the parameter in error messages.
750 * (If path.argument_name is NULL it uses "path".)
751 *
752 * Output fields:
753 * path.wide
754 * Points to the path if it was expressed as Unicode
755 * and was not encoded. (Only used on Windows.)
756 * path.narrow
757 * Points to the path if it was expressed as bytes,
758 * or it was Unicode and was encoded to bytes.
759 * path.fd
760 * Contains a file descriptor if path.accept_fd was true
761 * and the caller provided a signed integer instead of any
762 * sort of string.
763 *
764 * WARNING: if your "path" parameter is optional, and is
765 * unspecified, path_converter will never get called.
766 * So if you set allow_fd, you *MUST* initialize path.fd = -1
767 * yourself!
768 * path.length
769 * The length of the path in characters, if specified as
770 * a string.
771 * path.object
772 * The original object passed in.
773 * path.cleanup
774 * For internal use only. May point to a temporary object.
775 * (Pay no attention to the man behind the curtain.)
776 *
777 * At most one of path.wide or path.narrow will be non-NULL.
778 * If path was None and path.nullable was set,
779 * or if path was an integer and path.allow_fd was set,
780 * both path.wide and path.narrow will be NULL
781 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200782 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 * path_converter takes care to not write to the path_t
784 * unless it's successful. However it must reset the
785 * "cleanup" field each time it's called.
786 *
787 * Use as follows:
788 * path_t path;
789 * memset(&path, 0, sizeof(path));
790 * PyArg_ParseTuple(args, "O&", path_converter, &path);
791 * // ... use values from path ...
792 * path_cleanup(&path);
793 *
794 * (Note that if PyArg_Parse fails you don't need to call
795 * path_cleanup(). However it is safe to do so.)
796 */
797typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100798 const char *function_name;
799 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700800 int nullable;
801 int allow_fd;
802 wchar_t *wide;
803 char *narrow;
804 int fd;
805 Py_ssize_t length;
806 PyObject *object;
807 PyObject *cleanup;
808} path_t;
809
Larry Hastings2f936352014-08-05 14:04:04 +1000810#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
811 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700812
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813static void
814path_cleanup(path_t *path) {
815 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200816 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817 }
818}
819
820static int
821path_converter(PyObject *o, void *p) {
822 path_t *path = (path_t *)p;
823 PyObject *unicode, *bytes;
824 Py_ssize_t length;
825 char *narrow;
826
827#define FORMAT_EXCEPTION(exc, fmt) \
828 PyErr_Format(exc, "%s%s" fmt, \
829 path->function_name ? path->function_name : "", \
830 path->function_name ? ": " : "", \
831 path->argument_name ? path->argument_name : "path")
832
833 /* Py_CLEANUP_SUPPORTED support */
834 if (o == NULL) {
835 path_cleanup(path);
836 return 1;
837 }
838
839 /* ensure it's always safe to call path_cleanup() */
840 path->cleanup = NULL;
841
842 if (o == Py_None) {
843 if (!path->nullable) {
844 FORMAT_EXCEPTION(PyExc_TypeError,
845 "can't specify None for %s argument");
846 return 0;
847 }
848 path->wide = NULL;
849 path->narrow = NULL;
850 path->length = 0;
851 path->object = o;
852 path->fd = -1;
853 return 1;
854 }
855
856 unicode = PyUnicode_FromObject(o);
857 if (unicode) {
858#ifdef MS_WINDOWS
859 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100860
861 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
862 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700863 Py_DECREF(unicode);
864 return 0;
865 }
Victor Stinner59799a82013-11-13 14:17:30 +0100866 if (length > 32767) {
867 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700868 Py_DECREF(unicode);
869 return 0;
870 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300871 if (wcslen(wide) != length) {
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +0300872 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300873 Py_DECREF(unicode);
874 return 0;
875 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876
877 path->wide = wide;
878 path->narrow = NULL;
879 path->length = length;
880 path->object = o;
881 path->fd = -1;
882 path->cleanup = unicode;
883 return Py_CLEANUP_SUPPORTED;
884#else
885 int converted = PyUnicode_FSConverter(unicode, &bytes);
886 Py_DECREF(unicode);
887 if (!converted)
888 bytes = NULL;
889#endif
890 }
891 else {
892 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200893 if (PyObject_CheckBuffer(o))
894 bytes = PyBytes_FromObject(o);
895 else
896 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700897 if (!bytes) {
898 PyErr_Clear();
899 if (path->allow_fd) {
900 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200901 int result = _fd_converter(o, &fd,
902 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903 if (result) {
904 path->wide = NULL;
905 path->narrow = NULL;
906 path->length = 0;
907 path->object = o;
908 path->fd = fd;
909 return result;
910 }
911 }
912 }
913 }
914
915 if (!bytes) {
916 if (!PyErr_Occurred())
917 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
918 return 0;
919 }
920
921#ifdef MS_WINDOWS
922 if (win32_warn_bytes_api()) {
923 Py_DECREF(bytes);
924 return 0;
925 }
926#endif
927
928 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
954argument_unavailable_error(char *function_name, char *argument_name) {
955 PyErr_Format(PyExc_NotImplementedError,
956 "%s%s%s unavailable on this platform",
957 (function_name != NULL) ? function_name : "",
958 (function_name != NULL) ? ": ": "",
959 argument_name);
960}
961
962static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200963dir_fd_unavailable(PyObject *o, void *p)
964{
965 int dir_fd;
966 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200968 if (dir_fd != DEFAULT_DIR_FD) {
969 argument_unavailable_error(NULL, "dir_fd");
970 return 0;
971 }
972 *(int *)p = dir_fd;
973 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700974}
975
976static int
977fd_specified(char *function_name, int fd) {
978 if (fd == -1)
979 return 0;
980
981 argument_unavailable_error(function_name, "fd");
982 return 1;
983}
984
985static int
986follow_symlinks_specified(char *function_name, int follow_symlinks) {
987 if (follow_symlinks)
988 return 0;
989
990 argument_unavailable_error(function_name, "follow_symlinks");
991 return 1;
992}
993
994static int
995path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
996 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
997 PyErr_Format(PyExc_ValueError,
998 "%s: can't specify dir_fd without matching path",
999 function_name);
1000 return 1;
1001 }
1002 return 0;
1003}
1004
1005static int
1006dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
1007 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1008 PyErr_Format(PyExc_ValueError,
1009 "%s: can't specify both dir_fd and fd",
1010 function_name);
1011 return 1;
1012 }
1013 return 0;
1014}
1015
1016static int
1017fd_and_follow_symlinks_invalid(char *function_name, int fd,
1018 int follow_symlinks) {
1019 if ((fd > 0) && (!follow_symlinks)) {
1020 PyErr_Format(PyExc_ValueError,
1021 "%s: cannot use fd and follow_symlinks together",
1022 function_name);
1023 return 1;
1024 }
1025 return 0;
1026}
1027
1028static int
1029dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1030 int follow_symlinks) {
1031 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1032 PyErr_Format(PyExc_ValueError,
1033 "%s: cannot use dir_fd and follow_symlinks together",
1034 function_name);
1035 return 1;
1036 }
1037 return 0;
1038}
1039
Larry Hastings2f936352014-08-05 14:04:04 +10001040#ifdef MS_WINDOWS
1041 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001042#else
Larry Hastings2f936352014-08-05 14:04:04 +10001043 typedef off_t Py_off_t;
1044#endif
1045
1046static int
1047Py_off_t_converter(PyObject *arg, void *addr)
1048{
1049#ifdef HAVE_LARGEFILE_SUPPORT
1050 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1051#else
1052 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001053#endif
1054 if (PyErr_Occurred())
1055 return 0;
1056 return 1;
1057}
Larry Hastings2f936352014-08-05 14:04:04 +10001058
1059static PyObject *
1060PyLong_FromPy_off_t(Py_off_t offset)
1061{
1062#ifdef HAVE_LARGEFILE_SUPPORT
1063 return PyLong_FromLongLong(offset);
1064#else
1065 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001066#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001067}
1068
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001069
Steve Dowerd81431f2015-03-06 14:47:02 -08001070#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1071/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1072 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001074#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001075#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001076#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001077#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001078#define _NO_CONSOLE_FILENO (intptr_t)-2
1079
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001080/* the special case of checking dup2. The target fd must be in a sensible range */
1081static int
1082_PyVerify_fd_dup2(int fd1, int fd2)
1083{
Victor Stinner8c62be82010-05-06 00:08:46 +00001084 if (!_PyVerify_fd(fd1))
1085 return 0;
1086 if (fd2 == _NO_CONSOLE_FILENO)
1087 return 0;
1088 if ((unsigned)fd2 < _NHANDLE_)
1089 return 1;
1090 else
1091 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001092}
1093#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001094#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001095#endif
1096
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001097#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001098
1099static int
Brian Curtind25aef52011-06-13 15:16:04 -05001100win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001101{
1102 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1103 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1104 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001105
1106 if (0 == DeviceIoControl(
1107 reparse_point_handle,
1108 FSCTL_GET_REPARSE_POINT,
1109 NULL, 0, /* in buffer */
1110 target_buffer, sizeof(target_buffer),
1111 &n_bytes_returned,
1112 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001113 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001114
1115 if (reparse_tag)
1116 *reparse_tag = rdb->ReparseTag;
1117
Brian Curtind25aef52011-06-13 15:16:04 -05001118 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001119}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001120
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001121#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001122
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001124#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001125/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001126** environ directly, we must obtain it with _NSGetEnviron(). See also
1127** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001128*/
1129#include <crt_externs.h>
1130static char **environ;
1131#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001133#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134
Barry Warsaw53699e91996-12-10 23:23:01 +00001135static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001136convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137{
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001139#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001140 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001141#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001142 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001143#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001144
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 d = PyDict_New();
1146 if (d == NULL)
1147 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001148#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001149 if (environ == NULL)
1150 environ = *_NSGetEnviron();
1151#endif
1152#ifdef MS_WINDOWS
1153 /* _wenviron must be initialized in this way if the program is started
1154 through main() instead of wmain(). */
1155 _wgetenv(L"");
1156 if (_wenviron == NULL)
1157 return d;
1158 /* This part ignores errors */
1159 for (e = _wenviron; *e != NULL; e++) {
1160 PyObject *k;
1161 PyObject *v;
1162 wchar_t *p = wcschr(*e, L'=');
1163 if (p == NULL)
1164 continue;
1165 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1166 if (k == NULL) {
1167 PyErr_Clear();
1168 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001169 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001170 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1171 if (v == NULL) {
1172 PyErr_Clear();
1173 Py_DECREF(k);
1174 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001175 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001176 if (PyDict_GetItem(d, k) == NULL) {
1177 if (PyDict_SetItem(d, k, v) != 0)
1178 PyErr_Clear();
1179 }
1180 Py_DECREF(k);
1181 Py_DECREF(v);
1182 }
1183#else
1184 if (environ == NULL)
1185 return d;
1186 /* This part ignores errors */
1187 for (e = environ; *e != NULL; e++) {
1188 PyObject *k;
1189 PyObject *v;
1190 char *p = strchr(*e, '=');
1191 if (p == NULL)
1192 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001193 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001194 if (k == NULL) {
1195 PyErr_Clear();
1196 continue;
1197 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001198 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 if (v == NULL) {
1200 PyErr_Clear();
1201 Py_DECREF(k);
1202 continue;
1203 }
1204 if (PyDict_GetItem(d, k) == NULL) {
1205 if (PyDict_SetItem(d, k, v) != 0)
1206 PyErr_Clear();
1207 }
1208 Py_DECREF(k);
1209 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001210 }
1211#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001212 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213}
1214
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215/* Set a POSIX-specific error from errno, and return NULL */
1216
Barry Warsawd58d7641998-07-23 16:14:40 +00001217static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001218posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001219{
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221}
Mark Hammondef8b6542001-05-13 08:04:26 +00001222
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001223#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001224static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001225win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001226{
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 /* XXX We should pass the function name along in the future.
1228 (winreg.c also wants to pass the function name.)
1229 This would however require an additional param to the
1230 Windows error object, which is non-trivial.
1231 */
1232 errno = GetLastError();
1233 if (filename)
1234 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1235 else
1236 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001237}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001238
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001239static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001240win32_error_object(char* function, PyObject* filename)
1241{
1242 /* XXX - see win32_error for comments on 'function' */
1243 errno = GetLastError();
1244 if (filename)
1245 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001246 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001247 errno,
1248 filename);
1249 else
1250 return PyErr_SetFromWindowsErr(errno);
1251}
1252
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001253#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001256path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001257{
1258#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001259 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1260 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001261#else
Victor Stinner292c8352012-10-30 02:17:38 +01001262 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001263#endif
1264}
1265
Larry Hastings31826802013-10-19 00:09:25 -07001266
Larry Hastingsb0827312014-02-09 22:05:19 -08001267static PyObject *
1268path_error2(path_t *path, path_t *path2)
1269{
1270#ifdef MS_WINDOWS
1271 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1272 0, path->object, path2->object);
1273#else
1274 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1275 path->object, path2->object);
1276#endif
1277}
1278
1279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001280/* POSIX generic methods */
1281
Larry Hastings2f936352014-08-05 14:04:04 +10001282static int
1283fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001284{
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001286 int *pointer = (int *)p;
1287 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001289 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001290 *pointer = fd;
1291 return 1;
1292}
1293
1294static PyObject *
1295posix_fildes_fd(int fd, int (*func)(int))
1296{
1297 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001298 int async_err = 0;
1299
Steve Dower8fc89802015-04-12 00:26:27 -04001300 if (!_PyVerify_fd(fd))
1301 return posix_error();
1302
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001303 do {
1304 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001305 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001306 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001307 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001308 Py_END_ALLOW_THREADS
1309 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1310 if (res != 0)
1311 return (!async_err) ? posix_error() : NULL;
1312 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001313}
Guido van Rossum21142a01999-01-08 21:05:37 +00001314
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001316#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317/* This is a reimplementation of the C library's chdir function,
1318 but one that produces Win32 errors instead of DOS error codes.
1319 chdir is essentially a wrapper around SetCurrentDirectory; however,
1320 it also needs to set "magic" environment variables indicating
1321 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001322static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001323win32_chdir(LPCSTR path)
1324{
Victor Stinner75875072013-11-24 19:23:25 +01001325 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001326 int result;
1327 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328
Victor Stinner8c62be82010-05-06 00:08:46 +00001329 if(!SetCurrentDirectoryA(path))
1330 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001331 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 if (!result)
1333 return FALSE;
1334 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001335 than MAX_PATH-1 (not including the final null character). */
1336 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001337 if (strncmp(new_path, "\\\\", 2) == 0 ||
1338 strncmp(new_path, "//", 2) == 0)
1339 /* UNC path, nothing to do. */
1340 return TRUE;
1341 env[1] = new_path[0];
1342 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001343}
1344
1345/* The Unicode version differs from the ANSI version
1346 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001347static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001348win32_wchdir(LPCWSTR path)
1349{
Victor Stinnered537822015-12-13 21:40:26 +01001350 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 int result;
1352 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001353
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 if(!SetCurrentDirectoryW(path))
1355 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001356 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 if (!result)
1358 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001359 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001360 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 if (!new_path) {
1362 SetLastError(ERROR_OUTOFMEMORY);
1363 return FALSE;
1364 }
1365 result = GetCurrentDirectoryW(result, new_path);
1366 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001367 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 return FALSE;
1369 }
1370 }
1371 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1372 wcsncmp(new_path, L"//", 2) == 0)
1373 /* UNC path, nothing to do. */
1374 return TRUE;
1375 env[1] = new_path[0];
1376 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001377 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001378 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380}
1381#endif
1382
Martin v. Löwis14694662006-02-03 12:54:16 +00001383#ifdef MS_WINDOWS
1384/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1385 - time stamps are restricted to second resolution
1386 - file modification times suffer from forth-and-back conversions between
1387 UTC and local time
1388 Therefore, we implement our own stat, based on the Win32 API directly.
1389*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001390#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001391#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001392
Guido van Rossumd8faa362007-04-27 19:54:29 +00001393static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001394attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001395{
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 HANDLE hFindFile;
1397 WIN32_FIND_DATAA FileData;
1398 hFindFile = FindFirstFileA(pszFile, &FileData);
1399 if (hFindFile == INVALID_HANDLE_VALUE)
1400 return FALSE;
1401 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001402 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001404 info->dwFileAttributes = FileData.dwFileAttributes;
1405 info->ftCreationTime = FileData.ftCreationTime;
1406 info->ftLastAccessTime = FileData.ftLastAccessTime;
1407 info->ftLastWriteTime = FileData.ftLastWriteTime;
1408 info->nFileSizeHigh = FileData.nFileSizeHigh;
1409 info->nFileSizeLow = FileData.nFileSizeLow;
1410/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001411 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1412 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001414}
1415
Victor Stinner6036e442015-03-08 01:58:04 +01001416static void
1417find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1418 BY_HANDLE_FILE_INFORMATION *info,
1419 ULONG *reparse_tag)
1420{
1421 memset(info, 0, sizeof(*info));
1422 info->dwFileAttributes = pFileData->dwFileAttributes;
1423 info->ftCreationTime = pFileData->ftCreationTime;
1424 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1425 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1426 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1427 info->nFileSizeLow = pFileData->nFileSizeLow;
1428/* info->nNumberOfLinks = 1; */
1429 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1430 *reparse_tag = pFileData->dwReserved0;
1431 else
1432 *reparse_tag = 0;
1433}
1434
Guido van Rossumd8faa362007-04-27 19:54:29 +00001435static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001436attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001437{
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 HANDLE hFindFile;
1439 WIN32_FIND_DATAW FileData;
1440 hFindFile = FindFirstFileW(pszFile, &FileData);
1441 if (hFindFile == INVALID_HANDLE_VALUE)
1442 return FALSE;
1443 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001444 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001446}
1447
Brian Curtind25aef52011-06-13 15:16:04 -05001448static BOOL
1449get_target_path(HANDLE hdl, wchar_t **target_path)
1450{
1451 int buf_size, result_length;
1452 wchar_t *buf;
1453
1454 /* We have a good handle to the target, use it to determine
1455 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001456 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1457 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001458 if(!buf_size)
1459 return FALSE;
1460
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001461 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001462 if (!buf) {
1463 SetLastError(ERROR_OUTOFMEMORY);
1464 return FALSE;
1465 }
1466
Steve Dower2ea51c92015-03-20 21:49:12 -07001467 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001468 buf, buf_size, VOLUME_NAME_DOS);
1469
1470 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001471 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001472 return FALSE;
1473 }
1474
1475 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001476 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001477 return FALSE;
1478 }
1479
1480 buf[result_length] = 0;
1481
1482 *target_path = buf;
1483 return TRUE;
1484}
1485
1486static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001487win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001488 BOOL traverse);
1489static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001490win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001491 BOOL traverse)
1492{
Victor Stinner26de69d2011-06-17 15:15:38 +02001493 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001494 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001495 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001496 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001497 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001498 const char *dot;
1499
1500 hFile = CreateFileA(
1501 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001502 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001503 0, /* share mode */
1504 NULL, /* security attributes */
1505 OPEN_EXISTING,
1506 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001507 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1508 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001509 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001510 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1511 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001512 NULL);
1513
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001514 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515 /* Either the target doesn't exist, or we don't have access to
1516 get a handle to it. If the former, we need to return an error.
1517 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001518 DWORD lastError = GetLastError();
1519 if (lastError != ERROR_ACCESS_DENIED &&
1520 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 return -1;
1522 /* Could not get attributes on open file. Fall back to
1523 reading the directory. */
1524 if (!attributes_from_dir(path, &info, &reparse_tag))
1525 /* Very strange. This should not fail now */
1526 return -1;
1527 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1528 if (traverse) {
1529 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001530 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001532 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001534 } else {
1535 if (!GetFileInformationByHandle(hFile, &info)) {
1536 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001537 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001538 }
1539 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001540 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1541 return -1;
1542
1543 /* Close the outer open file handle now that we're about to
1544 reopen it with different flags. */
1545 if (!CloseHandle(hFile))
1546 return -1;
1547
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001548 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001549 /* In order to call GetFinalPathNameByHandle we need to open
1550 the file without the reparse handling flag set. */
1551 hFile2 = CreateFileA(
1552 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1553 NULL, OPEN_EXISTING,
1554 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1555 NULL);
1556 if (hFile2 == INVALID_HANDLE_VALUE)
1557 return -1;
1558
1559 if (!get_target_path(hFile2, &target_path))
1560 return -1;
1561
1562 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001563 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001564 return code;
1565 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001566 } else
1567 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001568 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001569 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001570
1571 /* Set S_IEXEC if it is an .exe, .bat, ... */
1572 dot = strrchr(path, '.');
1573 if (dot) {
1574 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1575 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1576 result->st_mode |= 0111;
1577 }
1578 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579}
1580
1581static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001582win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001583 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001584{
1585 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001586 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001587 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001588 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001589 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001590 const wchar_t *dot;
1591
1592 hFile = CreateFileW(
1593 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001594 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 0, /* share mode */
1596 NULL, /* security attributes */
1597 OPEN_EXISTING,
1598 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001599 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1600 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001601 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001602 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001603 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001604 NULL);
1605
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001606 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607 /* Either the target doesn't exist, or we don't have access to
1608 get a handle to it. If the former, we need to return an error.
1609 If the latter, we can use attributes_from_dir. */
Berker Peksagbf3c1c32016-09-18 13:56:29 +03001610 DWORD lastError = GetLastError();
1611 if (lastError != ERROR_ACCESS_DENIED &&
1612 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Berker Peksagbf3c1c32016-09-18 13:56:29 +03001622 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileW(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001655 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001661 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = wcsrchr(path, '.');
1665 if (dot) {
1666 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1667 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001674win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001675{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001676 /* Protocol violation: we explicitly clear errno, instead of
1677 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001678 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 errno = 0;
1680 return code;
1681}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001684win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685{
1686 /* Protocol violation: we explicitly clear errno, instead of
1687 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001688 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 errno = 0;
1690 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691}
Brian Curtind25aef52011-06-13 15:16:04 -05001692/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001693
1694 In Posix, stat automatically traverses symlinks and returns the stat
1695 structure for the target. In Windows, the equivalent GetFileAttributes by
1696 default does not traverse symlinks and instead returns attributes for
1697 the symlink.
1698
1699 Therefore, win32_lstat will get the attributes traditionally, and
1700 win32_stat will first explicitly resolve the symlink target and then will
1701 call win32_lstat on that result.
1702
Ezio Melotti4969f702011-03-15 05:59:46 +02001703 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001704
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001705static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001706win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001707{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001708 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001709}
1710
Victor Stinner8c62be82010-05-06 00:08:46 +00001711static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001712win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001713{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001715}
1716
1717static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001718win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001719{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001721}
1722
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001723static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001724win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001725{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001727}
1728
Martin v. Löwis14694662006-02-03 12:54:16 +00001729#endif /* MS_WINDOWS */
1730
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001731PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001732"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001733This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001734 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001735or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1736\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001737Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1738or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001739\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001740See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001741
1742static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001743 {"st_mode", "protection bits"},
1744 {"st_ino", "inode"},
1745 {"st_dev", "device"},
1746 {"st_nlink", "number of hard links"},
1747 {"st_uid", "user ID of owner"},
1748 {"st_gid", "group ID of owner"},
1749 {"st_size", "total size, in bytes"},
1750 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1751 {NULL, "integer time of last access"},
1752 {NULL, "integer time of last modification"},
1753 {NULL, "integer time of last change"},
1754 {"st_atime", "time of last access"},
1755 {"st_mtime", "time of last modification"},
1756 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001757 {"st_atime_ns", "time of last access in nanoseconds"},
1758 {"st_mtime_ns", "time of last modification in nanoseconds"},
1759 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001760#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001763#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_blocks", "number of blocks allocated"},
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_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001768#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001769#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001771#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001772#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001774#endif
1775#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001777#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001778#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1779 {"st_file_attributes", "Windows file attribute bits"},
1780#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782};
1783
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001785#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001787#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001788#endif
1789
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1792#else
1793#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1794#endif
1795
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001796#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1798#else
1799#define ST_RDEV_IDX ST_BLOCKS_IDX
1800#endif
1801
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001802#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1803#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1804#else
1805#define ST_FLAGS_IDX ST_RDEV_IDX
1806#endif
1807
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001808#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001809#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001810#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001811#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001812#endif
1813
1814#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1815#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1816#else
1817#define ST_BIRTHTIME_IDX ST_GEN_IDX
1818#endif
1819
Zachary Ware63f277b2014-06-19 09:46:37 -05001820#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1821#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1822#else
1823#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1824#endif
1825
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001826static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 "stat_result", /* name */
1828 stat_result__doc__, /* doc */
1829 stat_result_fields,
1830 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001831};
1832
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1835This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001837or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001838\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001840
1841static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 {"f_bsize", },
1843 {"f_frsize", },
1844 {"f_blocks", },
1845 {"f_bfree", },
1846 {"f_bavail", },
1847 {"f_files", },
1848 {"f_ffree", },
1849 {"f_favail", },
1850 {"f_flag", },
1851 {"f_namemax",},
1852 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853};
1854
1855static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 "statvfs_result", /* name */
1857 statvfs_result__doc__, /* doc */
1858 statvfs_result_fields,
1859 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001860};
1861
Ross Lagerwall7807c352011-03-17 20:20:30 +02001862#if defined(HAVE_WAITID) && !defined(__APPLE__)
1863PyDoc_STRVAR(waitid_result__doc__,
1864"waitid_result: Result from waitid.\n\n\
1865This object may be accessed either as a tuple of\n\
1866 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1867or via the attributes si_pid, si_uid, and so on.\n\
1868\n\
1869See os.waitid for more information.");
1870
1871static PyStructSequence_Field waitid_result_fields[] = {
1872 {"si_pid", },
1873 {"si_uid", },
1874 {"si_signo", },
1875 {"si_status", },
1876 {"si_code", },
1877 {0}
1878};
1879
1880static PyStructSequence_Desc waitid_result_desc = {
1881 "waitid_result", /* name */
1882 waitid_result__doc__, /* doc */
1883 waitid_result_fields,
1884 5
1885};
1886static PyTypeObject WaitidResultType;
1887#endif
1888
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001889static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001890static PyTypeObject StatResultType;
1891static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001892#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001893static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001894#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001895static newfunc structseq_new;
1896
1897static PyObject *
1898statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1899{
Victor Stinner8c62be82010-05-06 00:08:46 +00001900 PyStructSequence *result;
1901 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001902
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 result = (PyStructSequence*)structseq_new(type, args, kwds);
1904 if (!result)
1905 return NULL;
1906 /* If we have been initialized from a tuple,
1907 st_?time might be set to None. Initialize it
1908 from the int slots. */
1909 for (i = 7; i <= 9; i++) {
1910 if (result->ob_item[i+3] == Py_None) {
1911 Py_DECREF(Py_None);
1912 Py_INCREF(result->ob_item[i]);
1913 result->ob_item[i+3] = result->ob_item[i];
1914 }
1915 }
1916 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001917}
1918
1919
1920
1921/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001922static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001923
1924PyDoc_STRVAR(stat_float_times__doc__,
1925"stat_float_times([newval]) -> oldval\n\n\
1926Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001927\n\
1928If value is True, future calls to stat() return floats; if it is False,\n\
1929future calls return ints.\n\
1930If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001931
Larry Hastings2f936352014-08-05 14:04:04 +10001932/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001933static PyObject*
1934stat_float_times(PyObject* self, PyObject *args)
1935{
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 int newval = -1;
1937 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1938 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001939 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1940 "stat_float_times() is deprecated",
1941 1))
1942 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 if (newval == -1)
1944 /* Return old value */
1945 return PyBool_FromLong(_stat_float_times);
1946 _stat_float_times = newval;
1947 Py_INCREF(Py_None);
1948 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001949}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001950
Larry Hastings6fe20b32012-04-19 15:07:49 -07001951static PyObject *billion = NULL;
1952
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001953static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001954fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001955{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 PyObject *s = _PyLong_FromTime_t(sec);
1957 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1958 PyObject *s_in_ns = NULL;
1959 PyObject *ns_total = NULL;
1960 PyObject *float_s = NULL;
1961
1962 if (!(s && ns_fractional))
1963 goto exit;
1964
1965 s_in_ns = PyNumber_Multiply(s, billion);
1966 if (!s_in_ns)
1967 goto exit;
1968
1969 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1970 if (!ns_total)
1971 goto exit;
1972
Victor Stinner4195b5c2012-02-08 23:03:19 +01001973 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001974 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1975 if (!float_s)
1976 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001978 else {
1979 float_s = s;
1980 Py_INCREF(float_s);
1981 }
1982
1983 PyStructSequence_SET_ITEM(v, index, s);
1984 PyStructSequence_SET_ITEM(v, index+3, float_s);
1985 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1986 s = NULL;
1987 float_s = NULL;
1988 ns_total = NULL;
1989exit:
1990 Py_XDECREF(s);
1991 Py_XDECREF(ns_fractional);
1992 Py_XDECREF(s_in_ns);
1993 Py_XDECREF(ns_total);
1994 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001995}
1996
Tim Peters5aa91602002-01-30 05:46:57 +00001997/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001998 (used by posix_stat() and posix_fstat()) */
1999static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002000_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002001{
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 unsigned long ansec, mnsec, cnsec;
2003 PyObject *v = PyStructSequence_New(&StatResultType);
2004 if (v == NULL)
2005 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002006
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002008#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 PyStructSequence_SET_ITEM(v, 1,
2010 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002011#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002013#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002014#ifdef MS_WINDOWS
2015 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002016#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002017 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002018#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002020#if defined(MS_WINDOWS)
2021 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2022 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2023#else
2024 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2025 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2026#endif
Fred Drake699f3522000-06-29 21:12:41 +00002027#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002028 PyStructSequence_SET_ITEM(v, 6,
2029 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002030#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002032#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002033
Martin v. Löwis14694662006-02-03 12:54:16 +00002034#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 ansec = st->st_atim.tv_nsec;
2036 mnsec = st->st_mtim.tv_nsec;
2037 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002038#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 ansec = st->st_atimespec.tv_nsec;
2040 mnsec = st->st_mtimespec.tv_nsec;
2041 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002042#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002043 ansec = st->st_atime_nsec;
2044 mnsec = st->st_mtime_nsec;
2045 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002046#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002048#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002049 fill_time(v, 7, st->st_atime, ansec);
2050 fill_time(v, 8, st->st_mtime, mnsec);
2051 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002052
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002053#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2055 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002056#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002057#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2059 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002061#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2063 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002064#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2067 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002068#endif
2069#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002070 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002071 PyObject *val;
2072 unsigned long bsec,bnsec;
2073 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002075 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002077 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002078#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002079 if (_stat_float_times) {
2080 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2081 } else {
2082 val = PyLong_FromLong((long)bsec);
2083 }
2084 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2085 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002087#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002088#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2090 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002091#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002092#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2093 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2094 PyLong_FromUnsignedLong(st->st_file_attributes));
2095#endif
Fred Drake699f3522000-06-29 21:12:41 +00002096
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 if (PyErr_Occurred()) {
2098 Py_DECREF(v);
2099 return NULL;
2100 }
Fred Drake699f3522000-06-29 21:12:41 +00002101
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002103}
2104
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105/* POSIX methods */
2106
Guido van Rossum94f6f721999-01-06 18:42:14 +00002107
2108static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002109posix_do_stat(char *function_name, path_t *path,
2110 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002111{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002112 STRUCT_STAT st;
2113 int result;
2114
2115#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2116 if (follow_symlinks_specified(function_name, follow_symlinks))
2117 return NULL;
2118#endif
2119
2120 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2121 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2122 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2123 return NULL;
2124
2125 Py_BEGIN_ALLOW_THREADS
2126 if (path->fd != -1)
2127 result = FSTAT(path->fd, &st);
2128 else
2129#ifdef MS_WINDOWS
2130 if (path->wide) {
2131 if (follow_symlinks)
2132 result = win32_stat_w(path->wide, &st);
2133 else
2134 result = win32_lstat_w(path->wide, &st);
2135 }
2136 else
2137#endif
2138#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2139 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2140 result = LSTAT(path->narrow, &st);
2141 else
2142#endif
2143#ifdef HAVE_FSTATAT
2144 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2145 result = fstatat(dir_fd, path->narrow, &st,
2146 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2147 else
2148#endif
2149 result = STAT(path->narrow, &st);
2150 Py_END_ALLOW_THREADS
2151
Victor Stinner292c8352012-10-30 02:17:38 +01002152 if (result != 0) {
2153 return path_error(path);
2154 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002155
2156 return _pystat_fromstructstat(&st);
2157}
2158
Larry Hastings2f936352014-08-05 14:04:04 +10002159/*[python input]
2160
2161for s in """
2162
2163FACCESSAT
2164FCHMODAT
2165FCHOWNAT
2166FSTATAT
2167LINKAT
2168MKDIRAT
2169MKFIFOAT
2170MKNODAT
2171OPENAT
2172READLINKAT
2173SYMLINKAT
2174UNLINKAT
2175
2176""".strip().split():
2177 s = s.strip()
2178 print("""
2179#ifdef HAVE_{s}
2180 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002181#else
Larry Hastings2f936352014-08-05 14:04:04 +10002182 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002183#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002184""".rstrip().format(s=s))
2185
2186for s in """
2187
2188FCHDIR
2189FCHMOD
2190FCHOWN
2191FDOPENDIR
2192FEXECVE
2193FPATHCONF
2194FSTATVFS
2195FTRUNCATE
2196
2197""".strip().split():
2198 s = s.strip()
2199 print("""
2200#ifdef HAVE_{s}
2201 #define PATH_HAVE_{s} 1
2202#else
2203 #define PATH_HAVE_{s} 0
2204#endif
2205
2206""".rstrip().format(s=s))
2207[python start generated code]*/
2208
2209#ifdef HAVE_FACCESSAT
2210 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2211#else
2212 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2213#endif
2214
2215#ifdef HAVE_FCHMODAT
2216 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2217#else
2218 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2219#endif
2220
2221#ifdef HAVE_FCHOWNAT
2222 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2223#else
2224 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2225#endif
2226
2227#ifdef HAVE_FSTATAT
2228 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2229#else
2230 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2231#endif
2232
2233#ifdef HAVE_LINKAT
2234 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2235#else
2236 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2237#endif
2238
2239#ifdef HAVE_MKDIRAT
2240 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2241#else
2242 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2243#endif
2244
2245#ifdef HAVE_MKFIFOAT
2246 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_MKNODAT
2252 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_OPENAT
2258 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_READLINKAT
2264 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_SYMLINKAT
2270 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2271#else
2272 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2273#endif
2274
2275#ifdef HAVE_UNLINKAT
2276 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2277#else
2278 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2279#endif
2280
2281#ifdef HAVE_FCHDIR
2282 #define PATH_HAVE_FCHDIR 1
2283#else
2284 #define PATH_HAVE_FCHDIR 0
2285#endif
2286
2287#ifdef HAVE_FCHMOD
2288 #define PATH_HAVE_FCHMOD 1
2289#else
2290 #define PATH_HAVE_FCHMOD 0
2291#endif
2292
2293#ifdef HAVE_FCHOWN
2294 #define PATH_HAVE_FCHOWN 1
2295#else
2296 #define PATH_HAVE_FCHOWN 0
2297#endif
2298
2299#ifdef HAVE_FDOPENDIR
2300 #define PATH_HAVE_FDOPENDIR 1
2301#else
2302 #define PATH_HAVE_FDOPENDIR 0
2303#endif
2304
2305#ifdef HAVE_FEXECVE
2306 #define PATH_HAVE_FEXECVE 1
2307#else
2308 #define PATH_HAVE_FEXECVE 0
2309#endif
2310
2311#ifdef HAVE_FPATHCONF
2312 #define PATH_HAVE_FPATHCONF 1
2313#else
2314 #define PATH_HAVE_FPATHCONF 0
2315#endif
2316
2317#ifdef HAVE_FSTATVFS
2318 #define PATH_HAVE_FSTATVFS 1
2319#else
2320 #define PATH_HAVE_FSTATVFS 0
2321#endif
2322
2323#ifdef HAVE_FTRUNCATE
2324 #define PATH_HAVE_FTRUNCATE 1
2325#else
2326 #define PATH_HAVE_FTRUNCATE 0
2327#endif
2328/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002329
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002330#ifdef MS_WINDOWS
2331 #undef PATH_HAVE_FTRUNCATE
2332 #define PATH_HAVE_FTRUNCATE 1
2333#endif
Larry Hastings31826802013-10-19 00:09:25 -07002334
Larry Hastings61272b72014-01-07 12:41:53 -08002335/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002336
2337class path_t_converter(CConverter):
2338
2339 type = "path_t"
2340 impl_by_reference = True
2341 parse_by_reference = True
2342
2343 converter = 'path_converter'
2344
2345 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002346 # right now path_t doesn't support default values.
2347 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002348 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002349 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002350
Larry Hastings2f936352014-08-05 14:04:04 +10002351 if self.c_default not in (None, 'Py_None'):
2352 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002353
2354 self.nullable = nullable
2355 self.allow_fd = allow_fd
2356
Larry Hastings7726ac92014-01-31 22:03:12 -08002357 def pre_render(self):
2358 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002359 if isinstance(value, str):
2360 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002361 return str(int(bool(value)))
2362
2363 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002364 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002365 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002366 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002367 strify(self.nullable),
2368 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002369 )
2370
2371 def cleanup(self):
2372 return "path_cleanup(&" + self.name + ");\n"
2373
2374
2375class dir_fd_converter(CConverter):
2376 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002377
Larry Hastings2f936352014-08-05 14:04:04 +10002378 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002379 if self.default in (unspecified, None):
2380 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002381 if isinstance(requires, str):
2382 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2383 else:
2384 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002385
Larry Hastings2f936352014-08-05 14:04:04 +10002386class fildes_converter(CConverter):
2387 type = 'int'
2388 converter = 'fildes_converter'
2389
2390class uid_t_converter(CConverter):
2391 type = "uid_t"
2392 converter = '_Py_Uid_Converter'
2393
2394class gid_t_converter(CConverter):
2395 type = "gid_t"
2396 converter = '_Py_Gid_Converter'
2397
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002398class dev_t_converter(CConverter):
2399 type = 'dev_t'
2400 converter = '_Py_Dev_Converter'
2401
2402class dev_t_return_converter(unsigned_long_return_converter):
2403 type = 'dev_t'
2404 conversion_fn = '_PyLong_FromDev'
2405 unsigned_cast = '(dev_t)'
2406
Larry Hastings2f936352014-08-05 14:04:04 +10002407class FSConverter_converter(CConverter):
2408 type = 'PyObject *'
2409 converter = 'PyUnicode_FSConverter'
2410 def converter_init(self):
2411 if self.default is not unspecified:
2412 fail("FSConverter_converter does not support default values")
2413 self.c_default = 'NULL'
2414
2415 def cleanup(self):
2416 return "Py_XDECREF(" + self.name + ");\n"
2417
2418class pid_t_converter(CConverter):
2419 type = 'pid_t'
2420 format_unit = '" _Py_PARSE_PID "'
2421
2422class idtype_t_converter(int_converter):
2423 type = 'idtype_t'
2424
2425class id_t_converter(CConverter):
2426 type = 'id_t'
2427 format_unit = '" _Py_PARSE_PID "'
2428
2429class Py_intptr_t_converter(CConverter):
2430 type = 'Py_intptr_t'
2431 format_unit = '" _Py_PARSE_INTPTR "'
2432
2433class Py_off_t_converter(CConverter):
2434 type = 'Py_off_t'
2435 converter = 'Py_off_t_converter'
2436
2437class Py_off_t_return_converter(long_return_converter):
2438 type = 'Py_off_t'
2439 conversion_fn = 'PyLong_FromPy_off_t'
2440
2441class path_confname_converter(CConverter):
2442 type="int"
2443 converter="conv_path_confname"
2444
2445class confstr_confname_converter(path_confname_converter):
2446 converter='conv_confstr_confname'
2447
2448class sysconf_confname_converter(path_confname_converter):
2449 converter="conv_sysconf_confname"
2450
2451class sched_param_converter(CConverter):
2452 type = 'struct sched_param'
2453 converter = 'convert_sched_param'
2454 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002455
Larry Hastings61272b72014-01-07 12:41:53 -08002456[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002457/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002458
Larry Hastings61272b72014-01-07 12:41:53 -08002459/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002460
Larry Hastings2a727912014-01-16 11:32:01 -08002461os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002462
2463 path : path_t(allow_fd=True)
2464 Path to be examined; can be string, bytes, or open-file-descriptor int.
2465
2466 *
2467
Larry Hastings2f936352014-08-05 14:04:04 +10002468 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002469 If not None, it should be a file descriptor open to a directory,
2470 and path should be a relative string; path will then be relative to
2471 that directory.
2472
2473 follow_symlinks: bool = True
2474 If False, and the last element of the path is a symbolic link,
2475 stat will examine the symbolic link itself instead of the file
2476 the link points to.
2477
2478Perform a stat system call on the given path.
2479
2480dir_fd and follow_symlinks may not be implemented
2481 on your platform. If they are unavailable, using them will raise a
2482 NotImplementedError.
2483
2484It's an error to use dir_fd or follow_symlinks when specifying path as
2485 an open file descriptor.
2486
Larry Hastings61272b72014-01-07 12:41:53 -08002487[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002488
Larry Hastings31826802013-10-19 00:09:25 -07002489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002490os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2491/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002492{
2493 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2494}
2495
Larry Hastings2f936352014-08-05 14:04:04 +10002496
2497/*[clinic input]
2498os.lstat
2499
2500 path : path_t
2501
2502 *
2503
2504 dir_fd : dir_fd(requires='fstatat') = None
2505
2506Perform a stat system call on the given path, without following symbolic links.
2507
2508Like stat(), but do not follow symbolic links.
2509Equivalent to stat(path, follow_symlinks=False).
2510[clinic start generated code]*/
2511
Larry Hastings2f936352014-08-05 14:04:04 +10002512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002513os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2514/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002515{
2516 int follow_symlinks = 0;
2517 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2518}
Larry Hastings31826802013-10-19 00:09:25 -07002519
Larry Hastings2f936352014-08-05 14:04:04 +10002520
Larry Hastings61272b72014-01-07 12:41:53 -08002521/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002522os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002523
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002524 path: path_t
2525 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002526
2527 mode: int
2528 Operating-system mode bitfield. Can be F_OK to test existence,
2529 or the inclusive-OR of R_OK, W_OK, and X_OK.
2530
2531 *
2532
Larry Hastings2f936352014-08-05 14:04:04 +10002533 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002534 If not None, it should be a file descriptor open to a directory,
2535 and path should be relative; path will then be relative to that
2536 directory.
2537
2538 effective_ids: bool = False
2539 If True, access will use the effective uid/gid instead of
2540 the real uid/gid.
2541
2542 follow_symlinks: bool = True
2543 If False, and the last element of the path is a symbolic link,
2544 access will examine the symbolic link itself instead of the file
2545 the link points to.
2546
2547Use the real uid/gid to test for access to a path.
2548
2549{parameters}
2550dir_fd, effective_ids, and follow_symlinks may not be implemented
2551 on your platform. If they are unavailable, using them will raise a
2552 NotImplementedError.
2553
2554Note that most operations will use the effective uid/gid, therefore this
2555 routine can be used in a suid/sgid environment to test if the invoking user
2556 has the specified access to the path.
2557
Larry Hastings61272b72014-01-07 12:41:53 -08002558[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559
Larry Hastings2f936352014-08-05 14:04:04 +10002560static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002561os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002562 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002563/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002564{
Larry Hastings2f936352014-08-05 14:04:04 +10002565 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002566
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002567#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002568 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002569#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002571#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572
Larry Hastings9cf065c2012-06-22 16:30:09 -07002573#ifndef HAVE_FACCESSAT
2574 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002575 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576
2577 if (effective_ids) {
2578 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002579 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580 }
2581#endif
2582
2583#ifdef MS_WINDOWS
2584 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002585 if (path->wide != NULL)
2586 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002587 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002588 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589 Py_END_ALLOW_THREADS
2590
2591 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002592 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593 * * we didn't get a -1, and
2594 * * write access wasn't requested,
2595 * * or the file isn't read-only,
2596 * * or it's a directory.
2597 * (Directories cannot be read-only on Windows.)
2598 */
Larry Hastings2f936352014-08-05 14:04:04 +10002599 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002600 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002602 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603#else
2604
2605 Py_BEGIN_ALLOW_THREADS
2606#ifdef HAVE_FACCESSAT
2607 if ((dir_fd != DEFAULT_DIR_FD) ||
2608 effective_ids ||
2609 !follow_symlinks) {
2610 int flags = 0;
2611 if (!follow_symlinks)
2612 flags |= AT_SYMLINK_NOFOLLOW;
2613 if (effective_ids)
2614 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002615 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002616 }
2617 else
2618#endif
Larry Hastings31826802013-10-19 00:09:25 -07002619 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002621 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622#endif
2623
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002625}
2626
Guido van Rossumd371ff11999-01-25 16:12:23 +00002627#ifndef F_OK
2628#define F_OK 0
2629#endif
2630#ifndef R_OK
2631#define R_OK 4
2632#endif
2633#ifndef W_OK
2634#define W_OK 2
2635#endif
2636#ifndef X_OK
2637#define X_OK 1
2638#endif
2639
Larry Hastings31826802013-10-19 00:09:25 -07002640
Guido van Rossumd371ff11999-01-25 16:12:23 +00002641#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002642/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002643os.ttyname -> DecodeFSDefault
2644
2645 fd: int
2646 Integer file descriptor handle.
2647
2648 /
2649
2650Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002651[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002652
Larry Hastings31826802013-10-19 00:09:25 -07002653static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002654os_ttyname_impl(PyObject *module, int fd)
2655/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002656{
2657 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002658
Larry Hastings31826802013-10-19 00:09:25 -07002659 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002661 posix_error();
2662 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002663}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002664#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002666#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002667/*[clinic input]
2668os.ctermid
2669
2670Return the name of the controlling terminal for this process.
2671[clinic start generated code]*/
2672
Larry Hastings2f936352014-08-05 14:04:04 +10002673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002674os_ctermid_impl(PyObject *module)
2675/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002676{
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 char *ret;
2678 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679
Greg Wardb48bc172000-03-01 21:51:56 +00002680#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002682#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 if (ret == NULL)
2686 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002687 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002688}
Larry Hastings2f936352014-08-05 14:04:04 +10002689#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690
Larry Hastings2f936352014-08-05 14:04:04 +10002691
2692/*[clinic input]
2693os.chdir
2694
2695 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2696
2697Change the current working directory to the specified path.
2698
2699path may always be specified as a string.
2700On some platforms, path may also be specified as an open file descriptor.
2701 If this functionality is unavailable, using it raises an exception.
2702[clinic start generated code]*/
2703
Larry Hastings2f936352014-08-05 14:04:04 +10002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_chdir_impl(PyObject *module, path_t *path)
2706/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002707{
2708 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709
2710 Py_BEGIN_ALLOW_THREADS
2711#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002712 if (path->wide)
2713 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714 else
Larry Hastings2f936352014-08-05 14:04:04 +10002715 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002716 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717#else
2718#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002719 if (path->fd != -1)
2720 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721 else
2722#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002723 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724#endif
2725 Py_END_ALLOW_THREADS
2726
2727 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002728 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 }
2730
Larry Hastings2f936352014-08-05 14:04:04 +10002731 Py_RETURN_NONE;
2732}
2733
2734
2735#ifdef HAVE_FCHDIR
2736/*[clinic input]
2737os.fchdir
2738
2739 fd: fildes
2740
2741Change to the directory of the given file descriptor.
2742
2743fd must be opened on a directory, not a file.
2744Equivalent to os.chdir(fd).
2745
2746[clinic start generated code]*/
2747
Fred Drake4d1e64b2002-04-15 19:40:07 +00002748static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002749os_fchdir_impl(PyObject *module, int fd)
2750/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002751{
Larry Hastings2f936352014-08-05 14:04:04 +10002752 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002753}
2754#endif /* HAVE_FCHDIR */
2755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002756
Larry Hastings2f936352014-08-05 14:04:04 +10002757/*[clinic input]
2758os.chmod
2759
2760 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2761 Path to be modified. May always be specified as a str or bytes.
2762 On some platforms, path may also be specified as an open file descriptor.
2763 If this functionality is unavailable, using it raises an exception.
2764
2765 mode: int
2766 Operating-system mode bitfield.
2767
2768 *
2769
2770 dir_fd : dir_fd(requires='fchmodat') = None
2771 If not None, it should be a file descriptor open to a directory,
2772 and path should be relative; path will then be relative to that
2773 directory.
2774
2775 follow_symlinks: bool = True
2776 If False, and the last element of the path is a symbolic link,
2777 chmod will modify the symbolic link itself instead of the file
2778 the link points to.
2779
2780Change the access permissions of a file.
2781
2782It is an error to use dir_fd or follow_symlinks when specifying path as
2783 an open file descriptor.
2784dir_fd and follow_symlinks may not be implemented on your platform.
2785 If they are unavailable, using them will raise a NotImplementedError.
2786
2787[clinic start generated code]*/
2788
Larry Hastings2f936352014-08-05 14:04:04 +10002789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002790os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002791 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002792/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002793{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002796#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002799
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800#ifdef HAVE_FCHMODAT
2801 int fchmodat_nofollow_unsupported = 0;
2802#endif
2803
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2805 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002806 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807#endif
2808
2809#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002811 if (path->wide)
2812 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 else
Larry Hastings2f936352014-08-05 14:04:04 +10002814 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002815 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 result = 0;
2817 else {
2818 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002819 attr &= ~FILE_ATTRIBUTE_READONLY;
2820 else
2821 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002822 if (path->wide)
2823 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 else
Larry Hastings2f936352014-08-05 14:04:04 +10002825 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 }
2827 Py_END_ALLOW_THREADS
2828
2829 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002830 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 }
2832#else /* MS_WINDOWS */
2833 Py_BEGIN_ALLOW_THREADS
2834#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002835 if (path->fd != -1)
2836 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 else
2838#endif
2839#ifdef HAVE_LCHMOD
2840 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002841 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842 else
2843#endif
2844#ifdef HAVE_FCHMODAT
2845 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2846 /*
2847 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2848 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002849 * and then says it isn't implemented yet.
2850 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 *
2852 * Once it is supported, os.chmod will automatically
2853 * support dir_fd and follow_symlinks=False. (Hopefully.)
2854 * Until then, we need to be careful what exception we raise.
2855 */
Larry Hastings2f936352014-08-05 14:04:04 +10002856 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2858 /*
2859 * But wait! We can't throw the exception without allowing threads,
2860 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2861 */
2862 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002863 result &&
2864 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2865 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 }
2867 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002868#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002869 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870 Py_END_ALLOW_THREADS
2871
2872 if (result) {
2873#ifdef HAVE_FCHMODAT
2874 if (fchmodat_nofollow_unsupported) {
2875 if (dir_fd != DEFAULT_DIR_FD)
2876 dir_fd_and_follow_symlinks_invalid("chmod",
2877 dir_fd, follow_symlinks);
2878 else
2879 follow_symlinks_specified("chmod", follow_symlinks);
2880 }
2881 else
2882#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002883 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884 }
2885#endif
2886
Larry Hastings2f936352014-08-05 14:04:04 +10002887 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002888}
2889
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890
Christian Heimes4e30a842007-11-30 22:12:06 +00002891#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002892/*[clinic input]
2893os.fchmod
2894
2895 fd: int
2896 mode: int
2897
2898Change the access permissions of the file given by file descriptor fd.
2899
2900Equivalent to os.chmod(fd, mode).
2901[clinic start generated code]*/
2902
Larry Hastings2f936352014-08-05 14:04:04 +10002903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002904os_fchmod_impl(PyObject *module, int fd, int mode)
2905/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002906{
2907 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002908 int async_err = 0;
2909
2910 do {
2911 Py_BEGIN_ALLOW_THREADS
2912 res = fchmod(fd, mode);
2913 Py_END_ALLOW_THREADS
2914 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2915 if (res != 0)
2916 return (!async_err) ? posix_error() : NULL;
2917
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002919}
2920#endif /* HAVE_FCHMOD */
2921
Larry Hastings2f936352014-08-05 14:04:04 +10002922
Christian Heimes4e30a842007-11-30 22:12:06 +00002923#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002924/*[clinic input]
2925os.lchmod
2926
2927 path: path_t
2928 mode: int
2929
2930Change the access permissions of a file, without following symbolic links.
2931
2932If path is a symlink, this affects the link itself rather than the target.
2933Equivalent to chmod(path, mode, follow_symlinks=False)."
2934[clinic start generated code]*/
2935
Larry Hastings2f936352014-08-05 14:04:04 +10002936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937os_lchmod_impl(PyObject *module, path_t *path, int mode)
2938/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002939{
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002942 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002944 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002945 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002946 return NULL;
2947 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002949}
2950#endif /* HAVE_LCHMOD */
2951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
Thomas Wouterscf297e42007-02-23 15:07:44 +00002953#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002954/*[clinic input]
2955os.chflags
2956
2957 path: path_t
2958 flags: unsigned_long(bitwise=True)
2959 follow_symlinks: bool=True
2960
2961Set file flags.
2962
2963If follow_symlinks is False, and the last element of the path is a symbolic
2964 link, chflags will change flags on the symbolic link itself instead of the
2965 file the link points to.
2966follow_symlinks may not be implemented on your platform. If it is
2967unavailable, using it will raise a NotImplementedError.
2968
2969[clinic start generated code]*/
2970
Larry Hastings2f936352014-08-05 14:04:04 +10002971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002972os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002973 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002974/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002975{
2976 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977
2978#ifndef HAVE_LCHFLAGS
2979 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002980 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002981#endif
2982
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984#ifdef HAVE_LCHFLAGS
2985 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002986 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987 else
2988#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002989 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002990 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002991
Larry Hastings2f936352014-08-05 14:04:04 +10002992 if (result)
2993 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
Larry Hastings2f936352014-08-05 14:04:04 +10002995 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002996}
2997#endif /* HAVE_CHFLAGS */
2998
Larry Hastings2f936352014-08-05 14:04:04 +10002999
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003001/*[clinic input]
3002os.lchflags
3003
3004 path: path_t
3005 flags: unsigned_long(bitwise=True)
3006
3007Set file flags.
3008
3009This function will not follow symbolic links.
3010Equivalent to chflags(path, flags, follow_symlinks=False).
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3015/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003019 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003021 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003022 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003023 }
Victor Stinner292c8352012-10-30 02:17:38 +01003024 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003025}
3026#endif /* HAVE_LCHFLAGS */
3027
Larry Hastings2f936352014-08-05 14:04:04 +10003028
Martin v. Löwis244edc82001-10-04 22:44:26 +00003029#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003030/*[clinic input]
3031os.chroot
3032 path: path_t
3033
3034Change root directory to path.
3035
3036[clinic start generated code]*/
3037
Larry Hastings2f936352014-08-05 14:04:04 +10003038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003039os_chroot_impl(PyObject *module, path_t *path)
3040/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003041{
3042 int res;
3043 Py_BEGIN_ALLOW_THREADS
3044 res = chroot(path->narrow);
3045 Py_END_ALLOW_THREADS
3046 if (res < 0)
3047 return path_error(path);
3048 Py_RETURN_NONE;
3049}
3050#endif /* HAVE_CHROOT */
3051
Martin v. Löwis244edc82001-10-04 22:44:26 +00003052
Guido van Rossum21142a01999-01-08 21:05:37 +00003053#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003054/*[clinic input]
3055os.fsync
3056
3057 fd: fildes
3058
3059Force write of fd to disk.
3060[clinic start generated code]*/
3061
Larry Hastings2f936352014-08-05 14:04:04 +10003062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003063os_fsync_impl(PyObject *module, int fd)
3064/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003065{
3066 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003067}
3068#endif /* HAVE_FSYNC */
3069
Larry Hastings2f936352014-08-05 14:04:04 +10003070
Ross Lagerwall7807c352011-03-17 20:20:30 +02003071#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003072/*[clinic input]
3073os.sync
3074
3075Force write of everything to disk.
3076[clinic start generated code]*/
3077
Larry Hastings2f936352014-08-05 14:04:04 +10003078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003079os_sync_impl(PyObject *module)
3080/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003081{
3082 Py_BEGIN_ALLOW_THREADS
3083 sync();
3084 Py_END_ALLOW_THREADS
3085 Py_RETURN_NONE;
3086}
Larry Hastings2f936352014-08-05 14:04:04 +10003087#endif /* HAVE_SYNC */
3088
Ross Lagerwall7807c352011-03-17 20:20:30 +02003089
Guido van Rossum21142a01999-01-08 21:05:37 +00003090#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003091#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003092extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3093#endif
3094
Larry Hastings2f936352014-08-05 14:04:04 +10003095/*[clinic input]
3096os.fdatasync
3097
3098 fd: fildes
3099
3100Force write of fd to disk without forcing update of metadata.
3101[clinic start generated code]*/
3102
Larry Hastings2f936352014-08-05 14:04:04 +10003103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003104os_fdatasync_impl(PyObject *module, int fd)
3105/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003106{
3107 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003108}
3109#endif /* HAVE_FDATASYNC */
3110
3111
Fredrik Lundh10723342000-07-10 16:38:09 +00003112#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003113/*[clinic input]
3114os.chown
3115
3116 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3117 Path to be examined; can be string, bytes, or open-file-descriptor int.
3118
3119 uid: uid_t
3120
3121 gid: gid_t
3122
3123 *
3124
3125 dir_fd : dir_fd(requires='fchownat') = None
3126 If not None, it should be a file descriptor open to a directory,
3127 and path should be relative; path will then be relative to that
3128 directory.
3129
3130 follow_symlinks: bool = True
3131 If False, and the last element of the path is a symbolic link,
3132 stat will examine the symbolic link itself instead of the file
3133 the link points to.
3134
3135Change the owner and group id of path to the numeric uid and gid.\
3136
3137path may always be specified as a string.
3138On some platforms, path may also be specified as an open file descriptor.
3139 If this functionality is unavailable, using it raises an exception.
3140If dir_fd is not None, it should be a file descriptor open to a directory,
3141 and path should be relative; path will then be relative to that directory.
3142If follow_symlinks is False, and the last element of the path is a symbolic
3143 link, chown will modify the symbolic link itself instead of the file the
3144 link points to.
3145It is an error to use dir_fd or follow_symlinks when specifying path as
3146 an open file descriptor.
3147dir_fd and follow_symlinks may not be implemented on your platform.
3148 If they are unavailable, using them will raise a NotImplementedError.
3149
3150[clinic start generated code]*/
3151
Larry Hastings2f936352014-08-05 14:04:04 +10003152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003154 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003155/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003156{
3157 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003158
3159#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3160 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003161 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003163 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3164 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3165 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166
3167#ifdef __APPLE__
3168 /*
3169 * This is for Mac OS X 10.3, which doesn't have lchown.
3170 * (But we still have an lchown symbol because of weak-linking.)
3171 * It doesn't have fchownat either. So there's no possibility
3172 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003173 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 if ((!follow_symlinks) && (lchown == NULL)) {
3175 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003176 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177 }
3178#endif
3179
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003182 if (path->fd != -1)
3183 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184 else
3185#endif
3186#ifdef HAVE_LCHOWN
3187 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003188 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189 else
3190#endif
3191#ifdef HAVE_FCHOWNAT
3192 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003193 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3195 else
3196#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003197 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199
Larry Hastings2f936352014-08-05 14:04:04 +10003200 if (result)
3201 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202
Larry Hastings2f936352014-08-05 14:04:04 +10003203 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003205#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003206
Larry Hastings2f936352014-08-05 14:04:04 +10003207
Christian Heimes4e30a842007-11-30 22:12:06 +00003208#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003209/*[clinic input]
3210os.fchown
3211
3212 fd: int
3213 uid: uid_t
3214 gid: gid_t
3215
3216Change the owner and group id of the file specified by file descriptor.
3217
3218Equivalent to os.chown(fd, uid, gid).
3219
3220[clinic start generated code]*/
3221
Larry Hastings2f936352014-08-05 14:04:04 +10003222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003223os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3224/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003225{
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003227 int async_err = 0;
3228
3229 do {
3230 Py_BEGIN_ALLOW_THREADS
3231 res = fchown(fd, uid, gid);
3232 Py_END_ALLOW_THREADS
3233 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3234 if (res != 0)
3235 return (!async_err) ? posix_error() : NULL;
3236
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003238}
3239#endif /* HAVE_FCHOWN */
3240
Larry Hastings2f936352014-08-05 14:04:04 +10003241
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003242#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003243/*[clinic input]
3244os.lchown
3245
3246 path : path_t
3247 uid: uid_t
3248 gid: gid_t
3249
3250Change the owner and group id of path to the numeric uid and gid.
3251
3252This function will not follow symbolic links.
3253Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3254[clinic start generated code]*/
3255
Larry Hastings2f936352014-08-05 14:04:04 +10003256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003257os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3258/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003259{
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003262 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003264 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003265 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003266 }
Larry Hastings2f936352014-08-05 14:04:04 +10003267 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003268}
3269#endif /* HAVE_LCHOWN */
3270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003271
Barry Warsaw53699e91996-12-10 23:23:01 +00003272static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003273posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003274{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003275 char *buf, *tmpbuf;
3276 char *cwd;
3277 const size_t chunk = 1024;
3278 size_t buflen = 0;
3279 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003280
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003281#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003283 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 wchar_t *wbuf2 = wbuf;
3285 PyObject *resobj;
3286 DWORD len;
3287 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003288 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 /* If the buffer is large enough, len does not include the
3290 terminating \0. If the buffer is too small, len includes
3291 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003292 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003293 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 if (wbuf2)
3295 len = GetCurrentDirectoryW(len, wbuf2);
3296 }
3297 Py_END_ALLOW_THREADS
3298 if (!wbuf2) {
3299 PyErr_NoMemory();
3300 return NULL;
3301 }
3302 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003304 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003305 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 }
3307 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003308 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003309 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 return resobj;
3311 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003312
3313 if (win32_warn_bytes_api())
3314 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003315#endif
3316
Victor Stinner4403d7d2015-04-25 00:16:10 +02003317 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003319 do {
3320 buflen += chunk;
3321 tmpbuf = PyMem_RawRealloc(buf, buflen);
3322 if (tmpbuf == NULL)
3323 break;
3324
3325 buf = tmpbuf;
3326 cwd = getcwd(buf, buflen);
3327 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003329
3330 if (cwd == NULL) {
3331 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003333 }
3334
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3337 else
3338 obj = PyUnicode_DecodeFSDefault(buf);
3339 PyMem_RawFree(buf);
3340
3341 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003342}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003343
Larry Hastings2f936352014-08-05 14:04:04 +10003344
3345/*[clinic input]
3346os.getcwd
3347
3348Return a unicode string representing the current working directory.
3349[clinic start generated code]*/
3350
Larry Hastings2f936352014-08-05 14:04:04 +10003351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003352os_getcwd_impl(PyObject *module)
3353/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003354{
3355 return posix_getcwd(0);
3356}
3357
Larry Hastings2f936352014-08-05 14:04:04 +10003358
3359/*[clinic input]
3360os.getcwdb
3361
3362Return a bytes string representing the current working directory.
3363[clinic start generated code]*/
3364
Larry Hastings2f936352014-08-05 14:04:04 +10003365static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003366os_getcwdb_impl(PyObject *module)
3367/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003368{
3369 return posix_getcwd(1);
3370}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003371
Larry Hastings2f936352014-08-05 14:04:04 +10003372
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3374#define HAVE_LINK 1
3375#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003376
Guido van Rossumb6775db1994-08-01 11:34:53 +00003377#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003378/*[clinic input]
3379
3380os.link
3381
3382 src : path_t
3383 dst : path_t
3384 *
3385 src_dir_fd : dir_fd = None
3386 dst_dir_fd : dir_fd = None
3387 follow_symlinks: bool = True
3388
3389Create a hard link to a file.
3390
3391If either src_dir_fd or dst_dir_fd is not None, it should be a file
3392 descriptor open to a directory, and the respective path string (src or dst)
3393 should be relative; the path will then be relative to that directory.
3394If follow_symlinks is False, and the last element of src is a symbolic
3395 link, link will create a link to the symbolic link itself instead of the
3396 file the link points to.
3397src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3398 platform. If they are unavailable, using them will raise a
3399 NotImplementedError.
3400[clinic start generated code]*/
3401
Larry Hastings2f936352014-08-05 14:04:04 +10003402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003403os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003404 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003405/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003406{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407#ifdef MS_WINDOWS
3408 BOOL result;
3409#else
3410 int result;
3411#endif
3412
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413#ifndef HAVE_LINKAT
3414 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3415 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003416 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417 }
3418#endif
3419
Larry Hastings2f936352014-08-05 14:04:04 +10003420 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421 PyErr_SetString(PyExc_NotImplementedError,
3422 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003423 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003425
Brian Curtin1b9df392010-11-24 20:24:31 +00003426#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003428 if (src->wide)
3429 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 else
Larry Hastings2f936352014-08-05 14:04:04 +10003431 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (!result)
3435 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436#else
3437 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003438#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3440 (dst_dir_fd != DEFAULT_DIR_FD) ||
3441 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003442 result = linkat(src_dir_fd, src->narrow,
3443 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3445 else
3446#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003447 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003449
Larry Hastings2f936352014-08-05 14:04:04 +10003450 if (result)
3451 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452#endif
3453
Larry Hastings2f936352014-08-05 14:04:04 +10003454 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003455}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456#endif
3457
Brian Curtin1b9df392010-11-24 20:24:31 +00003458
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003459#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003460static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003461_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 PyObject *v;
3464 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3465 BOOL result;
3466 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003467 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003468 char *bufptr = namebuf;
3469 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003470 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 PyObject *po = NULL;
3472 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003477
Gregory P. Smith40a21602013-03-20 20:52:50 -07003478 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003479 po_wchars = L".";
3480 len = 1;
3481 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003482 po_wchars = path->wide;
3483 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003484 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003486 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 if (!wnamebuf) {
3488 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003491 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003493 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003494 if (wch != SEP && wch != ALTSEP && wch != L':')
3495 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 wcscpy(wnamebuf + len, L"*.*");
3497 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 if ((list = PyList_New(0)) == NULL) {
3499 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003501 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003503 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 if (hFindFile == INVALID_HANDLE_VALUE) {
3505 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if (error == ERROR_FILE_NOT_FOUND)
3507 goto exit;
3508 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
3512 do {
3513 /* Skip over . and .. */
3514 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3515 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 v = PyUnicode_FromWideChar(wFileData.cFileName,
3517 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_DECREF(list);
3520 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 break;
3522 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 break;
3528 }
3529 Py_DECREF(v);
3530 }
3531 Py_BEGIN_ALLOW_THREADS
3532 result = FindNextFileW(hFindFile, &wFileData);
3533 Py_END_ALLOW_THREADS
3534 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3535 it got to the end of the directory. */
3536 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003538 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 }
3541 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003542
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545 strcpy(namebuf, path->narrow);
3546 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 if (len > 0) {
3548 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003549 if (ch != '\\' && ch != '/' && ch != ':')
3550 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 strcpy(namebuf + len, "*.*");
3552 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003556
Antoine Pitroub73caab2010-08-09 23:39:31 +00003557 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003559 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 if (hFindFile == INVALID_HANDLE_VALUE) {
3561 int error = GetLastError();
3562 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 goto exit;
3564 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003565 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 }
3568 do {
3569 /* Skip over . and .. */
3570 if (strcmp(FileData.cFileName, ".") != 0 &&
3571 strcmp(FileData.cFileName, "..") != 0) {
3572 v = PyBytes_FromString(FileData.cFileName);
3573 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 Py_DECREF(list);
3575 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 break;
3577 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 Py_DECREF(list);
3581 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 break;
3583 }
3584 Py_DECREF(v);
3585 }
3586 Py_BEGIN_ALLOW_THREADS
3587 result = FindNextFile(hFindFile, &FileData);
3588 Py_END_ALLOW_THREADS
3589 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3590 it got to the end of the directory. */
3591 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 }
3596 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003597
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598exit:
3599 if (hFindFile != INVALID_HANDLE_VALUE) {
3600 if (FindClose(hFindFile) == FALSE) {
3601 if (list != NULL) {
3602 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 }
3605 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003607 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003608
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003610} /* end of _listdir_windows_no_opendir */
3611
3612#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3613
3614static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003615_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003616{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003617 PyObject *v;
3618 DIR *dirp = NULL;
3619 struct dirent *ep;
3620 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003621#ifdef HAVE_FDOPENDIR
3622 int fd = -1;
3623#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003624
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003627 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003629 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003630 if (fd == -1)
3631 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632
Larry Hastingsfdaea062012-06-25 04:42:23 -07003633 return_str = 1;
3634
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 Py_BEGIN_ALLOW_THREADS
3636 dirp = fdopendir(fd);
3637 Py_END_ALLOW_THREADS
3638 }
3639 else
3640#endif
3641 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003642 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003643 if (path->narrow) {
3644 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003645 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003646 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003647 }
3648 else {
3649 name = ".";
3650 return_str = 1;
3651 }
3652
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 Py_BEGIN_ALLOW_THREADS
3654 dirp = opendir(name);
3655 Py_END_ALLOW_THREADS
3656 }
3657
3658 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003659 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003660#ifdef HAVE_FDOPENDIR
3661 if (fd != -1) {
3662 Py_BEGIN_ALLOW_THREADS
3663 close(fd);
3664 Py_END_ALLOW_THREADS
3665 }
3666#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 goto exit;
3668 }
3669 if ((list = PyList_New(0)) == NULL) {
3670 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 }
3672 for (;;) {
3673 errno = 0;
3674 Py_BEGIN_ALLOW_THREADS
3675 ep = readdir(dirp);
3676 Py_END_ALLOW_THREADS
3677 if (ep == NULL) {
3678 if (errno == 0) {
3679 break;
3680 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003682 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
3685 }
3686 if (ep->d_name[0] == '.' &&
3687 (NAMLEN(ep) == 1 ||
3688 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3689 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003690 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003691 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3692 else
3693 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003700 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 break;
3702 }
3703 Py_DECREF(v);
3704 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003705
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706exit:
3707 if (dirp != NULL) {
3708 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003709#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 if (fd > -1)
3711 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003712#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 closedir(dirp);
3714 Py_END_ALLOW_THREADS
3715 }
3716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003718} /* end of _posix_listdir */
3719#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003720
Larry Hastings2f936352014-08-05 14:04:04 +10003721
3722/*[clinic input]
3723os.listdir
3724
3725 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3726
3727Return a list containing the names of the files in the directory.
3728
3729path can be specified as either str or bytes. If path is bytes,
3730 the filenames returned will also be bytes; in all other circumstances
3731 the filenames returned will be str.
3732If path is None, uses the path='.'.
3733On some platforms, path may also be specified as an open file descriptor;\
3734 the file descriptor must refer to a directory.
3735 If this functionality is unavailable, using it raises NotImplementedError.
3736
3737The list is in arbitrary order. It does not include the special
3738entries '.' and '..' even if they are present in the directory.
3739
3740
3741[clinic start generated code]*/
3742
Larry Hastings2f936352014-08-05 14:04:04 +10003743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003744os_listdir_impl(PyObject *module, path_t *path)
3745/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003746{
3747#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3748 return _listdir_windows_no_opendir(path, NULL);
3749#else
3750 return _posix_listdir(path, NULL);
3751#endif
3752}
3753
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003754#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003755/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003756/*[clinic input]
3757os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003758
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003759 path: path_t
3760 /
3761
3762[clinic start generated code]*/
3763
3764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003765os__getfullpathname_impl(PyObject *module, path_t *path)
3766/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003767{
3768 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769 {
Victor Stinner75875072013-11-24 19:23:25 +01003770 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003771 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 DWORD result;
3773 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003775 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003776 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003778 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003779 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 if (!woutbufp)
3781 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003782 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 }
3784 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003785 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003789 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 return v;
3791 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003792 else {
3793 char outbuf[MAX_PATH];
3794 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003795
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003796 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3797 outbuf, &temp)) {
3798 win32_error_object("GetFullPathName", path->object);
3799 return NULL;
3800 }
3801 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 }
Larry Hastings2f936352014-08-05 14:04:04 +10003803}
Brian Curtind40e6f72010-07-08 21:39:08 +00003804
Brian Curtind25aef52011-06-13 15:16:04 -05003805
Larry Hastings2f936352014-08-05 14:04:04 +10003806/*[clinic input]
3807os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003808
Larry Hastings2f936352014-08-05 14:04:04 +10003809 path: unicode
3810 /
3811
3812A helper function for samepath on windows.
3813[clinic start generated code]*/
3814
Larry Hastings2f936352014-08-05 14:04:04 +10003815static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003816os__getfinalpathname_impl(PyObject *module, PyObject *path)
3817/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003818{
3819 HANDLE hFile;
3820 int buf_size;
3821 wchar_t *target_path;
3822 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003823 PyObject *result;
3824 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003825
Larry Hastings2f936352014-08-05 14:04:04 +10003826 path_wchar = PyUnicode_AsUnicode(path);
3827 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003828 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003829
Brian Curtind40e6f72010-07-08 21:39:08 +00003830 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003831 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003832 0, /* desired access */
3833 0, /* share mode */
3834 NULL, /* security attributes */
3835 OPEN_EXISTING,
3836 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3837 FILE_FLAG_BACKUP_SEMANTICS,
3838 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003839
Victor Stinnereb5657a2011-09-30 01:44:27 +02003840 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003841 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003842
3843 /* We have a good handle to the target, use it to determine the
3844 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003845 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003846
3847 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003848 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003849
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003850 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003851 if(!target_path)
3852 return PyErr_NoMemory();
3853
Steve Dower2ea51c92015-03-20 21:49:12 -07003854 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3855 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003857 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003858
3859 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003860 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003861
3862 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003863 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003864 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003865 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003866}
Brian Curtin62857742010-09-06 17:07:27 +00003867
Brian Curtin95d028f2011-06-09 09:10:38 -05003868PyDoc_STRVAR(posix__isdir__doc__,
3869"Return true if the pathname refers to an existing directory.");
3870
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003871/*[clinic input]
3872os._isdir
3873
3874 path: path_t
3875 /
3876
3877[clinic start generated code]*/
3878
Brian Curtin9c669cc2011-06-08 18:17:18 -05003879static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003880os__isdir_impl(PyObject *module, path_t *path)
3881/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003882{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003883 DWORD attributes;
3884
Steve Dowerb22a6772016-07-17 20:49:38 -07003885 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003886 if (!path->narrow)
3887 attributes = GetFileAttributesW(path->wide);
3888 else
3889 attributes = GetFileAttributesA(path->narrow);
Steve Dowerb22a6772016-07-17 20:49:38 -07003890 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003891
Brian Curtin9c669cc2011-06-08 18:17:18 -05003892 if (attributes == INVALID_FILE_ATTRIBUTES)
3893 Py_RETURN_FALSE;
3894
Brian Curtin9c669cc2011-06-08 18:17:18 -05003895 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3896 Py_RETURN_TRUE;
3897 else
3898 Py_RETURN_FALSE;
3899}
Tim Golden6b528062013-08-01 12:44:00 +01003900
Tim Golden6b528062013-08-01 12:44:00 +01003901
Larry Hastings2f936352014-08-05 14:04:04 +10003902/*[clinic input]
3903os._getvolumepathname
3904
3905 path: unicode
3906
3907A helper function for ismount on Win32.
3908[clinic start generated code]*/
3909
Larry Hastings2f936352014-08-05 14:04:04 +10003910static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003911os__getvolumepathname_impl(PyObject *module, PyObject *path)
3912/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003913{
3914 PyObject *result;
3915 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003916 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003917 BOOL ret;
3918
Larry Hastings2f936352014-08-05 14:04:04 +10003919 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3920 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003921 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003922 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003923
3924 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003925 buflen = Py_MAX(buflen, MAX_PATH);
3926
3927 if (buflen > DWORD_MAX) {
3928 PyErr_SetString(PyExc_OverflowError, "path too long");
3929 return NULL;
3930 }
3931
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003932 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003933 if (mountpath == NULL)
3934 return PyErr_NoMemory();
3935
3936 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003937 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003938 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003939 Py_END_ALLOW_THREADS
3940
3941 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003942 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003943 goto exit;
3944 }
3945 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3946
3947exit:
3948 PyMem_Free(mountpath);
3949 return result;
3950}
Tim Golden6b528062013-08-01 12:44:00 +01003951
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003952#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003953
Larry Hastings2f936352014-08-05 14:04:04 +10003954
3955/*[clinic input]
3956os.mkdir
3957
3958 path : path_t
3959
3960 mode: int = 0o777
3961
3962 *
3963
3964 dir_fd : dir_fd(requires='mkdirat') = None
3965
3966# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3967
3968Create a directory.
3969
3970If dir_fd is not None, it should be a file descriptor open to a directory,
3971 and path should be relative; path will then be relative to that directory.
3972dir_fd may not be implemented on your platform.
3973 If it is unavailable, using it will raise a NotImplementedError.
3974
3975The mode argument is ignored on Windows.
3976[clinic start generated code]*/
3977
Larry Hastings2f936352014-08-05 14:04:04 +10003978static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003979os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3980/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003981{
3982 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003983
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003984#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003985 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003986 if (path->wide)
3987 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003988 else
Larry Hastings2f936352014-08-05 14:04:04 +10003989 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003990 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003991
Larry Hastings2f936352014-08-05 14:04:04 +10003992 if (!result)
3993 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003995 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996#if HAVE_MKDIRAT
3997 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003998 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003999 else
4000#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004001#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004002 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004003#else
Larry Hastings2f936352014-08-05 14:04:04 +10004004 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004005#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004006 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004007 if (result < 0)
4008 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004009#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004010 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004011}
4012
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004013
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004014/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4015#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004016#include <sys/resource.h>
4017#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004018
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004019
4020#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004021/*[clinic input]
4022os.nice
4023
4024 increment: int
4025 /
4026
4027Add increment to the priority of process and return the new priority.
4028[clinic start generated code]*/
4029
Larry Hastings2f936352014-08-05 14:04:04 +10004030static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004031os_nice_impl(PyObject *module, int increment)
4032/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004033{
4034 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004035
Victor Stinner8c62be82010-05-06 00:08:46 +00004036 /* There are two flavours of 'nice': one that returns the new
4037 priority (as required by almost all standards out there) and the
4038 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4039 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004040
Victor Stinner8c62be82010-05-06 00:08:46 +00004041 If we are of the nice family that returns the new priority, we
4042 need to clear errno before the call, and check if errno is filled
4043 before calling posix_error() on a returnvalue of -1, because the
4044 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004045
Victor Stinner8c62be82010-05-06 00:08:46 +00004046 errno = 0;
4047 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004048#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004049 if (value == 0)
4050 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004051#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004052 if (value == -1 && errno != 0)
4053 /* either nice() or getpriority() returned an error */
4054 return posix_error();
4055 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004056}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004057#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004058
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004059
4060#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004061/*[clinic input]
4062os.getpriority
4063
4064 which: int
4065 who: int
4066
4067Return program scheduling priority.
4068[clinic start generated code]*/
4069
Larry Hastings2f936352014-08-05 14:04:04 +10004070static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004071os_getpriority_impl(PyObject *module, int which, int who)
4072/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004073{
4074 int retval;
4075
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004076 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004077 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004078 if (errno != 0)
4079 return posix_error();
4080 return PyLong_FromLong((long)retval);
4081}
4082#endif /* HAVE_GETPRIORITY */
4083
4084
4085#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004086/*[clinic input]
4087os.setpriority
4088
4089 which: int
4090 who: int
4091 priority: int
4092
4093Set program scheduling priority.
4094[clinic start generated code]*/
4095
Larry Hastings2f936352014-08-05 14:04:04 +10004096static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004097os_setpriority_impl(PyObject *module, int which, int who, int priority)
4098/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004099{
4100 int retval;
4101
4102 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004103 if (retval == -1)
4104 return posix_error();
4105 Py_RETURN_NONE;
4106}
4107#endif /* HAVE_SETPRIORITY */
4108
4109
Barry Warsaw53699e91996-12-10 23:23:01 +00004110static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004111internal_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 +00004112{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004114 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004116#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004117 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004118 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004119#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004121#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4124 (dst_dir_fd != DEFAULT_DIR_FD);
4125#ifndef HAVE_RENAMEAT
4126 if (dir_fd_specified) {
4127 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004128 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 }
4130#endif
4131
Larry Hastings2f936352014-08-05 14:04:04 +10004132 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133 PyErr_Format(PyExc_ValueError,
4134 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004135 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004136 }
4137
4138#ifdef MS_WINDOWS
4139 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004140 if (src->wide)
4141 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004142 else
Larry Hastings2f936352014-08-05 14:04:04 +10004143 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144 Py_END_ALLOW_THREADS
4145
Larry Hastings2f936352014-08-05 14:04:04 +10004146 if (!result)
4147 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148
4149#else
4150 Py_BEGIN_ALLOW_THREADS
4151#ifdef HAVE_RENAMEAT
4152 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004153 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154 else
4155#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004156 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004157 Py_END_ALLOW_THREADS
4158
Larry Hastings2f936352014-08-05 14:04:04 +10004159 if (result)
4160 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004161#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004162 Py_RETURN_NONE;
4163}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004164
Larry Hastings2f936352014-08-05 14:04:04 +10004165
4166/*[clinic input]
4167os.rename
4168
4169 src : path_t
4170 dst : path_t
4171 *
4172 src_dir_fd : dir_fd = None
4173 dst_dir_fd : dir_fd = None
4174
4175Rename a file or directory.
4176
4177If either src_dir_fd or dst_dir_fd is not None, it should be a file
4178 descriptor open to a directory, and the respective path string (src or dst)
4179 should be relative; the path will then be relative to that directory.
4180src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4181 If they are unavailable, using them will raise a NotImplementedError.
4182[clinic start generated code]*/
4183
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004184static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004185os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004186 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004187/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004188{
Larry Hastings2f936352014-08-05 14:04:04 +10004189 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004190}
4191
Larry Hastings2f936352014-08-05 14:04:04 +10004192
4193/*[clinic input]
4194os.replace = os.rename
4195
4196Rename a file or directory, overwriting the destination.
4197
4198If either src_dir_fd or dst_dir_fd is not None, it should be a file
4199 descriptor open to a directory, and the respective path string (src or dst)
4200 should be relative; the path will then be relative to that directory.
4201src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4202 If they are unavailable, using them will raise a NotImplementedError."
4203[clinic start generated code]*/
4204
Larry Hastings2f936352014-08-05 14:04:04 +10004205static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004206os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4207 int dst_dir_fd)
4208/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004209{
4210 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4211}
4212
4213
4214/*[clinic input]
4215os.rmdir
4216
4217 path: path_t
4218 *
4219 dir_fd: dir_fd(requires='unlinkat') = None
4220
4221Remove a directory.
4222
4223If dir_fd is not None, it should be a file descriptor open to a directory,
4224 and path should be relative; path will then be relative to that directory.
4225dir_fd may not be implemented on your platform.
4226 If it is unavailable, using it will raise a NotImplementedError.
4227[clinic start generated code]*/
4228
Larry Hastings2f936352014-08-05 14:04:04 +10004229static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004230os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4231/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004232{
4233 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004234
4235 Py_BEGIN_ALLOW_THREADS
4236#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004237 if (path->wide)
4238 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004239 else
Larry Hastings2f936352014-08-05 14:04:04 +10004240 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004241 result = !result; /* Windows, success=1, UNIX, success=0 */
4242#else
4243#ifdef HAVE_UNLINKAT
4244 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004245 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004246 else
4247#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004248 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249#endif
4250 Py_END_ALLOW_THREADS
4251
Larry Hastings2f936352014-08-05 14:04:04 +10004252 if (result)
4253 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004254
Larry Hastings2f936352014-08-05 14:04:04 +10004255 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004256}
4257
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004258
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004259#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004260#ifdef MS_WINDOWS
4261/*[clinic input]
4262os.system -> long
4263
4264 command: Py_UNICODE
4265
4266Execute the command in a subshell.
4267[clinic start generated code]*/
4268
Larry Hastings2f936352014-08-05 14:04:04 +10004269static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004270os_system_impl(PyObject *module, Py_UNICODE *command)
4271/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004272{
4273 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004275 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004276 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004277 return result;
4278}
4279#else /* MS_WINDOWS */
4280/*[clinic input]
4281os.system -> long
4282
4283 command: FSConverter
4284
4285Execute the command in a subshell.
4286[clinic start generated code]*/
4287
Larry Hastings2f936352014-08-05 14:04:04 +10004288static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004289os_system_impl(PyObject *module, PyObject *command)
4290/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004291{
4292 long result;
4293 char *bytes = PyBytes_AsString(command);
4294 Py_BEGIN_ALLOW_THREADS
4295 result = system(bytes);
4296 Py_END_ALLOW_THREADS
4297 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004298}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004299#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004300#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004301
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004302
Larry Hastings2f936352014-08-05 14:04:04 +10004303/*[clinic input]
4304os.umask
4305
4306 mask: int
4307 /
4308
4309Set the current numeric umask and return the previous umask.
4310[clinic start generated code]*/
4311
Larry Hastings2f936352014-08-05 14:04:04 +10004312static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004313os_umask_impl(PyObject *module, int mask)
4314/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004315{
4316 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004317 if (i < 0)
4318 return posix_error();
4319 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004320}
4321
Brian Curtind40e6f72010-07-08 21:39:08 +00004322#ifdef MS_WINDOWS
4323
4324/* override the default DeleteFileW behavior so that directory
4325symlinks can be removed with this function, the same as with
4326Unix symlinks */
4327BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4328{
4329 WIN32_FILE_ATTRIBUTE_DATA info;
4330 WIN32_FIND_DATAW find_data;
4331 HANDLE find_data_handle;
4332 int is_directory = 0;
4333 int is_link = 0;
4334
4335 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4336 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004337
Brian Curtind40e6f72010-07-08 21:39:08 +00004338 /* Get WIN32_FIND_DATA structure for the path to determine if
4339 it is a symlink */
4340 if(is_directory &&
4341 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4342 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4343
4344 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004345 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4346 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4347 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4348 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004349 FindClose(find_data_handle);
4350 }
4351 }
4352 }
4353
4354 if (is_directory && is_link)
4355 return RemoveDirectoryW(lpFileName);
4356
4357 return DeleteFileW(lpFileName);
4358}
4359#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004360
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004361
Larry Hastings2f936352014-08-05 14:04:04 +10004362/*[clinic input]
4363os.unlink
4364
4365 path: path_t
4366 *
4367 dir_fd: dir_fd(requires='unlinkat')=None
4368
4369Remove a file (same as remove()).
4370
4371If dir_fd is not None, it should be a file descriptor open to a directory,
4372 and path should be relative; path will then be relative to that directory.
4373dir_fd may not be implemented on your platform.
4374 If it is unavailable, using it will raise a NotImplementedError.
4375
4376[clinic start generated code]*/
4377
Larry Hastings2f936352014-08-05 14:04:04 +10004378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004379os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4380/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004381{
4382 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383
4384 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004385 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004387 if (path->wide)
4388 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004389 else
Larry Hastings2f936352014-08-05 14:04:04 +10004390 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391 result = !result; /* Windows, success=1, UNIX, success=0 */
4392#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004393#ifdef HAVE_UNLINKAT
4394 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004395 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396 else
4397#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004398 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004400 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004401 Py_END_ALLOW_THREADS
4402
Larry Hastings2f936352014-08-05 14:04:04 +10004403 if (result)
4404 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004405
Larry Hastings2f936352014-08-05 14:04:04 +10004406 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004407}
4408
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004409
Larry Hastings2f936352014-08-05 14:04:04 +10004410/*[clinic input]
4411os.remove = os.unlink
4412
4413Remove a file (same as unlink()).
4414
4415If dir_fd is not None, it should be a file descriptor open to a directory,
4416 and path should be relative; path will then be relative to that directory.
4417dir_fd may not be implemented on your platform.
4418 If it is unavailable, using it will raise a NotImplementedError.
4419[clinic start generated code]*/
4420
Larry Hastings2f936352014-08-05 14:04:04 +10004421static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004422os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4423/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004424{
4425 return os_unlink_impl(module, path, dir_fd);
4426}
4427
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004428
Larry Hastings605a62d2012-06-24 04:33:36 -07004429static PyStructSequence_Field uname_result_fields[] = {
4430 {"sysname", "operating system name"},
4431 {"nodename", "name of machine on network (implementation-defined)"},
4432 {"release", "operating system release"},
4433 {"version", "operating system version"},
4434 {"machine", "hardware identifier"},
4435 {NULL}
4436};
4437
4438PyDoc_STRVAR(uname_result__doc__,
4439"uname_result: Result from os.uname().\n\n\
4440This object may be accessed either as a tuple of\n\
4441 (sysname, nodename, release, version, machine),\n\
4442or via the attributes sysname, nodename, release, version, and machine.\n\
4443\n\
4444See os.uname for more information.");
4445
4446static PyStructSequence_Desc uname_result_desc = {
4447 "uname_result", /* name */
4448 uname_result__doc__, /* doc */
4449 uname_result_fields,
4450 5
4451};
4452
4453static PyTypeObject UnameResultType;
4454
4455
4456#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004457/*[clinic input]
4458os.uname
4459
4460Return an object identifying the current operating system.
4461
4462The object behaves like a named tuple with the following fields:
4463 (sysname, nodename, release, version, machine)
4464
4465[clinic start generated code]*/
4466
Larry Hastings2f936352014-08-05 14:04:04 +10004467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004468os_uname_impl(PyObject *module)
4469/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004470{
Victor Stinner8c62be82010-05-06 00:08:46 +00004471 struct utsname u;
4472 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004473 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004474
Victor Stinner8c62be82010-05-06 00:08:46 +00004475 Py_BEGIN_ALLOW_THREADS
4476 res = uname(&u);
4477 Py_END_ALLOW_THREADS
4478 if (res < 0)
4479 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004480
4481 value = PyStructSequence_New(&UnameResultType);
4482 if (value == NULL)
4483 return NULL;
4484
4485#define SET(i, field) \
4486 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004487 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004488 if (!o) { \
4489 Py_DECREF(value); \
4490 return NULL; \
4491 } \
4492 PyStructSequence_SET_ITEM(value, i, o); \
4493 } \
4494
4495 SET(0, u.sysname);
4496 SET(1, u.nodename);
4497 SET(2, u.release);
4498 SET(3, u.version);
4499 SET(4, u.machine);
4500
4501#undef SET
4502
4503 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004504}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004505#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004506
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004507
Larry Hastings9cf065c2012-06-22 16:30:09 -07004508
4509typedef struct {
4510 int now;
4511 time_t atime_s;
4512 long atime_ns;
4513 time_t mtime_s;
4514 long mtime_ns;
4515} utime_t;
4516
4517/*
Victor Stinner484df002014-10-09 13:52:31 +02004518 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004519 * they also intentionally leak the declaration of a pointer named "time"
4520 */
4521#define UTIME_TO_TIMESPEC \
4522 struct timespec ts[2]; \
4523 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004524 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004525 time = NULL; \
4526 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004527 ts[0].tv_sec = ut->atime_s; \
4528 ts[0].tv_nsec = ut->atime_ns; \
4529 ts[1].tv_sec = ut->mtime_s; \
4530 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 time = ts; \
4532 } \
4533
4534#define UTIME_TO_TIMEVAL \
4535 struct timeval tv[2]; \
4536 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004537 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004538 time = NULL; \
4539 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004540 tv[0].tv_sec = ut->atime_s; \
4541 tv[0].tv_usec = ut->atime_ns / 1000; \
4542 tv[1].tv_sec = ut->mtime_s; \
4543 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 time = tv; \
4545 } \
4546
4547#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004548 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004550 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004551 time = NULL; \
4552 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004553 u.actime = ut->atime_s; \
4554 u.modtime = ut->mtime_s; \
4555 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004556 }
4557
4558#define UTIME_TO_TIME_T \
4559 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004560 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004561 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562 time = NULL; \
4563 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004564 timet[0] = ut->atime_s; \
4565 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004566 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567 } \
4568
4569
Victor Stinner528a9ab2015-09-03 21:30:26 +02004570#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004571
4572static int
Victor Stinner484df002014-10-09 13:52:31 +02004573utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574{
4575#ifdef HAVE_UTIMENSAT
4576 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4577 UTIME_TO_TIMESPEC;
4578 return utimensat(dir_fd, path, time, flags);
4579#elif defined(HAVE_FUTIMESAT)
4580 UTIME_TO_TIMEVAL;
4581 /*
4582 * follow_symlinks will never be false here;
4583 * we only allow !follow_symlinks and dir_fd together
4584 * if we have utimensat()
4585 */
4586 assert(follow_symlinks);
4587 return futimesat(dir_fd, path, time);
4588#endif
4589}
4590
Larry Hastings2f936352014-08-05 14:04:04 +10004591 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4592#else
4593 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004594#endif
4595
Victor Stinner528a9ab2015-09-03 21:30:26 +02004596#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004597
4598static int
Victor Stinner484df002014-10-09 13:52:31 +02004599utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004600{
4601#ifdef HAVE_FUTIMENS
4602 UTIME_TO_TIMESPEC;
4603 return futimens(fd, time);
4604#else
4605 UTIME_TO_TIMEVAL;
4606 return futimes(fd, time);
4607#endif
4608}
4609
Larry Hastings2f936352014-08-05 14:04:04 +10004610 #define PATH_UTIME_HAVE_FD 1
4611#else
4612 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004613#endif
4614
4615
4616#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4617 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4618
4619#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4620
4621static int
Victor Stinner484df002014-10-09 13:52:31 +02004622utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004623{
4624#ifdef HAVE_UTIMENSAT
4625 UTIME_TO_TIMESPEC;
4626 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4627#else
4628 UTIME_TO_TIMEVAL;
4629 return lutimes(path, time);
4630#endif
4631}
4632
4633#endif
4634
4635#ifndef MS_WINDOWS
4636
4637static int
Victor Stinner484df002014-10-09 13:52:31 +02004638utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004639{
4640#ifdef HAVE_UTIMENSAT
4641 UTIME_TO_TIMESPEC;
4642 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4643#elif defined(HAVE_UTIMES)
4644 UTIME_TO_TIMEVAL;
4645 return utimes(path, time);
4646#elif defined(HAVE_UTIME_H)
4647 UTIME_TO_UTIMBUF;
4648 return utime(path, time);
4649#else
4650 UTIME_TO_TIME_T;
4651 return utime(path, time);
4652#endif
4653}
4654
4655#endif
4656
Larry Hastings76ad59b2012-05-03 00:30:07 -07004657static int
4658split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4659{
4660 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004661 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004662 divmod = PyNumber_Divmod(py_long, billion);
4663 if (!divmod)
4664 goto exit;
4665 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4666 if ((*s == -1) && PyErr_Occurred())
4667 goto exit;
4668 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004669 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004670 goto exit;
4671
4672 result = 1;
4673exit:
4674 Py_XDECREF(divmod);
4675 return result;
4676}
4677
Larry Hastings2f936352014-08-05 14:04:04 +10004678
4679/*[clinic input]
4680os.utime
4681
4682 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4683 times: object = NULL
4684 *
4685 ns: object = NULL
4686 dir_fd: dir_fd(requires='futimensat') = None
4687 follow_symlinks: bool=True
4688
Martin Panter0ff89092015-09-09 01:56:53 +00004689# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004690
4691Set the access and modified time of path.
4692
4693path may always be specified as a string.
4694On some platforms, path may also be specified as an open file descriptor.
4695 If this functionality is unavailable, using it raises an exception.
4696
4697If times is not None, it must be a tuple (atime, mtime);
4698 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004699If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004700 atime_ns and mtime_ns should be expressed as integer nanoseconds
4701 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004702If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004703Specifying tuples for both times and ns is an error.
4704
4705If dir_fd is not None, it should be a file descriptor open to a directory,
4706 and path should be relative; path will then be relative to that directory.
4707If follow_symlinks is False, and the last element of the path is a symbolic
4708 link, utime will modify the symbolic link itself instead of the file the
4709 link points to.
4710It is an error to use dir_fd or follow_symlinks when specifying path
4711 as an open file descriptor.
4712dir_fd and follow_symlinks may not be available on your platform.
4713 If they are unavailable, using them will raise a NotImplementedError.
4714
4715[clinic start generated code]*/
4716
Larry Hastings2f936352014-08-05 14:04:04 +10004717static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004718os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4719 int dir_fd, int follow_symlinks)
4720/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004721{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722#ifdef MS_WINDOWS
4723 HANDLE hFile;
4724 FILETIME atime, mtime;
4725#else
4726 int result;
4727#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004728
Larry Hastings9cf065c2012-06-22 16:30:09 -07004729 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004730 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731
Christian Heimesb3c87242013-08-01 00:08:16 +02004732 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004733
Larry Hastings9cf065c2012-06-22 16:30:09 -07004734 if (times && (times != Py_None) && ns) {
4735 PyErr_SetString(PyExc_ValueError,
4736 "utime: you may specify either 'times'"
4737 " or 'ns' but not both");
4738 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004739 }
4740
4741 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004742 time_t a_sec, m_sec;
4743 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004744 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 PyErr_SetString(PyExc_TypeError,
4746 "utime: 'times' must be either"
4747 " a tuple of two ints or None");
4748 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004749 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004750 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004751 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004752 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004753 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004754 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004756 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004757 utime.atime_s = a_sec;
4758 utime.atime_ns = a_nsec;
4759 utime.mtime_s = m_sec;
4760 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004763 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004764 PyErr_SetString(PyExc_TypeError,
4765 "utime: 'ns' must be a tuple of two ints");
4766 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004767 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004769 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004771 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 &utime.mtime_s, &utime.mtime_ns)) {
4773 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004774 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 }
4776 else {
4777 /* times and ns are both None/unspecified. use "now". */
4778 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004779 }
4780
Larry Hastings9cf065c2012-06-22 16:30:09 -07004781#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4782 if (follow_symlinks_specified("utime", follow_symlinks))
4783 goto exit;
4784#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004785
Larry Hastings2f936352014-08-05 14:04:04 +10004786 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4787 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4788 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004790
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791#if !defined(HAVE_UTIMENSAT)
4792 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004793 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 "utime: cannot use dir_fd and follow_symlinks "
4795 "together on this platform");
4796 goto exit;
4797 }
4798#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004799
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004800#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004802 if (path->wide)
4803 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004804 NULL, OPEN_EXISTING,
4805 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 else
Larry Hastings2f936352014-08-05 14:04:04 +10004807 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004808 NULL, OPEN_EXISTING,
4809 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004810 Py_END_ALLOW_THREADS
4811 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004812 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004813 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004814 }
4815
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004817 GetSystemTimeAsFileTime(&mtime);
4818 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004819 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004820 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004821 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4822 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004823 }
4824 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4825 /* Avoid putting the file name into the error here,
4826 as that may confuse the user into believing that
4827 something is wrong with the file, when it also
4828 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004829 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004830 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004832#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004834
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4836 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004837 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004839#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840
Victor Stinner528a9ab2015-09-03 21:30:26 +02004841#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004843 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844 else
4845#endif
4846
Victor Stinner528a9ab2015-09-03 21:30:26 +02004847#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004848 if (path->fd != -1)
4849 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004850 else
4851#endif
4852
Larry Hastings2f936352014-08-05 14:04:04 +10004853 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004854
4855 Py_END_ALLOW_THREADS
4856
4857 if (result < 0) {
4858 /* see previous comment about not putting filename in error here */
4859 return_value = posix_error();
4860 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004861 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004862
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004863#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004864
4865 Py_INCREF(Py_None);
4866 return_value = Py_None;
4867
4868exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004869#ifdef MS_WINDOWS
4870 if (hFile != INVALID_HANDLE_VALUE)
4871 CloseHandle(hFile);
4872#endif
4873 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004874}
4875
Guido van Rossum3b066191991-06-04 19:40:25 +00004876/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004877
Larry Hastings2f936352014-08-05 14:04:04 +10004878
4879/*[clinic input]
4880os._exit
4881
4882 status: int
4883
4884Exit to the system with specified status, without normal exit processing.
4885[clinic start generated code]*/
4886
Larry Hastings2f936352014-08-05 14:04:04 +10004887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004888os__exit_impl(PyObject *module, int status)
4889/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004890{
4891 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004893}
4894
Martin v. Löwis114619e2002-10-07 06:44:21 +00004895#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4896static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004897free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004898{
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 Py_ssize_t i;
4900 for (i = 0; i < count; i++)
4901 PyMem_Free(array[i]);
4902 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004903}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004904
Antoine Pitrou69f71142009-05-24 21:25:49 +00004905static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004906int fsconvert_strdup(PyObject *o, char**out)
4907{
Victor Stinner8c62be82010-05-06 00:08:46 +00004908 PyObject *bytes;
4909 Py_ssize_t size;
4910 if (!PyUnicode_FSConverter(o, &bytes))
4911 return 0;
4912 size = PyBytes_GET_SIZE(bytes);
4913 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004914 if (!*out) {
4915 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004917 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004918 memcpy(*out, PyBytes_AsString(bytes), size+1);
4919 Py_DECREF(bytes);
4920 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004921}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004922#endif
4923
Ross Lagerwall7807c352011-03-17 20:20:30 +02004924#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004925static char**
4926parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4927{
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 char **envlist;
4929 Py_ssize_t i, pos, envc;
4930 PyObject *keys=NULL, *vals=NULL;
4931 PyObject *key, *val, *key2, *val2;
4932 char *p, *k, *v;
4933 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004934
Victor Stinner8c62be82010-05-06 00:08:46 +00004935 i = PyMapping_Size(env);
4936 if (i < 0)
4937 return NULL;
4938 envlist = PyMem_NEW(char *, i + 1);
4939 if (envlist == NULL) {
4940 PyErr_NoMemory();
4941 return NULL;
4942 }
4943 envc = 0;
4944 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004945 if (!keys)
4946 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004948 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 goto error;
4950 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4951 PyErr_Format(PyExc_TypeError,
4952 "env.keys() or env.values() is not a list");
4953 goto error;
4954 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004955
Victor Stinner8c62be82010-05-06 00:08:46 +00004956 for (pos = 0; pos < i; pos++) {
4957 key = PyList_GetItem(keys, pos);
4958 val = PyList_GetItem(vals, pos);
4959 if (!key || !val)
4960 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004961
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 if (PyUnicode_FSConverter(key, &key2) == 0)
4963 goto error;
4964 if (PyUnicode_FSConverter(val, &val2) == 0) {
4965 Py_DECREF(key2);
4966 goto error;
4967 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 k = PyBytes_AsString(key2);
4970 v = PyBytes_AsString(val2);
4971 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004972
Victor Stinner8c62be82010-05-06 00:08:46 +00004973 p = PyMem_NEW(char, len);
4974 if (p == NULL) {
4975 PyErr_NoMemory();
4976 Py_DECREF(key2);
4977 Py_DECREF(val2);
4978 goto error;
4979 }
4980 PyOS_snprintf(p, len, "%s=%s", k, v);
4981 envlist[envc++] = p;
4982 Py_DECREF(key2);
4983 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 }
4985 Py_DECREF(vals);
4986 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004987
Victor Stinner8c62be82010-05-06 00:08:46 +00004988 envlist[envc] = 0;
4989 *envc_ptr = envc;
4990 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004991
4992error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004993 Py_XDECREF(keys);
4994 Py_XDECREF(vals);
4995 while (--envc >= 0)
4996 PyMem_DEL(envlist[envc]);
4997 PyMem_DEL(envlist);
4998 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004999}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005000
Ross Lagerwall7807c352011-03-17 20:20:30 +02005001static char**
5002parse_arglist(PyObject* argv, Py_ssize_t *argc)
5003{
5004 int i;
5005 char **argvlist = PyMem_NEW(char *, *argc+1);
5006 if (argvlist == NULL) {
5007 PyErr_NoMemory();
5008 return NULL;
5009 }
5010 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005011 PyObject* item = PySequence_ITEM(argv, i);
5012 if (item == NULL)
5013 goto fail;
5014 if (!fsconvert_strdup(item, &argvlist[i])) {
5015 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005016 goto fail;
5017 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005018 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005019 }
5020 argvlist[*argc] = NULL;
5021 return argvlist;
5022fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005023 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024 free_string_array(argvlist, *argc);
5025 return NULL;
5026}
5027#endif
5028
Larry Hastings2f936352014-08-05 14:04:04 +10005029
Ross Lagerwall7807c352011-03-17 20:20:30 +02005030#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005031/*[clinic input]
5032os.execv
5033
5034 path: FSConverter
5035 Path of executable file.
5036 argv: object
5037 Tuple or list of strings.
5038 /
5039
5040Execute an executable path with arguments, replacing current process.
5041[clinic start generated code]*/
5042
Larry Hastings2f936352014-08-05 14:04:04 +10005043static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005044os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5045/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005046{
5047 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 char **argvlist;
5049 Py_ssize_t argc;
5050
5051 /* execv has two arguments: (path, argv), where
5052 argv is a list or tuple of strings. */
5053
Larry Hastings2f936352014-08-05 14:04:04 +10005054 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005055 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5056 PyErr_SetString(PyExc_TypeError,
5057 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005058 return NULL;
5059 }
5060 argc = PySequence_Size(argv);
5061 if (argc < 1) {
5062 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005063 return NULL;
5064 }
5065
5066 argvlist = parse_arglist(argv, &argc);
5067 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005068 return NULL;
5069 }
5070
Larry Hastings2f936352014-08-05 14:04:04 +10005071 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005072
5073 /* If we get here it's definitely an error */
5074
5075 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 return posix_error();
5077}
5078
Larry Hastings2f936352014-08-05 14:04:04 +10005079
5080/*[clinic input]
5081os.execve
5082
5083 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5084 Path of executable file.
5085 argv: object
5086 Tuple or list of strings.
5087 env: object
5088 Dictionary of strings mapping to strings.
5089
5090Execute an executable path with arguments, replacing current process.
5091[clinic start generated code]*/
5092
Larry Hastings2f936352014-08-05 14:04:04 +10005093static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005094os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5095/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005096{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005097 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005099 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005100
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 /* execve has three arguments: (path, argv, env), where
5102 argv is a list or tuple of strings and env is a dictionary
5103 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005104
Ross Lagerwall7807c352011-03-17 20:20:30 +02005105 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005106 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005107 "execve: argv must be a tuple or list");
5108 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005110 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005111 if (!PyMapping_Check(env)) {
5112 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113 "execve: environment must be a mapping object");
5114 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005116
Ross Lagerwall7807c352011-03-17 20:20:30 +02005117 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005119 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005121
Victor Stinner8c62be82010-05-06 00:08:46 +00005122 envlist = parse_envlist(env, &envc);
5123 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124 goto fail;
5125
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005127 if (path->fd > -1)
5128 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005129 else
5130#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005131 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005132
5133 /* If we get here it's definitely an error */
5134
Larry Hastings2f936352014-08-05 14:04:04 +10005135 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005136
5137 while (--envc >= 0)
5138 PyMem_DEL(envlist[envc]);
5139 PyMem_DEL(envlist);
5140 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005141 if (argvlist)
5142 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005143 return NULL;
5144}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005145#endif /* HAVE_EXECV */
5146
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005147
Guido van Rossuma1065681999-01-25 23:20:23 +00005148#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005149/*[clinic input]
5150os.spawnv
5151
5152 mode: int
5153 Mode of process creation.
5154 path: FSConverter
5155 Path of executable file.
5156 argv: object
5157 Tuple or list of strings.
5158 /
5159
5160Execute the program specified by path in a new process.
5161[clinic start generated code]*/
5162
Larry Hastings2f936352014-08-05 14:04:04 +10005163static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005164os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5165/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005166{
5167 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005169 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 Py_ssize_t argc;
5171 Py_intptr_t spawnval;
5172 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005173
Victor Stinner8c62be82010-05-06 00:08:46 +00005174 /* spawnv has three arguments: (mode, path, argv), where
5175 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005176
Larry Hastings2f936352014-08-05 14:04:04 +10005177 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005178 if (PyList_Check(argv)) {
5179 argc = PyList_Size(argv);
5180 getitem = PyList_GetItem;
5181 }
5182 else if (PyTuple_Check(argv)) {
5183 argc = PyTuple_Size(argv);
5184 getitem = PyTuple_GetItem;
5185 }
5186 else {
5187 PyErr_SetString(PyExc_TypeError,
5188 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 return NULL;
5190 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 argvlist = PyMem_NEW(char *, argc+1);
5193 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005194 return PyErr_NoMemory();
5195 }
5196 for (i = 0; i < argc; i++) {
5197 if (!fsconvert_strdup((*getitem)(argv, i),
5198 &argvlist[i])) {
5199 free_string_array(argvlist, i);
5200 PyErr_SetString(
5201 PyExc_TypeError,
5202 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 return NULL;
5204 }
5205 }
5206 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005207
Victor Stinner8c62be82010-05-06 00:08:46 +00005208 if (mode == _OLD_P_OVERLAY)
5209 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005210
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005212 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005214
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005216
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 if (spawnval == -1)
5218 return posix_error();
5219 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005220 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005221}
5222
5223
Larry Hastings2f936352014-08-05 14:04:04 +10005224/*[clinic input]
5225os.spawnve
5226
5227 mode: int
5228 Mode of process creation.
5229 path: FSConverter
5230 Path of executable file.
5231 argv: object
5232 Tuple or list of strings.
5233 env: object
5234 Dictionary of strings mapping to strings.
5235 /
5236
5237Execute the program specified by path in a new process.
5238[clinic start generated code]*/
5239
Larry Hastings2f936352014-08-05 14:04:04 +10005240static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005241os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5242 PyObject *env)
5243/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005244{
5245 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 char **argvlist;
5247 char **envlist;
5248 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005249 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005250 Py_intptr_t spawnval;
5251 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5252 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005253
Victor Stinner8c62be82010-05-06 00:08:46 +00005254 /* spawnve has four arguments: (mode, path, argv, env), where
5255 argv is a list or tuple of strings and env is a dictionary
5256 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005257
Larry Hastings2f936352014-08-05 14:04:04 +10005258 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005259 if (PyList_Check(argv)) {
5260 argc = PyList_Size(argv);
5261 getitem = PyList_GetItem;
5262 }
5263 else if (PyTuple_Check(argv)) {
5264 argc = PyTuple_Size(argv);
5265 getitem = PyTuple_GetItem;
5266 }
5267 else {
5268 PyErr_SetString(PyExc_TypeError,
5269 "spawnve() arg 2 must be a tuple or list");
5270 goto fail_0;
5271 }
5272 if (!PyMapping_Check(env)) {
5273 PyErr_SetString(PyExc_TypeError,
5274 "spawnve() arg 3 must be a mapping object");
5275 goto fail_0;
5276 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005277
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 argvlist = PyMem_NEW(char *, argc+1);
5279 if (argvlist == NULL) {
5280 PyErr_NoMemory();
5281 goto fail_0;
5282 }
5283 for (i = 0; i < argc; i++) {
5284 if (!fsconvert_strdup((*getitem)(argv, i),
5285 &argvlist[i]))
5286 {
5287 lastarg = i;
5288 goto fail_1;
5289 }
5290 }
5291 lastarg = argc;
5292 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005293
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 envlist = parse_envlist(env, &envc);
5295 if (envlist == NULL)
5296 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005297
Victor Stinner8c62be82010-05-06 00:08:46 +00005298 if (mode == _OLD_P_OVERLAY)
5299 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005300
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005302 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005304
Victor Stinner8c62be82010-05-06 00:08:46 +00005305 if (spawnval == -1)
5306 (void) posix_error();
5307 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005308 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005309
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 while (--envc >= 0)
5311 PyMem_DEL(envlist[envc]);
5312 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005313 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005315 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005316 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005317}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005318
Guido van Rossuma1065681999-01-25 23:20:23 +00005319#endif /* HAVE_SPAWNV */
5320
5321
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005322#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005323/*[clinic input]
5324os.fork1
5325
5326Fork a child process with a single multiplexed (i.e., not bound) thread.
5327
5328Return 0 to child process and PID of child to parent process.
5329[clinic start generated code]*/
5330
Larry Hastings2f936352014-08-05 14:04:04 +10005331static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005332os_fork1_impl(PyObject *module)
5333/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005334{
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 pid_t pid;
5336 int result = 0;
5337 _PyImport_AcquireLock();
5338 pid = fork1();
5339 if (pid == 0) {
5340 /* child: this clobbers and resets the import lock. */
5341 PyOS_AfterFork();
5342 } else {
5343 /* parent: release the import lock. */
5344 result = _PyImport_ReleaseLock();
5345 }
5346 if (pid == -1)
5347 return posix_error();
5348 if (result < 0) {
5349 /* Don't clobber the OSError if the fork failed. */
5350 PyErr_SetString(PyExc_RuntimeError,
5351 "not holding the import lock");
5352 return NULL;
5353 }
5354 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005355}
Larry Hastings2f936352014-08-05 14:04:04 +10005356#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005357
5358
Guido van Rossumad0ee831995-03-01 10:34:45 +00005359#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005360/*[clinic input]
5361os.fork
5362
5363Fork a child process.
5364
5365Return 0 to child process and PID of child to parent process.
5366[clinic start generated code]*/
5367
Larry Hastings2f936352014-08-05 14:04:04 +10005368static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005369os_fork_impl(PyObject *module)
5370/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005371{
Victor Stinner8c62be82010-05-06 00:08:46 +00005372 pid_t pid;
5373 int result = 0;
5374 _PyImport_AcquireLock();
5375 pid = fork();
5376 if (pid == 0) {
5377 /* child: this clobbers and resets the import lock. */
5378 PyOS_AfterFork();
5379 } else {
5380 /* parent: release the import lock. */
5381 result = _PyImport_ReleaseLock();
5382 }
5383 if (pid == -1)
5384 return posix_error();
5385 if (result < 0) {
5386 /* Don't clobber the OSError if the fork failed. */
5387 PyErr_SetString(PyExc_RuntimeError,
5388 "not holding the import lock");
5389 return NULL;
5390 }
5391 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005392}
Larry Hastings2f936352014-08-05 14:04:04 +10005393#endif /* HAVE_FORK */
5394
Guido van Rossum85e3b011991-06-03 12:42:10 +00005395
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005396#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005397#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005398/*[clinic input]
5399os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005400
Larry Hastings2f936352014-08-05 14:04:04 +10005401 policy: int
5402
5403Get the maximum scheduling priority for policy.
5404[clinic start generated code]*/
5405
Larry Hastings2f936352014-08-05 14:04:04 +10005406static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005407os_sched_get_priority_max_impl(PyObject *module, int policy)
5408/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005409{
5410 int max;
5411
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005412 max = sched_get_priority_max(policy);
5413 if (max < 0)
5414 return posix_error();
5415 return PyLong_FromLong(max);
5416}
5417
Larry Hastings2f936352014-08-05 14:04:04 +10005418
5419/*[clinic input]
5420os.sched_get_priority_min
5421
5422 policy: int
5423
5424Get the minimum scheduling priority for policy.
5425[clinic start generated code]*/
5426
Larry Hastings2f936352014-08-05 14:04:04 +10005427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005428os_sched_get_priority_min_impl(PyObject *module, int policy)
5429/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005430{
5431 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005432 if (min < 0)
5433 return posix_error();
5434 return PyLong_FromLong(min);
5435}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005436#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5437
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005438
Larry Hastings2f936352014-08-05 14:04:04 +10005439#ifdef HAVE_SCHED_SETSCHEDULER
5440/*[clinic input]
5441os.sched_getscheduler
5442 pid: pid_t
5443 /
5444
5445Get the scheduling policy for the process identifiedy by pid.
5446
5447Passing 0 for pid returns the scheduling policy for the calling process.
5448[clinic start generated code]*/
5449
Larry Hastings2f936352014-08-05 14:04:04 +10005450static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005451os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5452/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005453{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005454 int policy;
5455
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005456 policy = sched_getscheduler(pid);
5457 if (policy < 0)
5458 return posix_error();
5459 return PyLong_FromLong(policy);
5460}
Larry Hastings2f936352014-08-05 14:04:04 +10005461#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005462
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005463
5464#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005465/*[clinic input]
5466class os.sched_param "PyObject *" "&SchedParamType"
5467
5468@classmethod
5469os.sched_param.__new__
5470
5471 sched_priority: object
5472 A scheduling parameter.
5473
5474Current has only one field: sched_priority");
5475[clinic start generated code]*/
5476
Larry Hastings2f936352014-08-05 14:04:04 +10005477static PyObject *
5478os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005479/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005480{
5481 PyObject *res;
5482
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005483 res = PyStructSequence_New(type);
5484 if (!res)
5485 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005486 Py_INCREF(sched_priority);
5487 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005488 return res;
5489}
5490
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005491
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005492PyDoc_VAR(os_sched_param__doc__);
5493
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005494static PyStructSequence_Field sched_param_fields[] = {
5495 {"sched_priority", "the scheduling priority"},
5496 {0}
5497};
5498
5499static PyStructSequence_Desc sched_param_desc = {
5500 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005501 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005502 sched_param_fields,
5503 1
5504};
5505
5506static int
5507convert_sched_param(PyObject *param, struct sched_param *res)
5508{
5509 long priority;
5510
5511 if (Py_TYPE(param) != &SchedParamType) {
5512 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5513 return 0;
5514 }
5515 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5516 if (priority == -1 && PyErr_Occurred())
5517 return 0;
5518 if (priority > INT_MAX || priority < INT_MIN) {
5519 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5520 return 0;
5521 }
5522 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5523 return 1;
5524}
Larry Hastings2f936352014-08-05 14:04:04 +10005525#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005526
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005527
5528#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005529/*[clinic input]
5530os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005531
Larry Hastings2f936352014-08-05 14:04:04 +10005532 pid: pid_t
5533 policy: int
5534 param: sched_param
5535 /
5536
5537Set the scheduling policy for the process identified by pid.
5538
5539If pid is 0, the calling process is changed.
5540param is an instance of sched_param.
5541[clinic start generated code]*/
5542
Larry Hastings2f936352014-08-05 14:04:04 +10005543static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005544os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005545 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005546/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005547{
Jesus Cea9c822272011-09-10 01:40:52 +02005548 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005549 ** sched_setscheduler() returns 0 in Linux, but the previous
5550 ** scheduling policy under Solaris/Illumos, and others.
5551 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005552 */
Larry Hastings2f936352014-08-05 14:04:04 +10005553 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005554 return posix_error();
5555 Py_RETURN_NONE;
5556}
Larry Hastings2f936352014-08-05 14:04:04 +10005557#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005558
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005559
5560#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005561/*[clinic input]
5562os.sched_getparam
5563 pid: pid_t
5564 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005565
Larry Hastings2f936352014-08-05 14:04:04 +10005566Returns scheduling parameters for the process identified by pid.
5567
5568If pid is 0, returns parameters for the calling process.
5569Return value is an instance of sched_param.
5570[clinic start generated code]*/
5571
Larry Hastings2f936352014-08-05 14:04:04 +10005572static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005573os_sched_getparam_impl(PyObject *module, pid_t pid)
5574/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005575{
5576 struct sched_param param;
5577 PyObject *result;
5578 PyObject *priority;
5579
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005580 if (sched_getparam(pid, &param))
5581 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005582 result = PyStructSequence_New(&SchedParamType);
5583 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005584 return NULL;
5585 priority = PyLong_FromLong(param.sched_priority);
5586 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005587 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005588 return NULL;
5589 }
Larry Hastings2f936352014-08-05 14:04:04 +10005590 PyStructSequence_SET_ITEM(result, 0, priority);
5591 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005592}
5593
Larry Hastings2f936352014-08-05 14:04:04 +10005594
5595/*[clinic input]
5596os.sched_setparam
5597 pid: pid_t
5598 param: sched_param
5599 /
5600
5601Set scheduling parameters for the process identified by pid.
5602
5603If pid is 0, sets parameters for the calling process.
5604param should be an instance of sched_param.
5605[clinic start generated code]*/
5606
Larry Hastings2f936352014-08-05 14:04:04 +10005607static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005608os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005609 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005610/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005611{
5612 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005613 return posix_error();
5614 Py_RETURN_NONE;
5615}
Larry Hastings2f936352014-08-05 14:04:04 +10005616#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005617
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005618
5619#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005620/*[clinic input]
5621os.sched_rr_get_interval -> double
5622 pid: pid_t
5623 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005624
Larry Hastings2f936352014-08-05 14:04:04 +10005625Return the round-robin quantum for the process identified by pid, in seconds.
5626
5627Value returned is a float.
5628[clinic start generated code]*/
5629
Larry Hastings2f936352014-08-05 14:04:04 +10005630static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005631os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5632/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005633{
5634 struct timespec interval;
5635 if (sched_rr_get_interval(pid, &interval)) {
5636 posix_error();
5637 return -1.0;
5638 }
5639 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5640}
5641#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005642
Larry Hastings2f936352014-08-05 14:04:04 +10005643
5644/*[clinic input]
5645os.sched_yield
5646
5647Voluntarily relinquish the CPU.
5648[clinic start generated code]*/
5649
Larry Hastings2f936352014-08-05 14:04:04 +10005650static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005651os_sched_yield_impl(PyObject *module)
5652/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005653{
5654 if (sched_yield())
5655 return posix_error();
5656 Py_RETURN_NONE;
5657}
5658
Benjamin Peterson2740af82011-08-02 17:41:34 -05005659#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005660/* The minimum number of CPUs allocated in a cpu_set_t */
5661static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005662
Larry Hastings2f936352014-08-05 14:04:04 +10005663/*[clinic input]
5664os.sched_setaffinity
5665 pid: pid_t
5666 mask : object
5667 /
5668
5669Set the CPU affinity of the process identified by pid to mask.
5670
5671mask should be an iterable of integers identifying CPUs.
5672[clinic start generated code]*/
5673
Larry Hastings2f936352014-08-05 14:04:04 +10005674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005675os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5676/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005677{
Antoine Pitrou84869872012-08-04 16:16:35 +02005678 int ncpus;
5679 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005680 cpu_set_t *cpu_set = NULL;
5681 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005682
Larry Hastings2f936352014-08-05 14:04:04 +10005683 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005684 if (iterator == NULL)
5685 return NULL;
5686
5687 ncpus = NCPUS_START;
5688 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005689 cpu_set = CPU_ALLOC(ncpus);
5690 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005691 PyErr_NoMemory();
5692 goto error;
5693 }
Larry Hastings2f936352014-08-05 14:04:04 +10005694 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005695
5696 while ((item = PyIter_Next(iterator))) {
5697 long cpu;
5698 if (!PyLong_Check(item)) {
5699 PyErr_Format(PyExc_TypeError,
5700 "expected an iterator of ints, "
5701 "but iterator yielded %R",
5702 Py_TYPE(item));
5703 Py_DECREF(item);
5704 goto error;
5705 }
5706 cpu = PyLong_AsLong(item);
5707 Py_DECREF(item);
5708 if (cpu < 0) {
5709 if (!PyErr_Occurred())
5710 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5711 goto error;
5712 }
5713 if (cpu > INT_MAX - 1) {
5714 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5715 goto error;
5716 }
5717 if (cpu >= ncpus) {
5718 /* Grow CPU mask to fit the CPU number */
5719 int newncpus = ncpus;
5720 cpu_set_t *newmask;
5721 size_t newsetsize;
5722 while (newncpus <= cpu) {
5723 if (newncpus > INT_MAX / 2)
5724 newncpus = cpu + 1;
5725 else
5726 newncpus = newncpus * 2;
5727 }
5728 newmask = CPU_ALLOC(newncpus);
5729 if (newmask == NULL) {
5730 PyErr_NoMemory();
5731 goto error;
5732 }
5733 newsetsize = CPU_ALLOC_SIZE(newncpus);
5734 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005735 memcpy(newmask, cpu_set, setsize);
5736 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005737 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005738 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005739 ncpus = newncpus;
5740 }
Larry Hastings2f936352014-08-05 14:04:04 +10005741 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005742 }
5743 Py_CLEAR(iterator);
5744
Larry Hastings2f936352014-08-05 14:04:04 +10005745 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005746 posix_error();
5747 goto error;
5748 }
Larry Hastings2f936352014-08-05 14:04:04 +10005749 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005750 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005751
5752error:
Larry Hastings2f936352014-08-05 14:04:04 +10005753 if (cpu_set)
5754 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005755 Py_XDECREF(iterator);
5756 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005757}
5758
Larry Hastings2f936352014-08-05 14:04:04 +10005759
5760/*[clinic input]
5761os.sched_getaffinity
5762 pid: pid_t
5763 /
5764
5765Return the affinity of the process identified by pid.
5766
5767The affinity is returned as a set of CPU identifiers.
5768[clinic start generated code]*/
5769
Larry Hastings2f936352014-08-05 14:04:04 +10005770static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005771os_sched_getaffinity_impl(PyObject *module, pid_t pid)
5772/*[clinic end generated code: output=f726f2c193c17a4f input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005773{
Antoine Pitrou84869872012-08-04 16:16:35 +02005774 int cpu, ncpus, count;
5775 size_t setsize;
5776 cpu_set_t *mask = NULL;
5777 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005778
Antoine Pitrou84869872012-08-04 16:16:35 +02005779 ncpus = NCPUS_START;
5780 while (1) {
5781 setsize = CPU_ALLOC_SIZE(ncpus);
5782 mask = CPU_ALLOC(ncpus);
5783 if (mask == NULL)
5784 return PyErr_NoMemory();
5785 if (sched_getaffinity(pid, setsize, mask) == 0)
5786 break;
5787 CPU_FREE(mask);
5788 if (errno != EINVAL)
5789 return posix_error();
5790 if (ncpus > INT_MAX / 2) {
5791 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5792 "a large enough CPU set");
5793 return NULL;
5794 }
5795 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005796 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005797
5798 res = PySet_New(NULL);
5799 if (res == NULL)
5800 goto error;
5801 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5802 if (CPU_ISSET_S(cpu, setsize, mask)) {
5803 PyObject *cpu_num = PyLong_FromLong(cpu);
5804 --count;
5805 if (cpu_num == NULL)
5806 goto error;
5807 if (PySet_Add(res, cpu_num)) {
5808 Py_DECREF(cpu_num);
5809 goto error;
5810 }
5811 Py_DECREF(cpu_num);
5812 }
5813 }
5814 CPU_FREE(mask);
5815 return res;
5816
5817error:
5818 if (mask)
5819 CPU_FREE(mask);
5820 Py_XDECREF(res);
5821 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005822}
5823
Benjamin Peterson2740af82011-08-02 17:41:34 -05005824#endif /* HAVE_SCHED_SETAFFINITY */
5825
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005826#endif /* HAVE_SCHED_H */
5827
Larry Hastings2f936352014-08-05 14:04:04 +10005828
Neal Norwitzb59798b2003-03-21 01:43:31 +00005829/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005830/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5831#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005832#define DEV_PTY_FILE "/dev/ptc"
5833#define HAVE_DEV_PTMX
5834#else
5835#define DEV_PTY_FILE "/dev/ptmx"
5836#endif
5837
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005838#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005839#ifdef HAVE_PTY_H
5840#include <pty.h>
5841#else
5842#ifdef HAVE_LIBUTIL_H
5843#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005844#else
5845#ifdef HAVE_UTIL_H
5846#include <util.h>
5847#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005848#endif /* HAVE_LIBUTIL_H */
5849#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005850#ifdef HAVE_STROPTS_H
5851#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005852#endif
5853#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005854
Larry Hastings2f936352014-08-05 14:04:04 +10005855
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005856#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005857/*[clinic input]
5858os.openpty
5859
5860Open a pseudo-terminal.
5861
5862Return a tuple of (master_fd, slave_fd) containing open file descriptors
5863for both the master and slave ends.
5864[clinic start generated code]*/
5865
Larry Hastings2f936352014-08-05 14:04:04 +10005866static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005867os_openpty_impl(PyObject *module)
5868/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005869{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005870 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005871#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005872 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005873#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005874#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005875 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005876#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005877 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005878#endif
5879#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005880
Thomas Wouters70c21a12000-07-14 14:28:33 +00005881#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005882 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005883 goto posix_error;
5884
5885 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5886 goto error;
5887 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5888 goto error;
5889
Neal Norwitzb59798b2003-03-21 01:43:31 +00005890#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005891 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5892 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005893 goto posix_error;
5894 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5895 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005896
Victor Stinnerdaf45552013-08-28 00:53:59 +02005897 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005899 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005900
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005901#else
Victor Stinner000de532013-11-25 23:19:58 +01005902 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005904 goto posix_error;
5905
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005907
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 /* change permission of slave */
5909 if (grantpt(master_fd) < 0) {
5910 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005913
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 /* unlock slave */
5915 if (unlockpt(master_fd) < 0) {
5916 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005917 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005919
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005921
Victor Stinner8c62be82010-05-06 00:08:46 +00005922 slave_name = ptsname(master_fd); /* get name of slave */
5923 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005924 goto posix_error;
5925
5926 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005927 if (slave_fd == -1)
5928 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005929
5930 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5931 goto posix_error;
5932
Neal Norwitzb59798b2003-03-21 01:43:31 +00005933#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5935 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005936#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005937 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005938#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005939#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005940#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941
Victor Stinner8c62be82010-05-06 00:08:46 +00005942 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005943
Victor Stinnerdaf45552013-08-28 00:53:59 +02005944posix_error:
5945 posix_error();
5946error:
5947 if (master_fd != -1)
5948 close(master_fd);
5949 if (slave_fd != -1)
5950 close(slave_fd);
5951 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005952}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005953#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005954
Larry Hastings2f936352014-08-05 14:04:04 +10005955
Fred Drake8cef4cf2000-06-28 16:40:38 +00005956#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005957/*[clinic input]
5958os.forkpty
5959
5960Fork a new process with a new pseudo-terminal as controlling tty.
5961
5962Returns a tuple of (pid, master_fd).
5963Like fork(), return pid of 0 to the child process,
5964and pid of child to the parent process.
5965To both, return fd of newly opened pseudo-terminal.
5966[clinic start generated code]*/
5967
Larry Hastings2f936352014-08-05 14:04:04 +10005968static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005969os_forkpty_impl(PyObject *module)
5970/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005971{
Victor Stinner8c62be82010-05-06 00:08:46 +00005972 int master_fd = -1, result = 0;
5973 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005974
Victor Stinner8c62be82010-05-06 00:08:46 +00005975 _PyImport_AcquireLock();
5976 pid = forkpty(&master_fd, NULL, NULL, NULL);
5977 if (pid == 0) {
5978 /* child: this clobbers and resets the import lock. */
5979 PyOS_AfterFork();
5980 } else {
5981 /* parent: release the import lock. */
5982 result = _PyImport_ReleaseLock();
5983 }
5984 if (pid == -1)
5985 return posix_error();
5986 if (result < 0) {
5987 /* Don't clobber the OSError if the fork failed. */
5988 PyErr_SetString(PyExc_RuntimeError,
5989 "not holding the import lock");
5990 return NULL;
5991 }
5992 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005993}
Larry Hastings2f936352014-08-05 14:04:04 +10005994#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005995
Ross Lagerwall7807c352011-03-17 20:20:30 +02005996
Guido van Rossumad0ee831995-03-01 10:34:45 +00005997#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005998/*[clinic input]
5999os.getegid
6000
6001Return the current process's effective group id.
6002[clinic start generated code]*/
6003
Larry Hastings2f936352014-08-05 14:04:04 +10006004static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006005os_getegid_impl(PyObject *module)
6006/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006007{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006008 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006009}
Larry Hastings2f936352014-08-05 14:04:04 +10006010#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006011
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006012
Guido van Rossumad0ee831995-03-01 10:34:45 +00006013#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006014/*[clinic input]
6015os.geteuid
6016
6017Return the current process's effective user id.
6018[clinic start generated code]*/
6019
Larry Hastings2f936352014-08-05 14:04:04 +10006020static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006021os_geteuid_impl(PyObject *module)
6022/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006023{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006024 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006025}
Larry Hastings2f936352014-08-05 14:04:04 +10006026#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006027
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006028
Guido van Rossumad0ee831995-03-01 10:34:45 +00006029#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006030/*[clinic input]
6031os.getgid
6032
6033Return the current process's group id.
6034[clinic start generated code]*/
6035
Larry Hastings2f936352014-08-05 14:04:04 +10006036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006037os_getgid_impl(PyObject *module)
6038/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006039{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006040 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006041}
Larry Hastings2f936352014-08-05 14:04:04 +10006042#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006043
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006044
Larry Hastings2f936352014-08-05 14:04:04 +10006045/*[clinic input]
6046os.getpid
6047
6048Return the current process id.
6049[clinic start generated code]*/
6050
Larry Hastings2f936352014-08-05 14:04:04 +10006051static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006052os_getpid_impl(PyObject *module)
6053/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006054{
Victor Stinner8c62be82010-05-06 00:08:46 +00006055 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006056}
6057
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006058#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006059
6060/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006061PyDoc_STRVAR(posix_getgrouplist__doc__,
6062"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6063Returns a list of groups to which a user belongs.\n\n\
6064 user: username to lookup\n\
6065 group: base group id of the user");
6066
6067static PyObject *
6068posix_getgrouplist(PyObject *self, PyObject *args)
6069{
6070#ifdef NGROUPS_MAX
6071#define MAX_GROUPS NGROUPS_MAX
6072#else
6073 /* defined to be 16 on Solaris7, so this should be a small number */
6074#define MAX_GROUPS 64
6075#endif
6076
6077 const char *user;
6078 int i, ngroups;
6079 PyObject *list;
6080#ifdef __APPLE__
6081 int *groups, basegid;
6082#else
6083 gid_t *groups, basegid;
6084#endif
6085 ngroups = MAX_GROUPS;
6086
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006087#ifdef __APPLE__
6088 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006089 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006090#else
6091 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6092 _Py_Gid_Converter, &basegid))
6093 return NULL;
6094#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006095
6096#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006097 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006098#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006099 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006100#endif
6101 if (groups == NULL)
6102 return PyErr_NoMemory();
6103
6104 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6105 PyMem_Del(groups);
6106 return posix_error();
6107 }
6108
6109 list = PyList_New(ngroups);
6110 if (list == NULL) {
6111 PyMem_Del(groups);
6112 return NULL;
6113 }
6114
6115 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006116#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006117 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006118#else
6119 PyObject *o = _PyLong_FromGid(groups[i]);
6120#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006121 if (o == NULL) {
6122 Py_DECREF(list);
6123 PyMem_Del(groups);
6124 return NULL;
6125 }
6126 PyList_SET_ITEM(list, i, o);
6127 }
6128
6129 PyMem_Del(groups);
6130
6131 return list;
6132}
Larry Hastings2f936352014-08-05 14:04:04 +10006133#endif /* HAVE_GETGROUPLIST */
6134
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006135
Fred Drakec9680921999-12-13 16:37:25 +00006136#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006137/*[clinic input]
6138os.getgroups
6139
6140Return list of supplemental group IDs for the process.
6141[clinic start generated code]*/
6142
Larry Hastings2f936352014-08-05 14:04:04 +10006143static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006144os_getgroups_impl(PyObject *module)
6145/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006146{
6147 PyObject *result = NULL;
6148
Fred Drakec9680921999-12-13 16:37:25 +00006149#ifdef NGROUPS_MAX
6150#define MAX_GROUPS NGROUPS_MAX
6151#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006152 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006153#define MAX_GROUPS 64
6154#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006155 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006156
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006157 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006158 * This is a helper variable to store the intermediate result when
6159 * that happens.
6160 *
6161 * To keep the code readable the OSX behaviour is unconditional,
6162 * according to the POSIX spec this should be safe on all unix-y
6163 * systems.
6164 */
6165 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006166 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006167
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006168#ifdef __APPLE__
6169 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6170 * there are more groups than can fit in grouplist. Therefore, on OS X
6171 * always first call getgroups with length 0 to get the actual number
6172 * of groups.
6173 */
6174 n = getgroups(0, NULL);
6175 if (n < 0) {
6176 return posix_error();
6177 } else if (n <= MAX_GROUPS) {
6178 /* groups will fit in existing array */
6179 alt_grouplist = grouplist;
6180 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006181 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006182 if (alt_grouplist == NULL) {
6183 errno = EINVAL;
6184 return posix_error();
6185 }
6186 }
6187
6188 n = getgroups(n, alt_grouplist);
6189 if (n == -1) {
6190 if (alt_grouplist != grouplist) {
6191 PyMem_Free(alt_grouplist);
6192 }
6193 return posix_error();
6194 }
6195#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006196 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006197 if (n < 0) {
6198 if (errno == EINVAL) {
6199 n = getgroups(0, NULL);
6200 if (n == -1) {
6201 return posix_error();
6202 }
6203 if (n == 0) {
6204 /* Avoid malloc(0) */
6205 alt_grouplist = grouplist;
6206 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006207 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006208 if (alt_grouplist == NULL) {
6209 errno = EINVAL;
6210 return posix_error();
6211 }
6212 n = getgroups(n, alt_grouplist);
6213 if (n == -1) {
6214 PyMem_Free(alt_grouplist);
6215 return posix_error();
6216 }
6217 }
6218 } else {
6219 return posix_error();
6220 }
6221 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006222#endif
6223
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006224 result = PyList_New(n);
6225 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 int i;
6227 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006228 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006229 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006230 Py_DECREF(result);
6231 result = NULL;
6232 break;
Fred Drakec9680921999-12-13 16:37:25 +00006233 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006235 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006236 }
6237
6238 if (alt_grouplist != grouplist) {
6239 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006240 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006241
Fred Drakec9680921999-12-13 16:37:25 +00006242 return result;
6243}
Larry Hastings2f936352014-08-05 14:04:04 +10006244#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006245
Antoine Pitroub7572f02009-12-02 20:46:48 +00006246#ifdef HAVE_INITGROUPS
6247PyDoc_STRVAR(posix_initgroups__doc__,
6248"initgroups(username, gid) -> None\n\n\
6249Call the system initgroups() to initialize the group access list with all of\n\
6250the groups of which the specified username is a member, plus the specified\n\
6251group id.");
6252
Larry Hastings2f936352014-08-05 14:04:04 +10006253/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006254static PyObject *
6255posix_initgroups(PyObject *self, PyObject *args)
6256{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006257 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006258 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006259 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006260#ifdef __APPLE__
6261 int gid;
6262#else
6263 gid_t gid;
6264#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006265
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006266#ifdef __APPLE__
6267 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6268 PyUnicode_FSConverter, &oname,
6269 &gid))
6270#else
6271 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6272 PyUnicode_FSConverter, &oname,
6273 _Py_Gid_Converter, &gid))
6274#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006276 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006277
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006278 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006279 Py_DECREF(oname);
6280 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006282
Victor Stinner8c62be82010-05-06 00:08:46 +00006283 Py_INCREF(Py_None);
6284 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006285}
Larry Hastings2f936352014-08-05 14:04:04 +10006286#endif /* HAVE_INITGROUPS */
6287
Antoine Pitroub7572f02009-12-02 20:46:48 +00006288
Martin v. Löwis606edc12002-06-13 21:09:11 +00006289#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006290/*[clinic input]
6291os.getpgid
6292
6293 pid: pid_t
6294
6295Call the system call getpgid(), and return the result.
6296[clinic start generated code]*/
6297
Larry Hastings2f936352014-08-05 14:04:04 +10006298static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006299os_getpgid_impl(PyObject *module, pid_t pid)
6300/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006301{
6302 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006303 if (pgid < 0)
6304 return posix_error();
6305 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006306}
6307#endif /* HAVE_GETPGID */
6308
6309
Guido van Rossumb6775db1994-08-01 11:34:53 +00006310#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006311/*[clinic input]
6312os.getpgrp
6313
6314Return the current process group id.
6315[clinic start generated code]*/
6316
Larry Hastings2f936352014-08-05 14:04:04 +10006317static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006318os_getpgrp_impl(PyObject *module)
6319/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006320{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006321#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006323#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006325#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006326}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006327#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006328
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006329
Guido van Rossumb6775db1994-08-01 11:34:53 +00006330#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006331/*[clinic input]
6332os.setpgrp
6333
6334Make the current process the leader of its process group.
6335[clinic start generated code]*/
6336
Larry Hastings2f936352014-08-05 14:04:04 +10006337static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006338os_setpgrp_impl(PyObject *module)
6339/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006340{
Guido van Rossum64933891994-10-20 21:56:42 +00006341#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006343#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006345#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006346 return posix_error();
6347 Py_INCREF(Py_None);
6348 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006349}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006350#endif /* HAVE_SETPGRP */
6351
Guido van Rossumad0ee831995-03-01 10:34:45 +00006352#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006353
6354#ifdef MS_WINDOWS
6355#include <tlhelp32.h>
6356
6357static PyObject*
6358win32_getppid()
6359{
6360 HANDLE snapshot;
6361 pid_t mypid;
6362 PyObject* result = NULL;
6363 BOOL have_record;
6364 PROCESSENTRY32 pe;
6365
6366 mypid = getpid(); /* This function never fails */
6367
6368 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6369 if (snapshot == INVALID_HANDLE_VALUE)
6370 return PyErr_SetFromWindowsErr(GetLastError());
6371
6372 pe.dwSize = sizeof(pe);
6373 have_record = Process32First(snapshot, &pe);
6374 while (have_record) {
6375 if (mypid == (pid_t)pe.th32ProcessID) {
6376 /* We could cache the ulong value in a static variable. */
6377 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6378 break;
6379 }
6380
6381 have_record = Process32Next(snapshot, &pe);
6382 }
6383
6384 /* If our loop exits and our pid was not found (result will be NULL)
6385 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6386 * error anyway, so let's raise it. */
6387 if (!result)
6388 result = PyErr_SetFromWindowsErr(GetLastError());
6389
6390 CloseHandle(snapshot);
6391
6392 return result;
6393}
6394#endif /*MS_WINDOWS*/
6395
Larry Hastings2f936352014-08-05 14:04:04 +10006396
6397/*[clinic input]
6398os.getppid
6399
6400Return the parent's process id.
6401
6402If the parent process has already exited, Windows machines will still
6403return its id; others systems will return the id of the 'init' process (1).
6404[clinic start generated code]*/
6405
Larry Hastings2f936352014-08-05 14:04:04 +10006406static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006407os_getppid_impl(PyObject *module)
6408/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006409{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006410#ifdef MS_WINDOWS
6411 return win32_getppid();
6412#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006413 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006414#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006415}
6416#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006417
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006418
Fred Drake12c6e2d1999-12-14 21:25:03 +00006419#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006420/*[clinic input]
6421os.getlogin
6422
6423Return the actual login name.
6424[clinic start generated code]*/
6425
Larry Hastings2f936352014-08-05 14:04:04 +10006426static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006427os_getlogin_impl(PyObject *module)
6428/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006429{
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006431#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006432 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006433 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006434
6435 if (GetUserNameW(user_name, &num_chars)) {
6436 /* num_chars is the number of unicode chars plus null terminator */
6437 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006438 }
6439 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006440 result = PyErr_SetFromWindowsErr(GetLastError());
6441#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006442 char *name;
6443 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006444
Victor Stinner8c62be82010-05-06 00:08:46 +00006445 errno = 0;
6446 name = getlogin();
6447 if (name == NULL) {
6448 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006449 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006450 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006451 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006452 }
6453 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006454 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006455 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006456#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006457 return result;
6458}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006459#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006460
Larry Hastings2f936352014-08-05 14:04:04 +10006461
Guido van Rossumad0ee831995-03-01 10:34:45 +00006462#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006463/*[clinic input]
6464os.getuid
6465
6466Return the current process's user id.
6467[clinic start generated code]*/
6468
Larry Hastings2f936352014-08-05 14:04:04 +10006469static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006470os_getuid_impl(PyObject *module)
6471/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006472{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006473 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006474}
Larry Hastings2f936352014-08-05 14:04:04 +10006475#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006476
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006477
Brian Curtineb24d742010-04-12 17:16:38 +00006478#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006479#define HAVE_KILL
6480#endif /* MS_WINDOWS */
6481
6482#ifdef HAVE_KILL
6483/*[clinic input]
6484os.kill
6485
6486 pid: pid_t
6487 signal: Py_ssize_t
6488 /
6489
6490Kill a process with a signal.
6491[clinic start generated code]*/
6492
Larry Hastings2f936352014-08-05 14:04:04 +10006493static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006494os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6495/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006496#ifndef MS_WINDOWS
6497{
6498 if (kill(pid, (int)signal) == -1)
6499 return posix_error();
6500 Py_RETURN_NONE;
6501}
6502#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006503{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006504 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006505 DWORD sig = (DWORD)signal;
6506 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006508
Victor Stinner8c62be82010-05-06 00:08:46 +00006509 /* Console processes which share a common console can be sent CTRL+C or
6510 CTRL+BREAK events, provided they handle said events. */
6511 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006512 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006513 err = GetLastError();
6514 PyErr_SetFromWindowsErr(err);
6515 }
6516 else
6517 Py_RETURN_NONE;
6518 }
Brian Curtineb24d742010-04-12 17:16:38 +00006519
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6521 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006522 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006523 if (handle == NULL) {
6524 err = GetLastError();
6525 return PyErr_SetFromWindowsErr(err);
6526 }
Brian Curtineb24d742010-04-12 17:16:38 +00006527
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 if (TerminateProcess(handle, sig) == 0) {
6529 err = GetLastError();
6530 result = PyErr_SetFromWindowsErr(err);
6531 } else {
6532 Py_INCREF(Py_None);
6533 result = Py_None;
6534 }
Brian Curtineb24d742010-04-12 17:16:38 +00006535
Victor Stinner8c62be82010-05-06 00:08:46 +00006536 CloseHandle(handle);
6537 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006538}
Larry Hastings2f936352014-08-05 14:04:04 +10006539#endif /* !MS_WINDOWS */
6540#endif /* HAVE_KILL */
6541
6542
6543#ifdef HAVE_KILLPG
6544/*[clinic input]
6545os.killpg
6546
6547 pgid: pid_t
6548 signal: int
6549 /
6550
6551Kill a process group with a signal.
6552[clinic start generated code]*/
6553
Larry Hastings2f936352014-08-05 14:04:04 +10006554static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006555os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6556/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006557{
6558 /* XXX some man pages make the `pgid` parameter an int, others
6559 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6560 take the same type. Moreover, pid_t is always at least as wide as
6561 int (else compilation of this module fails), which is safe. */
6562 if (killpg(pgid, signal) == -1)
6563 return posix_error();
6564 Py_RETURN_NONE;
6565}
6566#endif /* HAVE_KILLPG */
6567
Brian Curtineb24d742010-04-12 17:16:38 +00006568
Guido van Rossumc0125471996-06-28 18:55:32 +00006569#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006570#ifdef HAVE_SYS_LOCK_H
6571#include <sys/lock.h>
6572#endif
6573
Larry Hastings2f936352014-08-05 14:04:04 +10006574/*[clinic input]
6575os.plock
6576 op: int
6577 /
6578
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006579Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006580[clinic start generated code]*/
6581
Larry Hastings2f936352014-08-05 14:04:04 +10006582static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006583os_plock_impl(PyObject *module, int op)
6584/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006585{
Victor Stinner8c62be82010-05-06 00:08:46 +00006586 if (plock(op) == -1)
6587 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006588 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006589}
Larry Hastings2f936352014-08-05 14:04:04 +10006590#endif /* HAVE_PLOCK */
6591
Guido van Rossumc0125471996-06-28 18:55:32 +00006592
Guido van Rossumb6775db1994-08-01 11:34:53 +00006593#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006594/*[clinic input]
6595os.setuid
6596
6597 uid: uid_t
6598 /
6599
6600Set the current process's user id.
6601[clinic start generated code]*/
6602
Larry Hastings2f936352014-08-05 14:04:04 +10006603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006604os_setuid_impl(PyObject *module, uid_t uid)
6605/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006606{
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 if (setuid(uid) < 0)
6608 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006609 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006610}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006611#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006612
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006613
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006614#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006615/*[clinic input]
6616os.seteuid
6617
6618 euid: uid_t
6619 /
6620
6621Set the current process's effective user id.
6622[clinic start generated code]*/
6623
Larry Hastings2f936352014-08-05 14:04:04 +10006624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006625os_seteuid_impl(PyObject *module, uid_t euid)
6626/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006627{
6628 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006629 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006630 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006631}
6632#endif /* HAVE_SETEUID */
6633
Larry Hastings2f936352014-08-05 14:04:04 +10006634
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006635#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006636/*[clinic input]
6637os.setegid
6638
6639 egid: gid_t
6640 /
6641
6642Set the current process's effective group id.
6643[clinic start generated code]*/
6644
Larry Hastings2f936352014-08-05 14:04:04 +10006645static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006646os_setegid_impl(PyObject *module, gid_t egid)
6647/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006648{
6649 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006651 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006652}
6653#endif /* HAVE_SETEGID */
6654
Larry Hastings2f936352014-08-05 14:04:04 +10006655
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006656#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006657/*[clinic input]
6658os.setreuid
6659
6660 ruid: uid_t
6661 euid: uid_t
6662 /
6663
6664Set the current process's real and effective user ids.
6665[clinic start generated code]*/
6666
Larry Hastings2f936352014-08-05 14:04:04 +10006667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006668os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6669/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006670{
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 if (setreuid(ruid, euid) < 0) {
6672 return posix_error();
6673 } else {
6674 Py_INCREF(Py_None);
6675 return Py_None;
6676 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006677}
6678#endif /* HAVE_SETREUID */
6679
Larry Hastings2f936352014-08-05 14:04:04 +10006680
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006681#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006682/*[clinic input]
6683os.setregid
6684
6685 rgid: gid_t
6686 egid: gid_t
6687 /
6688
6689Set the current process's real and effective group ids.
6690[clinic start generated code]*/
6691
Larry Hastings2f936352014-08-05 14:04:04 +10006692static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006693os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6694/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006695{
6696 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006697 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006698 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006699}
6700#endif /* HAVE_SETREGID */
6701
Larry Hastings2f936352014-08-05 14:04:04 +10006702
Guido van Rossumb6775db1994-08-01 11:34:53 +00006703#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006704/*[clinic input]
6705os.setgid
6706 gid: gid_t
6707 /
6708
6709Set the current process's group id.
6710[clinic start generated code]*/
6711
Larry Hastings2f936352014-08-05 14:04:04 +10006712static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006713os_setgid_impl(PyObject *module, gid_t gid)
6714/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006715{
Victor Stinner8c62be82010-05-06 00:08:46 +00006716 if (setgid(gid) < 0)
6717 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006718 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006719}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006720#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006721
Larry Hastings2f936352014-08-05 14:04:04 +10006722
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006723#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006724/*[clinic input]
6725os.setgroups
6726
6727 groups: object
6728 /
6729
6730Set the groups of the current process to list.
6731[clinic start generated code]*/
6732
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006734os_setgroups(PyObject *module, PyObject *groups)
6735/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006736{
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 int i, len;
6738 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006739
Victor Stinner8c62be82010-05-06 00:08:46 +00006740 if (!PySequence_Check(groups)) {
6741 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6742 return NULL;
6743 }
6744 len = PySequence_Size(groups);
6745 if (len > MAX_GROUPS) {
6746 PyErr_SetString(PyExc_ValueError, "too many groups");
6747 return NULL;
6748 }
6749 for(i = 0; i < len; i++) {
6750 PyObject *elem;
6751 elem = PySequence_GetItem(groups, i);
6752 if (!elem)
6753 return NULL;
6754 if (!PyLong_Check(elem)) {
6755 PyErr_SetString(PyExc_TypeError,
6756 "groups must be integers");
6757 Py_DECREF(elem);
6758 return NULL;
6759 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006760 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 Py_DECREF(elem);
6762 return NULL;
6763 }
6764 }
6765 Py_DECREF(elem);
6766 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006767
Victor Stinner8c62be82010-05-06 00:08:46 +00006768 if (setgroups(len, grouplist) < 0)
6769 return posix_error();
6770 Py_INCREF(Py_None);
6771 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006772}
6773#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006774
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006775#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6776static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006777wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006778{
Victor Stinner8c62be82010-05-06 00:08:46 +00006779 PyObject *result;
6780 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006781 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006782
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 if (pid == -1)
6784 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006785
Victor Stinner8c62be82010-05-06 00:08:46 +00006786 if (struct_rusage == NULL) {
6787 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6788 if (m == NULL)
6789 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006790 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006791 Py_DECREF(m);
6792 if (struct_rusage == NULL)
6793 return NULL;
6794 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006795
Victor Stinner8c62be82010-05-06 00:08:46 +00006796 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6797 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6798 if (!result)
6799 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006800
6801#ifndef doubletime
6802#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6803#endif
6804
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006806 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006808 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006809#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6811 SET_INT(result, 2, ru->ru_maxrss);
6812 SET_INT(result, 3, ru->ru_ixrss);
6813 SET_INT(result, 4, ru->ru_idrss);
6814 SET_INT(result, 5, ru->ru_isrss);
6815 SET_INT(result, 6, ru->ru_minflt);
6816 SET_INT(result, 7, ru->ru_majflt);
6817 SET_INT(result, 8, ru->ru_nswap);
6818 SET_INT(result, 9, ru->ru_inblock);
6819 SET_INT(result, 10, ru->ru_oublock);
6820 SET_INT(result, 11, ru->ru_msgsnd);
6821 SET_INT(result, 12, ru->ru_msgrcv);
6822 SET_INT(result, 13, ru->ru_nsignals);
6823 SET_INT(result, 14, ru->ru_nvcsw);
6824 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825#undef SET_INT
6826
Victor Stinner8c62be82010-05-06 00:08:46 +00006827 if (PyErr_Occurred()) {
6828 Py_DECREF(result);
6829 return NULL;
6830 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006831
Victor Stinner8c62be82010-05-06 00:08:46 +00006832 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006833}
6834#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6835
Larry Hastings2f936352014-08-05 14:04:04 +10006836
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006837#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006838/*[clinic input]
6839os.wait3
6840
6841 options: int
6842Wait for completion of a child process.
6843
6844Returns a tuple of information about the child process:
6845 (pid, status, rusage)
6846[clinic start generated code]*/
6847
Larry Hastings2f936352014-08-05 14:04:04 +10006848static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006849os_wait3_impl(PyObject *module, int options)
6850/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006851{
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006854 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006855 WAIT_TYPE status;
6856 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006858 do {
6859 Py_BEGIN_ALLOW_THREADS
6860 pid = wait3(&status, options, &ru);
6861 Py_END_ALLOW_THREADS
6862 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6863 if (pid < 0)
6864 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865
Victor Stinner4195b5c2012-02-08 23:03:19 +01006866 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006867}
6868#endif /* HAVE_WAIT3 */
6869
Larry Hastings2f936352014-08-05 14:04:04 +10006870
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006871#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006872/*[clinic input]
6873
6874os.wait4
6875
6876 pid: pid_t
6877 options: int
6878
6879Wait for completion of a specific child process.
6880
6881Returns a tuple of information about the child process:
6882 (pid, status, rusage)
6883[clinic start generated code]*/
6884
Larry Hastings2f936352014-08-05 14:04:04 +10006885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006886os_wait4_impl(PyObject *module, pid_t pid, int options)
6887/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006888{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006889 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006891 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006892 WAIT_TYPE status;
6893 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006895 do {
6896 Py_BEGIN_ALLOW_THREADS
6897 res = wait4(pid, &status, options, &ru);
6898 Py_END_ALLOW_THREADS
6899 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6900 if (res < 0)
6901 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006903 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006904}
6905#endif /* HAVE_WAIT4 */
6906
Larry Hastings2f936352014-08-05 14:04:04 +10006907
Ross Lagerwall7807c352011-03-17 20:20:30 +02006908#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006909/*[clinic input]
6910os.waitid
6911
6912 idtype: idtype_t
6913 Must be one of be P_PID, P_PGID or P_ALL.
6914 id: id_t
6915 The id to wait on.
6916 options: int
6917 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6918 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6919 /
6920
6921Returns the result of waiting for a process or processes.
6922
6923Returns either waitid_result or None if WNOHANG is specified and there are
6924no children in a waitable state.
6925[clinic start generated code]*/
6926
Larry Hastings2f936352014-08-05 14:04:04 +10006927static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006928os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6929/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006930{
6931 PyObject *result;
6932 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006933 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006934 siginfo_t si;
6935 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006936
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006937 do {
6938 Py_BEGIN_ALLOW_THREADS
6939 res = waitid(idtype, id, &si, options);
6940 Py_END_ALLOW_THREADS
6941 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6942 if (res < 0)
6943 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006944
6945 if (si.si_pid == 0)
6946 Py_RETURN_NONE;
6947
6948 result = PyStructSequence_New(&WaitidResultType);
6949 if (!result)
6950 return NULL;
6951
6952 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006953 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006954 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6955 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6956 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6957 if (PyErr_Occurred()) {
6958 Py_DECREF(result);
6959 return NULL;
6960 }
6961
6962 return result;
6963}
Larry Hastings2f936352014-08-05 14:04:04 +10006964#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006965
Larry Hastings2f936352014-08-05 14:04:04 +10006966
6967#if defined(HAVE_WAITPID)
6968/*[clinic input]
6969os.waitpid
6970 pid: pid_t
6971 options: int
6972 /
6973
6974Wait for completion of a given child process.
6975
6976Returns a tuple of information regarding the child process:
6977 (pid, status)
6978
6979The options argument is ignored on Windows.
6980[clinic start generated code]*/
6981
Larry Hastings2f936352014-08-05 14:04:04 +10006982static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006983os_waitpid_impl(PyObject *module, pid_t pid, int options)
6984/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006985{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006986 pid_t res;
6987 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006988 WAIT_TYPE status;
6989 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006990
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006991 do {
6992 Py_BEGIN_ALLOW_THREADS
6993 res = waitpid(pid, &status, options);
6994 Py_END_ALLOW_THREADS
6995 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6996 if (res < 0)
6997 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006998
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006999 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007000}
Tim Petersab034fa2002-02-01 11:27:43 +00007001#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007002/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007003/*[clinic input]
7004os.waitpid
7005 pid: Py_intptr_t
7006 options: int
7007 /
7008
7009Wait for completion of a given process.
7010
7011Returns a tuple of information regarding the process:
7012 (pid, status << 8)
7013
7014The options argument is ignored on Windows.
7015[clinic start generated code]*/
7016
Larry Hastings2f936352014-08-05 14:04:04 +10007017static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007018os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7019/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007020{
7021 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007022 Py_intptr_t res;
7023 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007024
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007025 do {
7026 Py_BEGIN_ALLOW_THREADS
7027 res = _cwait(&status, pid, options);
7028 Py_END_ALLOW_THREADS
7029 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007030 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007031 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007032
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007034 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007035}
Larry Hastings2f936352014-08-05 14:04:04 +10007036#endif
7037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007038
Guido van Rossumad0ee831995-03-01 10:34:45 +00007039#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007040/*[clinic input]
7041os.wait
7042
7043Wait for completion of a child process.
7044
7045Returns a tuple of information about the child process:
7046 (pid, status)
7047[clinic start generated code]*/
7048
Larry Hastings2f936352014-08-05 14:04:04 +10007049static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007050os_wait_impl(PyObject *module)
7051/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007052{
Victor Stinner8c62be82010-05-06 00:08:46 +00007053 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007054 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007055 WAIT_TYPE status;
7056 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007057
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007058 do {
7059 Py_BEGIN_ALLOW_THREADS
7060 pid = wait(&status);
7061 Py_END_ALLOW_THREADS
7062 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7063 if (pid < 0)
7064 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007065
Victor Stinner8c62be82010-05-06 00:08:46 +00007066 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007067}
Larry Hastings2f936352014-08-05 14:04:04 +10007068#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007069
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007070
Larry Hastings9cf065c2012-06-22 16:30:09 -07007071#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7072PyDoc_STRVAR(readlink__doc__,
7073"readlink(path, *, dir_fd=None) -> path\n\n\
7074Return a string representing the path to which the symbolic link points.\n\
7075\n\
7076If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7077 and path should be relative; path will then be relative to that directory.\n\
7078dir_fd may not be implemented on your platform.\n\
7079 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007080#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007081
Guido van Rossumb6775db1994-08-01 11:34:53 +00007082#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007083
Larry Hastings2f936352014-08-05 14:04:04 +10007084/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007085static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007086posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007087{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007088 path_t path;
7089 int dir_fd = DEFAULT_DIR_FD;
7090 char buffer[MAXPATHLEN];
7091 ssize_t length;
7092 PyObject *return_value = NULL;
7093 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007094
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007096 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7098 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007099 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007101
Victor Stinner8c62be82010-05-06 00:08:46 +00007102 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007103#ifdef HAVE_READLINKAT
7104 if (dir_fd != DEFAULT_DIR_FD)
7105 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007106 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007107#endif
7108 length = readlink(path.narrow, buffer, sizeof(buffer));
7109 Py_END_ALLOW_THREADS
7110
7111 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007112 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007113 goto exit;
7114 }
7115
7116 if (PyUnicode_Check(path.object))
7117 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7118 else
7119 return_value = PyBytes_FromStringAndSize(buffer, length);
7120exit:
7121 path_cleanup(&path);
7122 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007123}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007124
Guido van Rossumb6775db1994-08-01 11:34:53 +00007125#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007126
Larry Hastings2f936352014-08-05 14:04:04 +10007127#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7128
7129static PyObject *
7130win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7131{
7132 wchar_t *path;
7133 DWORD n_bytes_returned;
7134 DWORD io_result;
7135 PyObject *po, *result;
7136 int dir_fd;
7137 HANDLE reparse_point_handle;
7138
7139 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7140 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7141 wchar_t *print_name;
7142
7143 static char *keywords[] = {"path", "dir_fd", NULL};
7144
7145 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7146 &po,
7147 dir_fd_unavailable, &dir_fd
7148 ))
7149 return NULL;
7150
7151 path = PyUnicode_AsUnicode(po);
7152 if (path == NULL)
7153 return NULL;
7154
7155 /* First get a handle to the reparse point */
7156 Py_BEGIN_ALLOW_THREADS
7157 reparse_point_handle = CreateFileW(
7158 path,
7159 0,
7160 0,
7161 0,
7162 OPEN_EXISTING,
7163 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7164 0);
7165 Py_END_ALLOW_THREADS
7166
7167 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7168 return win32_error_object("readlink", po);
7169
7170 Py_BEGIN_ALLOW_THREADS
7171 /* New call DeviceIoControl to read the reparse point */
7172 io_result = DeviceIoControl(
7173 reparse_point_handle,
7174 FSCTL_GET_REPARSE_POINT,
7175 0, 0, /* in buffer */
7176 target_buffer, sizeof(target_buffer),
7177 &n_bytes_returned,
7178 0 /* we're not using OVERLAPPED_IO */
7179 );
7180 CloseHandle(reparse_point_handle);
7181 Py_END_ALLOW_THREADS
7182
7183 if (io_result==0)
7184 return win32_error_object("readlink", po);
7185
7186 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7187 {
7188 PyErr_SetString(PyExc_ValueError,
7189 "not a symbolic link");
7190 return NULL;
7191 }
7192 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7193 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7194
7195 result = PyUnicode_FromWideChar(print_name,
7196 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7197 return result;
7198}
7199
7200#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7201
7202
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007203
Larry Hastings9cf065c2012-06-22 16:30:09 -07007204#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007205
7206#if defined(MS_WINDOWS)
7207
7208/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7209static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7210static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007211
Larry Hastings9cf065c2012-06-22 16:30:09 -07007212static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007213check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007214{
7215 HINSTANCE hKernel32;
7216 /* only recheck */
7217 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7218 return 1;
7219 hKernel32 = GetModuleHandleW(L"KERNEL32");
7220 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7221 "CreateSymbolicLinkW");
7222 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7223 "CreateSymbolicLinkA");
7224 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7225}
7226
Victor Stinner31b3b922013-06-05 01:49:17 +02007227/* Remove the last portion of the path */
7228static void
7229_dirnameW(WCHAR *path)
7230{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007231 WCHAR *ptr;
7232
7233 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007234 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007235 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007236 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007237 }
7238 *ptr = 0;
7239}
7240
Victor Stinner31b3b922013-06-05 01:49:17 +02007241/* Remove the last portion of the path */
7242static void
7243_dirnameA(char *path)
7244{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007245 char *ptr;
7246
7247 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007248 for(ptr = path + strlen(path); ptr != path; ptr--) {
7249 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007250 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007251 }
7252 *ptr = 0;
7253}
7254
Victor Stinner31b3b922013-06-05 01:49:17 +02007255/* Is this path absolute? */
7256static int
7257_is_absW(const WCHAR *path)
7258{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7260
7261}
7262
Victor Stinner31b3b922013-06-05 01:49:17 +02007263/* Is this path absolute? */
7264static int
7265_is_absA(const char *path)
7266{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007267 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7268
7269}
7270
Victor Stinner31b3b922013-06-05 01:49:17 +02007271/* join root and rest with a backslash */
7272static void
7273_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7274{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007275 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276
Victor Stinner31b3b922013-06-05 01:49:17 +02007277 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007278 wcscpy(dest_path, rest);
7279 return;
7280 }
7281
7282 root_len = wcslen(root);
7283
7284 wcscpy(dest_path, root);
7285 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007286 dest_path[root_len] = L'\\';
7287 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007288 }
7289 wcscpy(dest_path+root_len, rest);
7290}
7291
Victor Stinner31b3b922013-06-05 01:49:17 +02007292/* join root and rest with a backslash */
7293static void
7294_joinA(char *dest_path, const char *root, const char *rest)
7295{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007296 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297
Victor Stinner31b3b922013-06-05 01:49:17 +02007298 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007299 strcpy(dest_path, rest);
7300 return;
7301 }
7302
7303 root_len = strlen(root);
7304
7305 strcpy(dest_path, root);
7306 if(root_len) {
7307 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007308 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007309 }
7310 strcpy(dest_path+root_len, rest);
7311}
7312
Victor Stinner31b3b922013-06-05 01:49:17 +02007313/* Return True if the path at src relative to dest is a directory */
7314static int
7315_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007317 WIN32_FILE_ATTRIBUTE_DATA src_info;
7318 WCHAR dest_parent[MAX_PATH];
7319 WCHAR src_resolved[MAX_PATH] = L"";
7320
7321 /* dest_parent = os.path.dirname(dest) */
7322 wcscpy(dest_parent, dest);
7323 _dirnameW(dest_parent);
7324 /* src_resolved = os.path.join(dest_parent, src) */
7325 _joinW(src_resolved, dest_parent, src);
7326 return (
7327 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7328 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7329 );
7330}
7331
Victor Stinner31b3b922013-06-05 01:49:17 +02007332/* Return True if the path at src relative to dest is a directory */
7333static int
7334_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007335{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007336 WIN32_FILE_ATTRIBUTE_DATA src_info;
7337 char dest_parent[MAX_PATH];
7338 char src_resolved[MAX_PATH] = "";
7339
7340 /* dest_parent = os.path.dirname(dest) */
7341 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007342 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007343 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007344 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007345 return (
7346 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7347 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7348 );
7349}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007350#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007351
Larry Hastings2f936352014-08-05 14:04:04 +10007352
7353/*[clinic input]
7354os.symlink
7355 src: path_t
7356 dst: path_t
7357 target_is_directory: bool = False
7358 *
7359 dir_fd: dir_fd(requires='symlinkat')=None
7360
7361# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7362
7363Create a symbolic link pointing to src named dst.
7364
7365target_is_directory is required on Windows if the target is to be
7366 interpreted as a directory. (On Windows, symlink requires
7367 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7368 target_is_directory is ignored on non-Windows platforms.
7369
7370If dir_fd is not None, it should be a file descriptor open to a directory,
7371 and path should be relative; path will then be relative to that directory.
7372dir_fd may not be implemented on your platform.
7373 If it is unavailable, using it will raise a NotImplementedError.
7374
7375[clinic start generated code]*/
7376
Larry Hastings2f936352014-08-05 14:04:04 +10007377static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007378os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007379 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007380/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007381{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382#ifdef MS_WINDOWS
7383 DWORD result;
7384#else
7385 int result;
7386#endif
7387
Larry Hastings9cf065c2012-06-22 16:30:09 -07007388#ifdef MS_WINDOWS
7389 if (!check_CreateSymbolicLink()) {
7390 PyErr_SetString(PyExc_NotImplementedError,
7391 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007392 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007393 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007394 if (!win32_can_symlink) {
7395 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007396 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007397 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007398#endif
7399
Larry Hastings2f936352014-08-05 14:04:04 +10007400 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007401 PyErr_SetString(PyExc_ValueError,
7402 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007403 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007404 }
7405
7406#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007407
Larry Hastings9cf065c2012-06-22 16:30:09 -07007408 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007409 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007410 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007411 target_is_directory |= _check_dirW(src->wide, dst->wide);
7412 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007413 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007414 }
7415 else {
7416 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007417 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7418 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007420 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007421 Py_END_ALLOW_THREADS
7422
Larry Hastings2f936352014-08-05 14:04:04 +10007423 if (!result)
7424 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007425
7426#else
7427
7428 Py_BEGIN_ALLOW_THREADS
7429#if HAVE_SYMLINKAT
7430 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007431 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007432 else
7433#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007434 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007435 Py_END_ALLOW_THREADS
7436
Larry Hastings2f936352014-08-05 14:04:04 +10007437 if (result)
7438 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007439#endif
7440
Larry Hastings2f936352014-08-05 14:04:04 +10007441 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007442}
7443#endif /* HAVE_SYMLINK */
7444
Larry Hastings9cf065c2012-06-22 16:30:09 -07007445
Brian Curtind40e6f72010-07-08 21:39:08 +00007446
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007447
Larry Hastings605a62d2012-06-24 04:33:36 -07007448static PyStructSequence_Field times_result_fields[] = {
7449 {"user", "user time"},
7450 {"system", "system time"},
7451 {"children_user", "user time of children"},
7452 {"children_system", "system time of children"},
7453 {"elapsed", "elapsed time since an arbitrary point in the past"},
7454 {NULL}
7455};
7456
7457PyDoc_STRVAR(times_result__doc__,
7458"times_result: Result from os.times().\n\n\
7459This object may be accessed either as a tuple of\n\
7460 (user, system, children_user, children_system, elapsed),\n\
7461or via the attributes user, system, children_user, children_system,\n\
7462and elapsed.\n\
7463\n\
7464See os.times for more information.");
7465
7466static PyStructSequence_Desc times_result_desc = {
7467 "times_result", /* name */
7468 times_result__doc__, /* doc */
7469 times_result_fields,
7470 5
7471};
7472
7473static PyTypeObject TimesResultType;
7474
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007475#ifdef MS_WINDOWS
7476#define HAVE_TIMES /* mandatory, for the method table */
7477#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007478
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007479#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007480
7481static PyObject *
7482build_times_result(double user, double system,
7483 double children_user, double children_system,
7484 double elapsed)
7485{
7486 PyObject *value = PyStructSequence_New(&TimesResultType);
7487 if (value == NULL)
7488 return NULL;
7489
7490#define SET(i, field) \
7491 { \
7492 PyObject *o = PyFloat_FromDouble(field); \
7493 if (!o) { \
7494 Py_DECREF(value); \
7495 return NULL; \
7496 } \
7497 PyStructSequence_SET_ITEM(value, i, o); \
7498 } \
7499
7500 SET(0, user);
7501 SET(1, system);
7502 SET(2, children_user);
7503 SET(3, children_system);
7504 SET(4, elapsed);
7505
7506#undef SET
7507
7508 return value;
7509}
7510
Larry Hastings605a62d2012-06-24 04:33:36 -07007511
Larry Hastings2f936352014-08-05 14:04:04 +10007512#ifndef MS_WINDOWS
7513#define NEED_TICKS_PER_SECOND
7514static long ticks_per_second = -1;
7515#endif /* MS_WINDOWS */
7516
7517/*[clinic input]
7518os.times
7519
7520Return a collection containing process timing information.
7521
7522The object returned behaves like a named tuple with these fields:
7523 (utime, stime, cutime, cstime, elapsed_time)
7524All fields are floating point numbers.
7525[clinic start generated code]*/
7526
Larry Hastings2f936352014-08-05 14:04:04 +10007527static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007528os_times_impl(PyObject *module)
7529/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007530#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007531{
Victor Stinner8c62be82010-05-06 00:08:46 +00007532 FILETIME create, exit, kernel, user;
7533 HANDLE hProc;
7534 hProc = GetCurrentProcess();
7535 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7536 /* The fields of a FILETIME structure are the hi and lo part
7537 of a 64-bit value expressed in 100 nanosecond units.
7538 1e7 is one second in such units; 1e-7 the inverse.
7539 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7540 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007541 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007542 (double)(user.dwHighDateTime*429.4967296 +
7543 user.dwLowDateTime*1e-7),
7544 (double)(kernel.dwHighDateTime*429.4967296 +
7545 kernel.dwLowDateTime*1e-7),
7546 (double)0,
7547 (double)0,
7548 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007549}
Larry Hastings2f936352014-08-05 14:04:04 +10007550#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007551{
Larry Hastings2f936352014-08-05 14:04:04 +10007552
7553
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007554 struct tms t;
7555 clock_t c;
7556 errno = 0;
7557 c = times(&t);
7558 if (c == (clock_t) -1)
7559 return posix_error();
7560 return build_times_result(
7561 (double)t.tms_utime / ticks_per_second,
7562 (double)t.tms_stime / ticks_per_second,
7563 (double)t.tms_cutime / ticks_per_second,
7564 (double)t.tms_cstime / ticks_per_second,
7565 (double)c / ticks_per_second);
7566}
Larry Hastings2f936352014-08-05 14:04:04 +10007567#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007568#endif /* HAVE_TIMES */
7569
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007570
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007571#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007572/*[clinic input]
7573os.getsid
7574
7575 pid: pid_t
7576 /
7577
7578Call the system call getsid(pid) and return the result.
7579[clinic start generated code]*/
7580
Larry Hastings2f936352014-08-05 14:04:04 +10007581static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007582os_getsid_impl(PyObject *module, pid_t pid)
7583/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007584{
Victor Stinner8c62be82010-05-06 00:08:46 +00007585 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007586 sid = getsid(pid);
7587 if (sid < 0)
7588 return posix_error();
7589 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007590}
7591#endif /* HAVE_GETSID */
7592
7593
Guido van Rossumb6775db1994-08-01 11:34:53 +00007594#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007595/*[clinic input]
7596os.setsid
7597
7598Call the system call setsid().
7599[clinic start generated code]*/
7600
Larry Hastings2f936352014-08-05 14:04:04 +10007601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007602os_setsid_impl(PyObject *module)
7603/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007604{
Victor Stinner8c62be82010-05-06 00:08:46 +00007605 if (setsid() < 0)
7606 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007607 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007608}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007609#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007610
Larry Hastings2f936352014-08-05 14:04:04 +10007611
Guido van Rossumb6775db1994-08-01 11:34:53 +00007612#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007613/*[clinic input]
7614os.setpgid
7615
7616 pid: pid_t
7617 pgrp: pid_t
7618 /
7619
7620Call the system call setpgid(pid, pgrp).
7621[clinic start generated code]*/
7622
Larry Hastings2f936352014-08-05 14:04:04 +10007623static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007624os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7625/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007626{
Victor Stinner8c62be82010-05-06 00:08:46 +00007627 if (setpgid(pid, pgrp) < 0)
7628 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007629 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007630}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007631#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007632
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007633
Guido van Rossumb6775db1994-08-01 11:34:53 +00007634#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007635/*[clinic input]
7636os.tcgetpgrp
7637
7638 fd: int
7639 /
7640
7641Return the process group associated with the terminal specified by fd.
7642[clinic start generated code]*/
7643
Larry Hastings2f936352014-08-05 14:04:04 +10007644static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007645os_tcgetpgrp_impl(PyObject *module, int fd)
7646/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007647{
7648 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007649 if (pgid < 0)
7650 return posix_error();
7651 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007652}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007653#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007654
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007655
Guido van Rossumb6775db1994-08-01 11:34:53 +00007656#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007657/*[clinic input]
7658os.tcsetpgrp
7659
7660 fd: int
7661 pgid: pid_t
7662 /
7663
7664Set the process group associated with the terminal specified by fd.
7665[clinic start generated code]*/
7666
Larry Hastings2f936352014-08-05 14:04:04 +10007667static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007668os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7669/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007670{
Victor Stinner8c62be82010-05-06 00:08:46 +00007671 if (tcsetpgrp(fd, pgid) < 0)
7672 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007673 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007674}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007675#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007676
Guido van Rossum687dd131993-05-17 08:34:16 +00007677/* Functions acting on file descriptors */
7678
Victor Stinnerdaf45552013-08-28 00:53:59 +02007679#ifdef O_CLOEXEC
7680extern int _Py_open_cloexec_works;
7681#endif
7682
Larry Hastings2f936352014-08-05 14:04:04 +10007683
7684/*[clinic input]
7685os.open -> int
7686 path: path_t
7687 flags: int
7688 mode: int = 0o777
7689 *
7690 dir_fd: dir_fd(requires='openat') = None
7691
7692# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7693
7694Open a file for low level IO. Returns a file descriptor (integer).
7695
7696If dir_fd is not None, it should be a file descriptor open to a directory,
7697 and path should be relative; path will then be relative to that directory.
7698dir_fd may not be implemented on your platform.
7699 If it is unavailable, using it will raise a NotImplementedError.
7700[clinic start generated code]*/
7701
Larry Hastings2f936352014-08-05 14:04:04 +10007702static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007703os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7704/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007705{
7706 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007707 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007708
Victor Stinnerdaf45552013-08-28 00:53:59 +02007709#ifdef O_CLOEXEC
7710 int *atomic_flag_works = &_Py_open_cloexec_works;
7711#elif !defined(MS_WINDOWS)
7712 int *atomic_flag_works = NULL;
7713#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007714
Victor Stinnerdaf45552013-08-28 00:53:59 +02007715#ifdef MS_WINDOWS
7716 flags |= O_NOINHERIT;
7717#elif defined(O_CLOEXEC)
7718 flags |= O_CLOEXEC;
7719#endif
7720
Steve Dower8fc89802015-04-12 00:26:27 -04007721 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007722 do {
7723 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007724#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007725 if (path->wide)
7726 fd = _wopen(path->wide, flags, mode);
7727 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007728#endif
7729#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007730 if (dir_fd != DEFAULT_DIR_FD)
7731 fd = openat(dir_fd, path->narrow, flags, mode);
7732 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007733#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007734 fd = open(path->narrow, flags, mode);
7735 Py_END_ALLOW_THREADS
7736 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007737 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007738
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007739 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007740 if (!async_err)
7741 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007742 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 }
7744
Victor Stinnerdaf45552013-08-28 00:53:59 +02007745#ifndef MS_WINDOWS
7746 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7747 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007748 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007749 }
7750#endif
7751
Larry Hastings2f936352014-08-05 14:04:04 +10007752 return fd;
7753}
7754
7755
7756/*[clinic input]
7757os.close
7758
7759 fd: int
7760
7761Close a file descriptor.
7762[clinic start generated code]*/
7763
Barry Warsaw53699e91996-12-10 23:23:01 +00007764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007765os_close_impl(PyObject *module, int fd)
7766/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007767{
Larry Hastings2f936352014-08-05 14:04:04 +10007768 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 if (!_PyVerify_fd(fd))
7770 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007771 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7772 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7773 * for more details.
7774 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007776 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007778 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 Py_END_ALLOW_THREADS
7780 if (res < 0)
7781 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007782 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007783}
7784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007785
Larry Hastings2f936352014-08-05 14:04:04 +10007786/*[clinic input]
7787os.closerange
7788
7789 fd_low: int
7790 fd_high: int
7791 /
7792
7793Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7794[clinic start generated code]*/
7795
Larry Hastings2f936352014-08-05 14:04:04 +10007796static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007797os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7798/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007799{
7800 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007802 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007803 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 if (_PyVerify_fd(i))
7805 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007806 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 Py_END_ALLOW_THREADS
7808 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007809}
7810
7811
Larry Hastings2f936352014-08-05 14:04:04 +10007812/*[clinic input]
7813os.dup -> int
7814
7815 fd: int
7816 /
7817
7818Return a duplicate of a file descriptor.
7819[clinic start generated code]*/
7820
Larry Hastings2f936352014-08-05 14:04:04 +10007821static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007822os_dup_impl(PyObject *module, int fd)
7823/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007824{
7825 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007826}
7827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007828
Larry Hastings2f936352014-08-05 14:04:04 +10007829/*[clinic input]
7830os.dup2
7831 fd: int
7832 fd2: int
7833 inheritable: bool=True
7834
7835Duplicate file descriptor.
7836[clinic start generated code]*/
7837
Larry Hastings2f936352014-08-05 14:04:04 +10007838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007839os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7840/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007841{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007842 int res;
7843#if defined(HAVE_DUP3) && \
7844 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7845 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7846 int dup3_works = -1;
7847#endif
7848
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 if (!_PyVerify_fd_dup2(fd, fd2))
7850 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007851
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007852 /* dup2() can fail with EINTR if the target FD is already open, because it
7853 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7854 * upon close(), and therefore below.
7855 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856#ifdef MS_WINDOWS
7857 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007858 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007860 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007861 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 if (res < 0)
7863 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007864
7865 /* Character files like console cannot be make non-inheritable */
7866 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7867 close(fd2);
7868 return NULL;
7869 }
7870
7871#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7872 Py_BEGIN_ALLOW_THREADS
7873 if (!inheritable)
7874 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7875 else
7876 res = dup2(fd, fd2);
7877 Py_END_ALLOW_THREADS
7878 if (res < 0)
7879 return posix_error();
7880
7881#else
7882
7883#ifdef HAVE_DUP3
7884 if (!inheritable && dup3_works != 0) {
7885 Py_BEGIN_ALLOW_THREADS
7886 res = dup3(fd, fd2, O_CLOEXEC);
7887 Py_END_ALLOW_THREADS
7888 if (res < 0) {
7889 if (dup3_works == -1)
7890 dup3_works = (errno != ENOSYS);
7891 if (dup3_works)
7892 return posix_error();
7893 }
7894 }
7895
7896 if (inheritable || dup3_works == 0)
7897 {
7898#endif
7899 Py_BEGIN_ALLOW_THREADS
7900 res = dup2(fd, fd2);
7901 Py_END_ALLOW_THREADS
7902 if (res < 0)
7903 return posix_error();
7904
7905 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7906 close(fd2);
7907 return NULL;
7908 }
7909#ifdef HAVE_DUP3
7910 }
7911#endif
7912
7913#endif
7914
Larry Hastings2f936352014-08-05 14:04:04 +10007915 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007916}
7917
Larry Hastings2f936352014-08-05 14:04:04 +10007918
Ross Lagerwall7807c352011-03-17 20:20:30 +02007919#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007920/*[clinic input]
7921os.lockf
7922
7923 fd: int
7924 An open file descriptor.
7925 command: int
7926 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7927 length: Py_off_t
7928 The number of bytes to lock, starting at the current position.
7929 /
7930
7931Apply, test or remove a POSIX lock on an open file descriptor.
7932
7933[clinic start generated code]*/
7934
Larry Hastings2f936352014-08-05 14:04:04 +10007935static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007936os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7937/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007938{
7939 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940
7941 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007942 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007943 Py_END_ALLOW_THREADS
7944
7945 if (res < 0)
7946 return posix_error();
7947
7948 Py_RETURN_NONE;
7949}
Larry Hastings2f936352014-08-05 14:04:04 +10007950#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007952
Larry Hastings2f936352014-08-05 14:04:04 +10007953/*[clinic input]
7954os.lseek -> Py_off_t
7955
7956 fd: int
7957 position: Py_off_t
7958 how: int
7959 /
7960
7961Set the position of a file descriptor. Return the new position.
7962
7963Return the new cursor position in number of bytes
7964relative to the beginning of the file.
7965[clinic start generated code]*/
7966
Larry Hastings2f936352014-08-05 14:04:04 +10007967static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007968os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7969/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007970{
7971 Py_off_t result;
7972
7973 if (!_PyVerify_fd(fd)) {
7974 posix_error();
7975 return -1;
7976 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007977#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7979 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007980 case 0: how = SEEK_SET; break;
7981 case 1: how = SEEK_CUR; break;
7982 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007984#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007985
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007987 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007988
Larry Hastings2f936352014-08-05 14:04:04 +10007989 if (!_PyVerify_fd(fd)) {
7990 posix_error();
7991 return -1;
7992 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007994 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007995#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007996 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007997#else
Larry Hastings2f936352014-08-05 14:04:04 +10007998 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007999#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008000 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008002 if (result < 0)
8003 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008004
Larry Hastings2f936352014-08-05 14:04:04 +10008005 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008006}
8007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008008
Larry Hastings2f936352014-08-05 14:04:04 +10008009/*[clinic input]
8010os.read
8011 fd: int
8012 length: Py_ssize_t
8013 /
8014
8015Read from a file descriptor. Returns a bytes object.
8016[clinic start generated code]*/
8017
Larry Hastings2f936352014-08-05 14:04:04 +10008018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008019os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8020/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008021{
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 Py_ssize_t n;
8023 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008024
8025 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 errno = EINVAL;
8027 return posix_error();
8028 }
Larry Hastings2f936352014-08-05 14:04:04 +10008029
8030#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008031 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008032 if (length > INT_MAX)
8033 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008034#endif
8035
8036 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 if (buffer == NULL)
8038 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008039
Victor Stinner66aab0c2015-03-19 22:53:20 +01008040 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8041 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008043 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 }
Larry Hastings2f936352014-08-05 14:04:04 +10008045
8046 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008048
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008050}
8051
Ross Lagerwall7807c352011-03-17 20:20:30 +02008052#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8053 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008054static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8056{
8057 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008058 Py_ssize_t blen, total = 0;
8059
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008060 *iov = PyMem_New(struct iovec, cnt);
8061 if (*iov == NULL) {
8062 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008063 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008065
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 *buf = PyMem_New(Py_buffer, cnt);
8067 if (*buf == NULL) {
8068 PyMem_Del(*iov);
8069 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008070 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071 }
8072
8073 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008074 PyObject *item = PySequence_GetItem(seq, i);
8075 if (item == NULL)
8076 goto fail;
8077 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8078 Py_DECREF(item);
8079 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008081 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008082 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008083 blen = (*buf)[i].len;
8084 (*iov)[i].iov_len = blen;
8085 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008087 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008088
8089fail:
8090 PyMem_Del(*iov);
8091 for (j = 0; j < i; j++) {
8092 PyBuffer_Release(&(*buf)[j]);
8093 }
8094 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008095 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008096}
8097
8098static void
8099iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8100{
8101 int i;
8102 PyMem_Del(iov);
8103 for (i = 0; i < cnt; i++) {
8104 PyBuffer_Release(&buf[i]);
8105 }
8106 PyMem_Del(buf);
8107}
8108#endif
8109
Larry Hastings2f936352014-08-05 14:04:04 +10008110
Ross Lagerwall7807c352011-03-17 20:20:30 +02008111#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008112/*[clinic input]
8113os.readv -> Py_ssize_t
8114
8115 fd: int
8116 buffers: object
8117 /
8118
8119Read from a file descriptor fd into an iterable of buffers.
8120
8121The buffers should be mutable buffers accepting bytes.
8122readv will transfer data into each buffer until it is full
8123and then move on to the next buffer in the sequence to hold
8124the rest of the data.
8125
8126readv returns the total number of bytes read,
8127which may be less than the total capacity of all the buffers.
8128[clinic start generated code]*/
8129
Larry Hastings2f936352014-08-05 14:04:04 +10008130static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008131os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8132/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008133{
8134 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008135 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008137 struct iovec *iov;
8138 Py_buffer *buf;
8139
Larry Hastings2f936352014-08-05 14:04:04 +10008140 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008141 PyErr_SetString(PyExc_TypeError,
8142 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008143 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145
Larry Hastings2f936352014-08-05 14:04:04 +10008146 cnt = PySequence_Size(buffers);
8147
8148 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8149 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008151 do {
8152 Py_BEGIN_ALLOW_THREADS
8153 n = readv(fd, iov, cnt);
8154 Py_END_ALLOW_THREADS
8155 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008156
8157 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008158 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008159 if (!async_err)
8160 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008161 return -1;
8162 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008163
Larry Hastings2f936352014-08-05 14:04:04 +10008164 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008165}
Larry Hastings2f936352014-08-05 14:04:04 +10008166#endif /* HAVE_READV */
8167
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168
8169#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008170/*[clinic input]
8171# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8172os.pread
8173
8174 fd: int
8175 length: int
8176 offset: Py_off_t
8177 /
8178
8179Read a number of bytes from a file descriptor starting at a particular offset.
8180
8181Read length bytes from file descriptor fd, starting at offset bytes from
8182the beginning of the file. The file offset remains unchanged.
8183[clinic start generated code]*/
8184
Larry Hastings2f936352014-08-05 14:04:04 +10008185static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008186os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8187/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008188{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008190 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192
Larry Hastings2f936352014-08-05 14:04:04 +10008193 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194 errno = EINVAL;
8195 return posix_error();
8196 }
Larry Hastings2f936352014-08-05 14:04:04 +10008197 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008198 if (buffer == NULL)
8199 return NULL;
8200 if (!_PyVerify_fd(fd)) {
8201 Py_DECREF(buffer);
8202 return posix_error();
8203 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008204
8205 do {
8206 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008207 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008208 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008209 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008210 Py_END_ALLOW_THREADS
8211 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8212
Ross Lagerwall7807c352011-03-17 20:20:30 +02008213 if (n < 0) {
8214 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008215 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216 }
Larry Hastings2f936352014-08-05 14:04:04 +10008217 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008218 _PyBytes_Resize(&buffer, n);
8219 return buffer;
8220}
Larry Hastings2f936352014-08-05 14:04:04 +10008221#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008222
Larry Hastings2f936352014-08-05 14:04:04 +10008223
8224/*[clinic input]
8225os.write -> Py_ssize_t
8226
8227 fd: int
8228 data: Py_buffer
8229 /
8230
8231Write a bytes object to a file descriptor.
8232[clinic start generated code]*/
8233
Larry Hastings2f936352014-08-05 14:04:04 +10008234static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008235os_write_impl(PyObject *module, int fd, Py_buffer *data)
8236/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008237{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008238 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008239}
8240
8241#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008243"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008244sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008246Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247
Larry Hastings2f936352014-08-05 14:04:04 +10008248/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008249static PyObject *
8250posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8251{
8252 int in, out;
8253 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008254 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 off_t offset;
8256
8257#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8258#ifndef __APPLE__
8259 Py_ssize_t len;
8260#endif
8261 PyObject *headers = NULL, *trailers = NULL;
8262 Py_buffer *hbuf, *tbuf;
8263 off_t sbytes;
8264 struct sf_hdtr sf;
8265 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008266 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008267 static char *keywords[] = {"out", "in",
8268 "offset", "count",
8269 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008270
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008271 sf.headers = NULL;
8272 sf.trailers = NULL;
8273
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008274#ifdef __APPLE__
8275 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008276 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008277#else
8278 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008279 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280#endif
8281 &headers, &trailers, &flags))
8282 return NULL;
8283 if (headers != NULL) {
8284 if (!PySequence_Check(headers)) {
8285 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008286 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008287 return NULL;
8288 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008289 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008290 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008291 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008292 (i = iov_setup(&(sf.headers), &hbuf,
8293 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008294 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008295#ifdef __APPLE__
8296 sbytes += i;
8297#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008298 }
8299 }
8300 if (trailers != NULL) {
8301 if (!PySequence_Check(trailers)) {
8302 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008303 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 return NULL;
8305 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008306 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008308 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008309 (i = iov_setup(&(sf.trailers), &tbuf,
8310 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008312#ifdef __APPLE__
8313 sbytes += i;
8314#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315 }
8316 }
8317
Steve Dower8fc89802015-04-12 00:26:27 -04008318 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 do {
8320 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008326 Py_END_ALLOW_THREADS
8327 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008328 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329
8330 if (sf.headers != NULL)
8331 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8332 if (sf.trailers != NULL)
8333 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8334
8335 if (ret < 0) {
8336 if ((errno == EAGAIN) || (errno == EBUSY)) {
8337 if (sbytes != 0) {
8338 // some data has been sent
8339 goto done;
8340 }
8341 else {
8342 // no data has been sent; upper application is supposed
8343 // to retry on EAGAIN or EBUSY
8344 return posix_error();
8345 }
8346 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008347 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348 }
8349 goto done;
8350
8351done:
8352 #if !defined(HAVE_LARGEFILE_SUPPORT)
8353 return Py_BuildValue("l", sbytes);
8354 #else
8355 return Py_BuildValue("L", sbytes);
8356 #endif
8357
8358#else
8359 Py_ssize_t count;
8360 PyObject *offobj;
8361 static char *keywords[] = {"out", "in",
8362 "offset", "count", NULL};
8363 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8364 keywords, &out, &in, &offobj, &count))
8365 return NULL;
8366#ifdef linux
8367 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008368 do {
8369 Py_BEGIN_ALLOW_THREADS
8370 ret = sendfile(out, in, NULL, count);
8371 Py_END_ALLOW_THREADS
8372 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008373 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008374 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008375 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008376 }
8377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008378 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008379 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008380
8381 do {
8382 Py_BEGIN_ALLOW_THREADS
8383 ret = sendfile(out, in, &offset, count);
8384 Py_END_ALLOW_THREADS
8385 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008387 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008388 return Py_BuildValue("n", ret);
8389#endif
8390}
Larry Hastings2f936352014-08-05 14:04:04 +10008391#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008392
Larry Hastings2f936352014-08-05 14:04:04 +10008393
8394/*[clinic input]
8395os.fstat
8396
8397 fd : int
8398
8399Perform a stat system call on the given file descriptor.
8400
8401Like stat(), but for an open file descriptor.
8402Equivalent to os.stat(fd).
8403[clinic start generated code]*/
8404
Larry Hastings2f936352014-08-05 14:04:04 +10008405static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008406os_fstat_impl(PyObject *module, int fd)
8407/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008408{
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 STRUCT_STAT st;
8410 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008412
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008413 do {
8414 Py_BEGIN_ALLOW_THREADS
8415 res = FSTAT(fd, &st);
8416 Py_END_ALLOW_THREADS
8417 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008419#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008420 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008421#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008423#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 }
Tim Peters5aa91602002-01-30 05:46:57 +00008425
Victor Stinner4195b5c2012-02-08 23:03:19 +01008426 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008427}
8428
Larry Hastings2f936352014-08-05 14:04:04 +10008429
8430/*[clinic input]
8431os.isatty -> bool
8432 fd: int
8433 /
8434
8435Return True if the fd is connected to a terminal.
8436
8437Return True if the file descriptor is an open file descriptor
8438connected to the slave end of a terminal.
8439[clinic start generated code]*/
8440
Larry Hastings2f936352014-08-05 14:04:04 +10008441static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008442os_isatty_impl(PyObject *module, int fd)
8443/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008444{
Steve Dower8fc89802015-04-12 00:26:27 -04008445 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008446 if (!_PyVerify_fd(fd))
8447 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008448 _Py_BEGIN_SUPPRESS_IPH
8449 return_value = isatty(fd);
8450 _Py_END_SUPPRESS_IPH
8451 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008452}
8453
8454
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008455#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008456/*[clinic input]
8457os.pipe
8458
8459Create a pipe.
8460
8461Returns a tuple of two file descriptors:
8462 (read_fd, write_fd)
8463[clinic start generated code]*/
8464
Larry Hastings2f936352014-08-05 14:04:04 +10008465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008466os_pipe_impl(PyObject *module)
8467/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008468{
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008470#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008471 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008472 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008474#else
8475 int res;
8476#endif
8477
8478#ifdef MS_WINDOWS
8479 attr.nLength = sizeof(attr);
8480 attr.lpSecurityDescriptor = NULL;
8481 attr.bInheritHandle = FALSE;
8482
8483 Py_BEGIN_ALLOW_THREADS
8484 ok = CreatePipe(&read, &write, &attr, 0);
8485 if (ok) {
8486 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8487 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8488 if (fds[0] == -1 || fds[1] == -1) {
8489 CloseHandle(read);
8490 CloseHandle(write);
8491 ok = 0;
8492 }
8493 }
8494 Py_END_ALLOW_THREADS
8495
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008497 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008498#else
8499
8500#ifdef HAVE_PIPE2
8501 Py_BEGIN_ALLOW_THREADS
8502 res = pipe2(fds, O_CLOEXEC);
8503 Py_END_ALLOW_THREADS
8504
8505 if (res != 0 && errno == ENOSYS)
8506 {
8507#endif
8508 Py_BEGIN_ALLOW_THREADS
8509 res = pipe(fds);
8510 Py_END_ALLOW_THREADS
8511
8512 if (res == 0) {
8513 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8514 close(fds[0]);
8515 close(fds[1]);
8516 return NULL;
8517 }
8518 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8519 close(fds[0]);
8520 close(fds[1]);
8521 return NULL;
8522 }
8523 }
8524#ifdef HAVE_PIPE2
8525 }
8526#endif
8527
8528 if (res != 0)
8529 return PyErr_SetFromErrno(PyExc_OSError);
8530#endif /* !MS_WINDOWS */
8531 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008532}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008533#endif /* HAVE_PIPE */
8534
Larry Hastings2f936352014-08-05 14:04:04 +10008535
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008536#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008537/*[clinic input]
8538os.pipe2
8539
8540 flags: int
8541 /
8542
8543Create a pipe with flags set atomically.
8544
8545Returns a tuple of two file descriptors:
8546 (read_fd, write_fd)
8547
8548flags can be constructed by ORing together one or more of these values:
8549O_NONBLOCK, O_CLOEXEC.
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008553os_pipe2_impl(PyObject *module, int flags)
8554/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008555{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008556 int fds[2];
8557 int res;
8558
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008559 res = pipe2(fds, flags);
8560 if (res != 0)
8561 return posix_error();
8562 return Py_BuildValue("(ii)", fds[0], fds[1]);
8563}
8564#endif /* HAVE_PIPE2 */
8565
Larry Hastings2f936352014-08-05 14:04:04 +10008566
Ross Lagerwall7807c352011-03-17 20:20:30 +02008567#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008568/*[clinic input]
8569os.writev -> Py_ssize_t
8570 fd: int
8571 buffers: object
8572 /
8573
8574Iterate over buffers, and write the contents of each to a file descriptor.
8575
8576Returns the total number of bytes written.
8577buffers must be a sequence of bytes-like objects.
8578[clinic start generated code]*/
8579
Larry Hastings2f936352014-08-05 14:04:04 +10008580static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008581os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8582/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008583{
8584 int cnt;
8585 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008586 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008587 struct iovec *iov;
8588 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008589
8590 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008591 PyErr_SetString(PyExc_TypeError,
8592 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008593 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594 }
Larry Hastings2f936352014-08-05 14:04:04 +10008595 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008596
Larry Hastings2f936352014-08-05 14:04:04 +10008597 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8598 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008599 }
8600
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008601 do {
8602 Py_BEGIN_ALLOW_THREADS
8603 result = writev(fd, iov, cnt);
8604 Py_END_ALLOW_THREADS
8605 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008606
8607 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008608 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008609 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008610
Georg Brandl306336b2012-06-24 12:55:33 +02008611 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008612}
Larry Hastings2f936352014-08-05 14:04:04 +10008613#endif /* HAVE_WRITEV */
8614
8615
8616#ifdef HAVE_PWRITE
8617/*[clinic input]
8618os.pwrite -> Py_ssize_t
8619
8620 fd: int
8621 buffer: Py_buffer
8622 offset: Py_off_t
8623 /
8624
8625Write bytes to a file descriptor starting at a particular offset.
8626
8627Write buffer to fd, starting at offset bytes from the beginning of
8628the file. Returns the number of bytes writte. Does not change the
8629current file offset.
8630[clinic start generated code]*/
8631
Larry Hastings2f936352014-08-05 14:04:04 +10008632static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008633os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8634/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008635{
8636 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008637 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008638
8639 if (!_PyVerify_fd(fd)) {
8640 posix_error();
8641 return -1;
8642 }
8643
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008644 do {
8645 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008646 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008647 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008648 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008649 Py_END_ALLOW_THREADS
8650 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008651
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008652 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008653 posix_error();
8654 return size;
8655}
8656#endif /* HAVE_PWRITE */
8657
8658
8659#ifdef HAVE_MKFIFO
8660/*[clinic input]
8661os.mkfifo
8662
8663 path: path_t
8664 mode: int=0o666
8665 *
8666 dir_fd: dir_fd(requires='mkfifoat')=None
8667
8668Create a "fifo" (a POSIX named pipe).
8669
8670If dir_fd is not None, it should be a file descriptor open to a directory,
8671 and path should be relative; path will then be relative to that directory.
8672dir_fd may not be implemented on your platform.
8673 If it is unavailable, using it will raise a NotImplementedError.
8674[clinic start generated code]*/
8675
Larry Hastings2f936352014-08-05 14:04:04 +10008676static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008677os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8678/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008679{
8680 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008681 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008682
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008683 do {
8684 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008685#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686 if (dir_fd != DEFAULT_DIR_FD)
8687 result = mkfifoat(dir_fd, path->narrow, mode);
8688 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008689#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008690 result = mkfifo(path->narrow, mode);
8691 Py_END_ALLOW_THREADS
8692 } while (result != 0 && errno == EINTR &&
8693 !(async_err = PyErr_CheckSignals()));
8694 if (result != 0)
8695 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008696
8697 Py_RETURN_NONE;
8698}
8699#endif /* HAVE_MKFIFO */
8700
8701
8702#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8703/*[clinic input]
8704os.mknod
8705
8706 path: path_t
8707 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008708 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008709 *
8710 dir_fd: dir_fd(requires='mknodat')=None
8711
8712Create a node in the file system.
8713
8714Create a node in the file system (file, device special file or named pipe)
8715at path. mode specifies both the permissions to use and the
8716type of node to be created, being combined (bitwise OR) with one of
8717S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8718device defines the newly created device special file (probably using
8719os.makedev()). Otherwise device is ignored.
8720
8721If dir_fd is not None, it should be a file descriptor open to a directory,
8722 and path should be relative; path will then be relative to that directory.
8723dir_fd may not be implemented on your platform.
8724 If it is unavailable, using it will raise a NotImplementedError.
8725[clinic start generated code]*/
8726
Larry Hastings2f936352014-08-05 14:04:04 +10008727static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008728os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008729 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008730/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008731{
8732 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008733 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008734
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008735 do {
8736 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008737#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008738 if (dir_fd != DEFAULT_DIR_FD)
8739 result = mknodat(dir_fd, path->narrow, mode, device);
8740 else
Larry Hastings2f936352014-08-05 14:04:04 +10008741#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008742 result = mknod(path->narrow, mode, device);
8743 Py_END_ALLOW_THREADS
8744 } while (result != 0 && errno == EINTR &&
8745 !(async_err = PyErr_CheckSignals()));
8746 if (result != 0)
8747 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008748
8749 Py_RETURN_NONE;
8750}
8751#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8752
8753
8754#ifdef HAVE_DEVICE_MACROS
8755/*[clinic input]
8756os.major -> unsigned_int
8757
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008758 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008759 /
8760
8761Extracts a device major number from a raw device number.
8762[clinic start generated code]*/
8763
Larry Hastings2f936352014-08-05 14:04:04 +10008764static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008765os_major_impl(PyObject *module, dev_t device)
8766/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008767{
8768 return major(device);
8769}
8770
8771
8772/*[clinic input]
8773os.minor -> unsigned_int
8774
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008775 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008776 /
8777
8778Extracts a device minor number from a raw device number.
8779[clinic start generated code]*/
8780
Larry Hastings2f936352014-08-05 14:04:04 +10008781static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008782os_minor_impl(PyObject *module, dev_t device)
8783/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008784{
8785 return minor(device);
8786}
8787
8788
8789/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008790os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008791
8792 major: int
8793 minor: int
8794 /
8795
8796Composes a raw device number from the major and minor device numbers.
8797[clinic start generated code]*/
8798
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008799static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008800os_makedev_impl(PyObject *module, int major, int minor)
8801/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008802{
8803 return makedev(major, minor);
8804}
8805#endif /* HAVE_DEVICE_MACROS */
8806
8807
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008808#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008809/*[clinic input]
8810os.ftruncate
8811
8812 fd: int
8813 length: Py_off_t
8814 /
8815
8816Truncate a file, specified by file descriptor, to a specific length.
8817[clinic start generated code]*/
8818
Larry Hastings2f936352014-08-05 14:04:04 +10008819static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008820os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8821/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008822{
8823 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008824 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008825
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008826 if (!_PyVerify_fd(fd))
8827 return posix_error();
8828
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008829 do {
8830 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008831 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008832#ifdef MS_WINDOWS
8833 result = _chsize_s(fd, length);
8834#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008835 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008836#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008837 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008838 Py_END_ALLOW_THREADS
8839 } while (result != 0 && errno == EINTR &&
8840 !(async_err = PyErr_CheckSignals()));
8841 if (result != 0)
8842 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008843 Py_RETURN_NONE;
8844}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008845#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008846
8847
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008848#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008849/*[clinic input]
8850os.truncate
8851 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8852 length: Py_off_t
8853
8854Truncate a file, specified by path, to a specific length.
8855
8856On some platforms, path may also be specified as an open file descriptor.
8857 If this functionality is unavailable, using it raises an exception.
8858[clinic start generated code]*/
8859
Larry Hastings2f936352014-08-05 14:04:04 +10008860static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008861os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8862/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008863{
8864 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008865#ifdef MS_WINDOWS
8866 int fd;
8867#endif
8868
8869 if (path->fd != -1)
8870 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008871
8872 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008873 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008874#ifdef MS_WINDOWS
8875 if (path->wide)
8876 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008877 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008878 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008879 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008880 result = -1;
8881 else {
8882 result = _chsize_s(fd, length);
8883 close(fd);
8884 if (result < 0)
8885 errno = result;
8886 }
8887#else
8888 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008889#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008890 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008891 Py_END_ALLOW_THREADS
8892 if (result < 0)
8893 return path_error(path);
8894
8895 Py_RETURN_NONE;
8896}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008897#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008898
Ross Lagerwall7807c352011-03-17 20:20:30 +02008899
Victor Stinnerd6b17692014-09-30 12:20:05 +02008900/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8901 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8902 defined, which is the case in Python on AIX. AIX bug report:
8903 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8904#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8905# define POSIX_FADVISE_AIX_BUG
8906#endif
8907
Victor Stinnerec39e262014-09-30 12:35:58 +02008908
Victor Stinnerd6b17692014-09-30 12:20:05 +02008909#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008910/*[clinic input]
8911os.posix_fallocate
8912
8913 fd: int
8914 offset: Py_off_t
8915 length: Py_off_t
8916 /
8917
8918Ensure a file has allocated at least a particular number of bytes on disk.
8919
8920Ensure that the file specified by fd encompasses a range of bytes
8921starting at offset bytes from the beginning and continuing for length bytes.
8922[clinic start generated code]*/
8923
Larry Hastings2f936352014-08-05 14:04:04 +10008924static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008925os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008926 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008927/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008928{
8929 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008930 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008931
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008932 do {
8933 Py_BEGIN_ALLOW_THREADS
8934 result = posix_fallocate(fd, offset, length);
8935 Py_END_ALLOW_THREADS
8936 } while (result != 0 && errno == EINTR &&
8937 !(async_err = PyErr_CheckSignals()));
8938 if (result != 0)
8939 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008940 Py_RETURN_NONE;
8941}
Victor Stinnerec39e262014-09-30 12:35:58 +02008942#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008943
Ross Lagerwall7807c352011-03-17 20:20:30 +02008944
Victor Stinnerd6b17692014-09-30 12:20:05 +02008945#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008946/*[clinic input]
8947os.posix_fadvise
8948
8949 fd: int
8950 offset: Py_off_t
8951 length: Py_off_t
8952 advice: int
8953 /
8954
8955Announce an intention to access data in a specific pattern.
8956
8957Announce an intention to access data in a specific pattern, thus allowing
8958the kernel to make optimizations.
8959The advice applies to the region of the file specified by fd starting at
8960offset and continuing for length bytes.
8961advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8962POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8963POSIX_FADV_DONTNEED.
8964[clinic start generated code]*/
8965
Larry Hastings2f936352014-08-05 14:04:04 +10008966static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008967os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008968 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008969/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008970{
8971 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008972 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008973
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008974 do {
8975 Py_BEGIN_ALLOW_THREADS
8976 result = posix_fadvise(fd, offset, length, advice);
8977 Py_END_ALLOW_THREADS
8978 } while (result != 0 && errno == EINTR &&
8979 !(async_err = PyErr_CheckSignals()));
8980 if (result != 0)
8981 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008982 Py_RETURN_NONE;
8983}
Victor Stinnerec39e262014-09-30 12:35:58 +02008984#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008985
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008986#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008987
Fred Drake762e2061999-08-26 17:23:54 +00008988/* Save putenv() parameters as values here, so we can collect them when they
8989 * get re-set with another call for the same key. */
8990static PyObject *posix_putenv_garbage;
8991
Larry Hastings2f936352014-08-05 14:04:04 +10008992static void
8993posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008994{
Larry Hastings2f936352014-08-05 14:04:04 +10008995 /* Install the first arg and newstr in posix_putenv_garbage;
8996 * this will cause previous value to be collected. This has to
8997 * happen after the real putenv() call because the old value
8998 * was still accessible until then. */
8999 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9000 /* really not much we can do; just leak */
9001 PyErr_Clear();
9002 else
9003 Py_DECREF(value);
9004}
9005
9006
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009007#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009008/*[clinic input]
9009os.putenv
9010
9011 name: unicode
9012 value: unicode
9013 /
9014
9015Change or add an environment variable.
9016[clinic start generated code]*/
9017
Larry Hastings2f936352014-08-05 14:04:04 +10009018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009019os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9020/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009021{
9022 wchar_t *env;
9023
9024 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9025 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009026 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009027 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009028 }
Larry Hastings2f936352014-08-05 14:04:04 +10009029 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009030 PyErr_Format(PyExc_ValueError,
9031 "the environment variable is longer than %u characters",
9032 _MAX_ENV);
9033 goto error;
9034 }
9035
Larry Hastings2f936352014-08-05 14:04:04 +10009036 env = PyUnicode_AsUnicode(unicode);
9037 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009038 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009039 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009041 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009042 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009043
Larry Hastings2f936352014-08-05 14:04:04 +10009044 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009045 Py_RETURN_NONE;
9046
9047error:
Larry Hastings2f936352014-08-05 14:04:04 +10009048 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009049 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009050}
Larry Hastings2f936352014-08-05 14:04:04 +10009051#else /* MS_WINDOWS */
9052/*[clinic input]
9053os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009054
Larry Hastings2f936352014-08-05 14:04:04 +10009055 name: FSConverter
9056 value: FSConverter
9057 /
9058
9059Change or add an environment variable.
9060[clinic start generated code]*/
9061
Larry Hastings2f936352014-08-05 14:04:04 +10009062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009063os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9064/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009065{
9066 PyObject *bytes = NULL;
9067 char *env;
9068 char *name_string = PyBytes_AsString(name);
9069 char *value_string = PyBytes_AsString(value);
9070
9071 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9072 if (bytes == NULL) {
9073 PyErr_NoMemory();
9074 return NULL;
9075 }
9076
9077 env = PyBytes_AS_STRING(bytes);
9078 if (putenv(env)) {
9079 Py_DECREF(bytes);
9080 return posix_error();
9081 }
9082
9083 posix_putenv_garbage_setitem(name, bytes);
9084 Py_RETURN_NONE;
9085}
9086#endif /* MS_WINDOWS */
9087#endif /* HAVE_PUTENV */
9088
9089
9090#ifdef HAVE_UNSETENV
9091/*[clinic input]
9092os.unsetenv
9093 name: FSConverter
9094 /
9095
9096Delete an environment variable.
9097[clinic start generated code]*/
9098
Larry Hastings2f936352014-08-05 14:04:04 +10009099static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009100os_unsetenv_impl(PyObject *module, PyObject *name)
9101/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009102{
Victor Stinner984890f2011-11-24 13:53:38 +01009103#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009104 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009105#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009106
Victor Stinner984890f2011-11-24 13:53:38 +01009107#ifdef HAVE_BROKEN_UNSETENV
9108 unsetenv(PyBytes_AS_STRING(name));
9109#else
Victor Stinner65170952011-11-22 22:16:17 +01009110 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009111 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009112 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009113#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009114
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 /* Remove the key from posix_putenv_garbage;
9116 * this will cause it to be collected. This has to
9117 * happen after the real unsetenv() call because the
9118 * old value was still accessible until then.
9119 */
Victor Stinner65170952011-11-22 22:16:17 +01009120 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009121 /* really not much we can do; just leak */
9122 PyErr_Clear();
9123 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009124 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009125}
Larry Hastings2f936352014-08-05 14:04:04 +10009126#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009127
Larry Hastings2f936352014-08-05 14:04:04 +10009128
9129/*[clinic input]
9130os.strerror
9131
9132 code: int
9133 /
9134
9135Translate an error code to a message string.
9136[clinic start generated code]*/
9137
Larry Hastings2f936352014-08-05 14:04:04 +10009138static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009139os_strerror_impl(PyObject *module, int code)
9140/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009141{
9142 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009143 if (message == NULL) {
9144 PyErr_SetString(PyExc_ValueError,
9145 "strerror() argument out of range");
9146 return NULL;
9147 }
Victor Stinner1b579672011-12-17 05:47:23 +01009148 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009149}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009150
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009151
Guido van Rossumc9641791998-08-04 15:26:23 +00009152#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009153#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009154/*[clinic input]
9155os.WCOREDUMP -> bool
9156
9157 status: int
9158 /
9159
9160Return True if the process returning status was dumped to a core file.
9161[clinic start generated code]*/
9162
Larry Hastings2f936352014-08-05 14:04:04 +10009163static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009164os_WCOREDUMP_impl(PyObject *module, int status)
9165/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009166{
9167 WAIT_TYPE wait_status;
9168 WAIT_STATUS_INT(wait_status) = status;
9169 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009170}
9171#endif /* WCOREDUMP */
9172
Larry Hastings2f936352014-08-05 14:04:04 +10009173
Fred Drake106c1a02002-04-23 15:58:02 +00009174#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009175/*[clinic input]
9176os.WIFCONTINUED -> bool
9177
9178 status: int
9179
9180Return True if a particular process was continued from a job control stop.
9181
9182Return True if the process returning status was continued from a
9183job control stop.
9184[clinic start generated code]*/
9185
Larry Hastings2f936352014-08-05 14:04:04 +10009186static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009187os_WIFCONTINUED_impl(PyObject *module, int status)
9188/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009189{
9190 WAIT_TYPE wait_status;
9191 WAIT_STATUS_INT(wait_status) = status;
9192 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009193}
9194#endif /* WIFCONTINUED */
9195
Larry Hastings2f936352014-08-05 14:04:04 +10009196
Guido van Rossumc9641791998-08-04 15:26:23 +00009197#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009198/*[clinic input]
9199os.WIFSTOPPED -> bool
9200
9201 status: int
9202
9203Return True if the process returning status was stopped.
9204[clinic start generated code]*/
9205
Larry Hastings2f936352014-08-05 14:04:04 +10009206static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009207os_WIFSTOPPED_impl(PyObject *module, int status)
9208/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009209{
9210 WAIT_TYPE wait_status;
9211 WAIT_STATUS_INT(wait_status) = status;
9212 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009213}
9214#endif /* WIFSTOPPED */
9215
Larry Hastings2f936352014-08-05 14:04:04 +10009216
Guido van Rossumc9641791998-08-04 15:26:23 +00009217#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009218/*[clinic input]
9219os.WIFSIGNALED -> bool
9220
9221 status: int
9222
9223Return True if the process returning status was terminated by a signal.
9224[clinic start generated code]*/
9225
Larry Hastings2f936352014-08-05 14:04:04 +10009226static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009227os_WIFSIGNALED_impl(PyObject *module, int status)
9228/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009229{
9230 WAIT_TYPE wait_status;
9231 WAIT_STATUS_INT(wait_status) = status;
9232 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009233}
9234#endif /* WIFSIGNALED */
9235
Larry Hastings2f936352014-08-05 14:04:04 +10009236
Guido van Rossumc9641791998-08-04 15:26:23 +00009237#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009238/*[clinic input]
9239os.WIFEXITED -> bool
9240
9241 status: int
9242
9243Return True if the process returning status exited via the exit() system call.
9244[clinic start generated code]*/
9245
Larry Hastings2f936352014-08-05 14:04:04 +10009246static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009247os_WIFEXITED_impl(PyObject *module, int status)
9248/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009249{
9250 WAIT_TYPE wait_status;
9251 WAIT_STATUS_INT(wait_status) = status;
9252 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009253}
9254#endif /* WIFEXITED */
9255
Larry Hastings2f936352014-08-05 14:04:04 +10009256
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009257#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009258/*[clinic input]
9259os.WEXITSTATUS -> int
9260
9261 status: int
9262
9263Return the process return code from status.
9264[clinic start generated code]*/
9265
Larry Hastings2f936352014-08-05 14:04:04 +10009266static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009267os_WEXITSTATUS_impl(PyObject *module, int status)
9268/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009269{
9270 WAIT_TYPE wait_status;
9271 WAIT_STATUS_INT(wait_status) = status;
9272 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009273}
9274#endif /* WEXITSTATUS */
9275
Larry Hastings2f936352014-08-05 14:04:04 +10009276
Guido van Rossumc9641791998-08-04 15:26:23 +00009277#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009278/*[clinic input]
9279os.WTERMSIG -> int
9280
9281 status: int
9282
9283Return the signal that terminated the process that provided the status value.
9284[clinic start generated code]*/
9285
Larry Hastings2f936352014-08-05 14:04:04 +10009286static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009287os_WTERMSIG_impl(PyObject *module, int status)
9288/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009289{
9290 WAIT_TYPE wait_status;
9291 WAIT_STATUS_INT(wait_status) = status;
9292 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009293}
9294#endif /* WTERMSIG */
9295
Larry Hastings2f936352014-08-05 14:04:04 +10009296
Guido van Rossumc9641791998-08-04 15:26:23 +00009297#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009298/*[clinic input]
9299os.WSTOPSIG -> int
9300
9301 status: int
9302
9303Return the signal that stopped the process that provided the status value.
9304[clinic start generated code]*/
9305
Larry Hastings2f936352014-08-05 14:04:04 +10009306static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009307os_WSTOPSIG_impl(PyObject *module, int status)
9308/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009309{
9310 WAIT_TYPE wait_status;
9311 WAIT_STATUS_INT(wait_status) = status;
9312 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009313}
9314#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009315#endif /* HAVE_SYS_WAIT_H */
9316
9317
Thomas Wouters477c8d52006-05-27 19:21:47 +00009318#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009319#ifdef _SCO_DS
9320/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9321 needed definitions in sys/statvfs.h */
9322#define _SVID3
9323#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009324#include <sys/statvfs.h>
9325
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009326static PyObject*
9327_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009328 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9329 if (v == NULL)
9330 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009331
9332#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009333 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9334 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9335 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9336 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9337 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9338 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9339 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9340 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9341 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9342 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009343#else
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,
9347 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9348 PyStructSequence_SET_ITEM(v, 3,
9349 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9350 PyStructSequence_SET_ITEM(v, 4,
9351 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9352 PyStructSequence_SET_ITEM(v, 5,
9353 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9354 PyStructSequence_SET_ITEM(v, 6,
9355 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9356 PyStructSequence_SET_ITEM(v, 7,
9357 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9358 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9359 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009360#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009361 if (PyErr_Occurred()) {
9362 Py_DECREF(v);
9363 return NULL;
9364 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009365
Victor Stinner8c62be82010-05-06 00:08:46 +00009366 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009367}
9368
Larry Hastings2f936352014-08-05 14:04:04 +10009369
9370/*[clinic input]
9371os.fstatvfs
9372 fd: int
9373 /
9374
9375Perform an fstatvfs system call on the given fd.
9376
9377Equivalent to statvfs(fd).
9378[clinic start generated code]*/
9379
Larry Hastings2f936352014-08-05 14:04:04 +10009380static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009381os_fstatvfs_impl(PyObject *module, int fd)
9382/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009383{
9384 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009385 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009386 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009387
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009388 do {
9389 Py_BEGIN_ALLOW_THREADS
9390 result = fstatvfs(fd, &st);
9391 Py_END_ALLOW_THREADS
9392 } while (result != 0 && errno == EINTR &&
9393 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009394 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009395 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009396
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009398}
Larry Hastings2f936352014-08-05 14:04:04 +10009399#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009400
9401
Thomas Wouters477c8d52006-05-27 19:21:47 +00009402#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009403#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009404/*[clinic input]
9405os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009406
Larry Hastings2f936352014-08-05 14:04:04 +10009407 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9408
9409Perform a statvfs system call on the given path.
9410
9411path may always be specified as a string.
9412On some platforms, path may also be specified as an open file descriptor.
9413 If this functionality is unavailable, using it raises an exception.
9414[clinic start generated code]*/
9415
Larry Hastings2f936352014-08-05 14:04:04 +10009416static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009417os_statvfs_impl(PyObject *module, path_t *path)
9418/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009419{
9420 int result;
9421 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009422
9423 Py_BEGIN_ALLOW_THREADS
9424#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009425 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009426#ifdef __APPLE__
9427 /* handle weak-linking on Mac OS X 10.3 */
9428 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009429 fd_specified("statvfs", path->fd);
9430 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009431 }
9432#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009433 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009434 }
9435 else
9436#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009437 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009438 Py_END_ALLOW_THREADS
9439
9440 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009441 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009442 }
9443
Larry Hastings2f936352014-08-05 14:04:04 +10009444 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009445}
Larry Hastings2f936352014-08-05 14:04:04 +10009446#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9447
Guido van Rossum94f6f721999-01-06 18:42:14 +00009448
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009449#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009450/*[clinic input]
9451os._getdiskusage
9452
9453 path: Py_UNICODE
9454
9455Return disk usage statistics about the given path as a (total, free) tuple.
9456[clinic start generated code]*/
9457
Larry Hastings2f936352014-08-05 14:04:04 +10009458static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009459os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9460/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009461{
9462 BOOL retval;
9463 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009464
9465 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009466 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009467 Py_END_ALLOW_THREADS
9468 if (retval == 0)
9469 return PyErr_SetFromWindowsErr(0);
9470
9471 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9472}
Larry Hastings2f936352014-08-05 14:04:04 +10009473#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009474
9475
Fred Drakec9680921999-12-13 16:37:25 +00009476/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9477 * It maps strings representing configuration variable names to
9478 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009479 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009480 * rarely-used constants. There are three separate tables that use
9481 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009482 *
9483 * This code is always included, even if none of the interfaces that
9484 * need it are included. The #if hackery needed to avoid it would be
9485 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009486 */
9487struct constdef {
9488 char *name;
9489 long value;
9490};
9491
Fred Drake12c6e2d1999-12-14 21:25:03 +00009492static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009493conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009494 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009495{
Christian Heimes217cfd12007-12-02 14:31:20 +00009496 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009497 *valuep = PyLong_AS_LONG(arg);
9498 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009499 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009500 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009501 /* look up the value in the table using a binary search */
9502 size_t lo = 0;
9503 size_t mid;
9504 size_t hi = tablesize;
9505 int cmp;
9506 const char *confname;
9507 if (!PyUnicode_Check(arg)) {
9508 PyErr_SetString(PyExc_TypeError,
9509 "configuration names must be strings or integers");
9510 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009511 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009512 confname = _PyUnicode_AsString(arg);
9513 if (confname == NULL)
9514 return 0;
9515 while (lo < hi) {
9516 mid = (lo + hi) / 2;
9517 cmp = strcmp(confname, table[mid].name);
9518 if (cmp < 0)
9519 hi = mid;
9520 else if (cmp > 0)
9521 lo = mid + 1;
9522 else {
9523 *valuep = table[mid].value;
9524 return 1;
9525 }
9526 }
9527 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9528 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009529 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009530}
9531
9532
9533#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9534static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009535#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009537#endif
9538#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009540#endif
Fred Drakec9680921999-12-13 16:37:25 +00009541#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009586#ifdef _PC_ACL_ENABLED
9587 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9588#endif
9589#ifdef _PC_MIN_HOLE_SIZE
9590 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9591#endif
9592#ifdef _PC_ALLOC_SIZE_MIN
9593 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9594#endif
9595#ifdef _PC_REC_INCR_XFER_SIZE
9596 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9597#endif
9598#ifdef _PC_REC_MAX_XFER_SIZE
9599 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9600#endif
9601#ifdef _PC_REC_MIN_XFER_SIZE
9602 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9603#endif
9604#ifdef _PC_REC_XFER_ALIGN
9605 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9606#endif
9607#ifdef _PC_SYMLINK_MAX
9608 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9609#endif
9610#ifdef _PC_XATTR_ENABLED
9611 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9612#endif
9613#ifdef _PC_XATTR_EXISTS
9614 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9615#endif
9616#ifdef _PC_TIMESTAMP_RESOLUTION
9617 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9618#endif
Fred Drakec9680921999-12-13 16:37:25 +00009619};
9620
Fred Drakec9680921999-12-13 16:37:25 +00009621static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009622conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009623{
9624 return conv_confname(arg, valuep, posix_constants_pathconf,
9625 sizeof(posix_constants_pathconf)
9626 / sizeof(struct constdef));
9627}
9628#endif
9629
Larry Hastings2f936352014-08-05 14:04:04 +10009630
Fred Drakec9680921999-12-13 16:37:25 +00009631#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009632/*[clinic input]
9633os.fpathconf -> long
9634
9635 fd: int
9636 name: path_confname
9637 /
9638
9639Return the configuration limit name for the file descriptor fd.
9640
9641If there is no limit, return -1.
9642[clinic start generated code]*/
9643
Larry Hastings2f936352014-08-05 14:04:04 +10009644static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009645os_fpathconf_impl(PyObject *module, int fd, int name)
9646/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009647{
9648 long limit;
9649
9650 errno = 0;
9651 limit = fpathconf(fd, name);
9652 if (limit == -1 && errno != 0)
9653 posix_error();
9654
9655 return limit;
9656}
9657#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009658
9659
9660#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009661/*[clinic input]
9662os.pathconf -> long
9663 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9664 name: path_confname
9665
9666Return the configuration limit name for the file or directory path.
9667
9668If there is no limit, return -1.
9669On some platforms, path may also be specified as an open file descriptor.
9670 If this functionality is unavailable, using it raises an exception.
9671[clinic start generated code]*/
9672
Larry Hastings2f936352014-08-05 14:04:04 +10009673static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009674os_pathconf_impl(PyObject *module, path_t *path, int name)
9675/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009676{
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009678
Victor Stinner8c62be82010-05-06 00:08:46 +00009679 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009680#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009681 if (path->fd != -1)
9682 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009683 else
9684#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009685 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 if (limit == -1 && errno != 0) {
9687 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009688 /* could be a path or name problem */
9689 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009690 else
Larry Hastings2f936352014-08-05 14:04:04 +10009691 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 }
Larry Hastings2f936352014-08-05 14:04:04 +10009693
9694 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009695}
Larry Hastings2f936352014-08-05 14:04:04 +10009696#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009697
9698#ifdef HAVE_CONFSTR
9699static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009700#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009702#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009703#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009705#endif
9706#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009708#endif
Fred Draked86ed291999-12-15 15:34:33 +00009709#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009711#endif
9712#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009714#endif
9715#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009717#endif
9718#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009720#endif
Fred Drakec9680921999-12-13 16:37:25 +00009721#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
9730#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
Fred Draked86ed291999-12-15 15:34:33 +00009745#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009747#endif
Fred Drakec9680921999-12-13 16:37:25 +00009748#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
Fred Draked86ed291999-12-15 15:34:33 +00009751#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009753#endif
9754#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009756#endif
9757#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009759#endif
9760#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009762#endif
Fred Drakec9680921999-12-13 16:37:25 +00009763#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
Fred Draked86ed291999-12-15 15:34:33 +00009811#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009813#endif
9814#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009816#endif
9817#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009819#endif
9820#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009822#endif
9823#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009825#endif
9826#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009828#endif
9829#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009831#endif
9832#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009834#endif
9835#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009837#endif
9838#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
9841#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
9844#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009846#endif
9847#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009849#endif
Fred Drakec9680921999-12-13 16:37:25 +00009850};
9851
9852static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009853conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009854{
9855 return conv_confname(arg, valuep, posix_constants_confstr,
9856 sizeof(posix_constants_confstr)
9857 / sizeof(struct constdef));
9858}
9859
Larry Hastings2f936352014-08-05 14:04:04 +10009860
9861/*[clinic input]
9862os.confstr
9863
9864 name: confstr_confname
9865 /
9866
9867Return a string-valued system configuration variable.
9868[clinic start generated code]*/
9869
Larry Hastings2f936352014-08-05 14:04:04 +10009870static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009871os_confstr_impl(PyObject *module, int name)
9872/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009873{
9874 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009875 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009876 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009877
Victor Stinnercb043522010-09-10 23:49:04 +00009878 errno = 0;
9879 len = confstr(name, buffer, sizeof(buffer));
9880 if (len == 0) {
9881 if (errno) {
9882 posix_error();
9883 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009884 }
9885 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009886 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009887 }
9888 }
Victor Stinnercb043522010-09-10 23:49:04 +00009889
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009890 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009891 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009892 char *buf = PyMem_Malloc(len);
9893 if (buf == NULL)
9894 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009895 len2 = confstr(name, buf, len);
9896 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009897 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009898 PyMem_Free(buf);
9899 }
9900 else
9901 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009902 return result;
9903}
Larry Hastings2f936352014-08-05 14:04:04 +10009904#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009905
9906
9907#ifdef HAVE_SYSCONF
9908static struct constdef posix_constants_sysconf[] = {
9909#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
Fred Draked86ed291999-12-15 15:34:33 +00009939#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009941#endif
9942#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009944#endif
Fred Drakec9680921999-12-13 16:37:25 +00009945#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
Fred Drakec9680921999-12-13 16:37:25 +00009948#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
Fred Draked86ed291999-12-15 15:34:33 +00009963#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009965#endif
Fred Drakec9680921999-12-13 16:37:25 +00009966#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
Fred Draked86ed291999-12-15 15:34:33 +00009981#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009983#endif
Fred Drakec9680921999-12-13 16:37:25 +00009984#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
Fred Draked86ed291999-12-15 15:34:33 +000010053#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010055#endif
Fred Drakec9680921999-12-13 16:37:25 +000010056#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
Fred Draked86ed291999-12-15 15:34:33 +000010065#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010067#endif
Fred Drakec9680921999-12-13 16:37:25 +000010068#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
Fred Draked86ed291999-12-15 15:34:33 +000010071#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010073#endif
10074#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010076#endif
Fred Drakec9680921999-12-13 16:37:25 +000010077#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
Fred Draked86ed291999-12-15 15:34:33 +000010089#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010091#endif
Fred Drakec9680921999-12-13 16:37:25 +000010092#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
Fred Draked86ed291999-12-15 15:34:33 +000010113#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010115#endif
Fred Drakec9680921999-12-13 16:37:25 +000010116#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
Fred Draked86ed291999-12-15 15:34:33 +000010122#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010124#endif
Fred Drakec9680921999-12-13 16:37:25 +000010125#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
Fred Draked86ed291999-12-15 15:34:33 +000010152#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010154#endif
10155#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010157#endif
Fred Drakec9680921999-12-13 16:37:25 +000010158#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
Fred Draked86ed291999-12-15 15:34:33 +000010263#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010265#endif
Fred Drakec9680921999-12-13 16:37:25 +000010266#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010400#endif
10401};
10402
10403static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010404conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010405{
10406 return conv_confname(arg, valuep, posix_constants_sysconf,
10407 sizeof(posix_constants_sysconf)
10408 / sizeof(struct constdef));
10409}
10410
Larry Hastings2f936352014-08-05 14:04:04 +100010411
10412/*[clinic input]
10413os.sysconf -> long
10414 name: sysconf_confname
10415 /
10416
10417Return an integer-valued system configuration variable.
10418[clinic start generated code]*/
10419
Larry Hastings2f936352014-08-05 14:04:04 +100010420static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010421os_sysconf_impl(PyObject *module, int name)
10422/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010423{
10424 long value;
10425
10426 errno = 0;
10427 value = sysconf(name);
10428 if (value == -1 && errno != 0)
10429 posix_error();
10430 return value;
10431}
10432#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010433
10434
Fred Drakebec628d1999-12-15 18:31:10 +000010435/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010436 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010437 * the exported dictionaries that are used to publish information about the
10438 * names available on the host platform.
10439 *
10440 * Sorting the table at runtime ensures that the table is properly ordered
10441 * when used, even for platforms we're not able to test on. It also makes
10442 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010443 */
Fred Drakebec628d1999-12-15 18:31:10 +000010444
10445static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010446cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010447{
10448 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010450 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010451 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010452
10453 return strcmp(c1->name, c2->name);
10454}
10455
10456static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010457setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010458 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010459{
Fred Drakebec628d1999-12-15 18:31:10 +000010460 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010461 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010462
10463 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10464 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010465 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010467
Barry Warsaw3155db32000-04-13 15:20:40 +000010468 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010469 PyObject *o = PyLong_FromLong(table[i].value);
10470 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10471 Py_XDECREF(o);
10472 Py_DECREF(d);
10473 return -1;
10474 }
10475 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010476 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010477 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010478}
10479
Fred Drakebec628d1999-12-15 18:31:10 +000010480/* Return -1 on failure, 0 on success. */
10481static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010482setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010483{
10484#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010485 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010486 sizeof(posix_constants_pathconf)
10487 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010488 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010489 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010490#endif
10491#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010492 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010493 sizeof(posix_constants_confstr)
10494 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010495 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010496 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010497#endif
10498#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010499 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010500 sizeof(posix_constants_sysconf)
10501 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010502 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010503 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010504#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010505 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010506}
Fred Draked86ed291999-12-15 15:34:33 +000010507
10508
Larry Hastings2f936352014-08-05 14:04:04 +100010509/*[clinic input]
10510os.abort
10511
10512Abort the interpreter immediately.
10513
10514This function 'dumps core' or otherwise fails in the hardest way possible
10515on the hosting operating system. This function never returns.
10516[clinic start generated code]*/
10517
Larry Hastings2f936352014-08-05 14:04:04 +100010518static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010519os_abort_impl(PyObject *module)
10520/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010521{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010522 abort();
10523 /*NOTREACHED*/
10524 Py_FatalError("abort() called from Python code didn't abort!");
10525 return NULL;
10526}
Fred Drakebec628d1999-12-15 18:31:10 +000010527
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010528#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010529/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010530PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010531"startfile(filepath [, operation])\n\
10532\n\
10533Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010534\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010535When \"operation\" is not specified or \"open\", this acts like\n\
10536double-clicking the file in Explorer, or giving the file name as an\n\
10537argument to the DOS \"start\" command: the file is opened with whatever\n\
10538application (if any) its extension is associated.\n\
10539When another \"operation\" is given, it specifies what should be done with\n\
10540the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010541\n\
10542startfile returns as soon as the associated application is launched.\n\
10543There is no option to wait for the application to close, and no way\n\
10544to retrieve the application's exit status.\n\
10545\n\
10546The filepath is relative to the current directory. If you want to use\n\
10547an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010548the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010549
Steve Dower7d0e0c92015-01-24 08:18:24 -080010550/* Grab ShellExecute dynamically from shell32 */
10551static int has_ShellExecute = -1;
10552static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10553 LPCSTR, INT);
10554static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10555 LPCWSTR, INT);
10556static int
10557check_ShellExecute()
10558{
10559 HINSTANCE hShell32;
10560
10561 /* only recheck */
10562 if (-1 == has_ShellExecute) {
10563 Py_BEGIN_ALLOW_THREADS
10564 hShell32 = LoadLibraryW(L"SHELL32");
10565 Py_END_ALLOW_THREADS
10566 if (hShell32) {
10567 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10568 "ShellExecuteA");
10569 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10570 "ShellExecuteW");
10571 has_ShellExecute = Py_ShellExecuteA &&
10572 Py_ShellExecuteW;
10573 } else {
10574 has_ShellExecute = 0;
10575 }
10576 }
10577 return has_ShellExecute;
10578}
10579
10580
Tim Petersf58a7aa2000-09-22 10:05:54 +000010581static PyObject *
10582win32_startfile(PyObject *self, PyObject *args)
10583{
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 PyObject *ofilepath;
10585 char *filepath;
10586 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010587 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010589
Victor Stinnereb5657a2011-09-30 01:44:27 +020010590 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010591
10592 if(!check_ShellExecute()) {
10593 /* If the OS doesn't have ShellExecute, return a
10594 NotImplementedError. */
10595 return PyErr_Format(PyExc_NotImplementedError,
10596 "startfile not available on this platform");
10597 }
10598
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 if (!PyArg_ParseTuple(args, "U|s:startfile",
10600 &unipath, &operation)) {
10601 PyErr_Clear();
10602 goto normal;
10603 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010604
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010606 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010608 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 PyErr_Clear();
10610 operation = NULL;
10611 goto normal;
10612 }
10613 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010614
Victor Stinnereb5657a2011-09-30 01:44:27 +020010615 wpath = PyUnicode_AsUnicode(unipath);
10616 if (wpath == NULL)
10617 goto normal;
10618 if (uoperation) {
10619 woperation = PyUnicode_AsUnicode(uoperation);
10620 if (woperation == NULL)
10621 goto normal;
10622 }
10623 else
10624 woperation = NULL;
10625
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010627 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10628 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 Py_END_ALLOW_THREADS
10630
Victor Stinnereb5657a2011-09-30 01:44:27 +020010631 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010632 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010633 win32_error_object("startfile", unipath);
10634 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010635 }
10636 Py_INCREF(Py_None);
10637 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010638
10639normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10641 PyUnicode_FSConverter, &ofilepath,
10642 &operation))
10643 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010644 if (win32_warn_bytes_api()) {
10645 Py_DECREF(ofilepath);
10646 return NULL;
10647 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 filepath = PyBytes_AsString(ofilepath);
10649 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010650 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10651 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 Py_END_ALLOW_THREADS
10653 if (rc <= (HINSTANCE)32) {
10654 PyObject *errval = win32_error("startfile", filepath);
10655 Py_DECREF(ofilepath);
10656 return errval;
10657 }
10658 Py_DECREF(ofilepath);
10659 Py_INCREF(Py_None);
10660 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010661}
Larry Hastings2f936352014-08-05 14:04:04 +100010662#endif /* MS_WINDOWS */
10663
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010664
Martin v. Löwis438b5342002-12-27 10:16:42 +000010665#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010666/*[clinic input]
10667os.getloadavg
10668
10669Return average recent system load information.
10670
10671Return the number of processes in the system run queue averaged over
10672the last 1, 5, and 15 minutes as a tuple of three floats.
10673Raises OSError if the load average was unobtainable.
10674[clinic start generated code]*/
10675
Larry Hastings2f936352014-08-05 14:04:04 +100010676static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010677os_getloadavg_impl(PyObject *module)
10678/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010679{
10680 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010681 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010682 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10683 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010684 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010685 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010686}
Larry Hastings2f936352014-08-05 14:04:04 +100010687#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010688
Larry Hastings2f936352014-08-05 14:04:04 +100010689
10690/*[clinic input]
10691os.device_encoding
10692 fd: int
10693
10694Return a string describing the encoding of a terminal's file descriptor.
10695
10696The file descriptor must be attached to a terminal.
10697If the device is not a terminal, return None.
10698[clinic start generated code]*/
10699
Larry Hastings2f936352014-08-05 14:04:04 +100010700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010701os_device_encoding_impl(PyObject *module, int fd)
10702/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010703{
Brett Cannonefb00c02012-02-29 18:31:31 -050010704 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010705}
10706
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010707
Larry Hastings2f936352014-08-05 14:04:04 +100010708#ifdef HAVE_SETRESUID
10709/*[clinic input]
10710os.setresuid
10711
10712 ruid: uid_t
10713 euid: uid_t
10714 suid: uid_t
10715 /
10716
10717Set the current process's real, effective, and saved user ids.
10718[clinic start generated code]*/
10719
Larry Hastings2f936352014-08-05 14:04:04 +100010720static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010721os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10722/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010723{
Victor Stinner8c62be82010-05-06 00:08:46 +000010724 if (setresuid(ruid, euid, suid) < 0)
10725 return posix_error();
10726 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010727}
Larry Hastings2f936352014-08-05 14:04:04 +100010728#endif /* HAVE_SETRESUID */
10729
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010730
10731#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010732/*[clinic input]
10733os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010734
Larry Hastings2f936352014-08-05 14:04:04 +100010735 rgid: gid_t
10736 egid: gid_t
10737 sgid: gid_t
10738 /
10739
10740Set the current process's real, effective, and saved group ids.
10741[clinic start generated code]*/
10742
Larry Hastings2f936352014-08-05 14:04:04 +100010743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010744os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10745/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010746{
Victor Stinner8c62be82010-05-06 00:08:46 +000010747 if (setresgid(rgid, egid, sgid) < 0)
10748 return posix_error();
10749 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010750}
Larry Hastings2f936352014-08-05 14:04:04 +100010751#endif /* HAVE_SETRESGID */
10752
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010753
10754#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010755/*[clinic input]
10756os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010757
Larry Hastings2f936352014-08-05 14:04:04 +100010758Return a tuple of the current process's real, effective, and saved user ids.
10759[clinic start generated code]*/
10760
Larry Hastings2f936352014-08-05 14:04:04 +100010761static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010762os_getresuid_impl(PyObject *module)
10763/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010764{
Victor Stinner8c62be82010-05-06 00:08:46 +000010765 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010766 if (getresuid(&ruid, &euid, &suid) < 0)
10767 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010768 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10769 _PyLong_FromUid(euid),
10770 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010771}
Larry Hastings2f936352014-08-05 14:04:04 +100010772#endif /* HAVE_GETRESUID */
10773
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010774
10775#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010776/*[clinic input]
10777os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010778
Larry Hastings2f936352014-08-05 14:04:04 +100010779Return a tuple of the current process's real, effective, and saved group ids.
10780[clinic start generated code]*/
10781
Larry Hastings2f936352014-08-05 14:04:04 +100010782static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010783os_getresgid_impl(PyObject *module)
10784/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010785{
10786 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010787 if (getresgid(&rgid, &egid, &sgid) < 0)
10788 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010789 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10790 _PyLong_FromGid(egid),
10791 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010792}
Larry Hastings2f936352014-08-05 14:04:04 +100010793#endif /* HAVE_GETRESGID */
10794
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010795
Benjamin Peterson9428d532011-09-14 11:45:52 -040010796#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010797/*[clinic input]
10798os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010799
Larry Hastings2f936352014-08-05 14:04:04 +100010800 path: path_t(allow_fd=True)
10801 attribute: path_t
10802 *
10803 follow_symlinks: bool = True
10804
10805Return the value of extended attribute attribute on path.
10806
10807path may be either a string or an open file descriptor.
10808If follow_symlinks is False, and the last element of the path is a symbolic
10809 link, getxattr will examine the symbolic link itself instead of the file
10810 the link points to.
10811
10812[clinic start generated code]*/
10813
Larry Hastings2f936352014-08-05 14:04:04 +100010814static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010815os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010816 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010817/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010818{
10819 Py_ssize_t i;
10820 PyObject *buffer = NULL;
10821
10822 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10823 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010824
Larry Hastings9cf065c2012-06-22 16:30:09 -070010825 for (i = 0; ; i++) {
10826 void *ptr;
10827 ssize_t result;
10828 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10829 Py_ssize_t buffer_size = buffer_sizes[i];
10830 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010831 path_error(path);
10832 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010833 }
10834 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10835 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010836 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010837 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010838
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010840 if (path->fd >= 0)
10841 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010842 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010843 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010844 else
Larry Hastings2f936352014-08-05 14:04:04 +100010845 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010846 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010847
Larry Hastings9cf065c2012-06-22 16:30:09 -070010848 if (result < 0) {
10849 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010850 if (errno == ERANGE)
10851 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010852 path_error(path);
10853 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010854 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010855
Larry Hastings9cf065c2012-06-22 16:30:09 -070010856 if (result != buffer_size) {
10857 /* Can only shrink. */
10858 _PyBytes_Resize(&buffer, result);
10859 }
10860 break;
10861 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010862
Larry Hastings9cf065c2012-06-22 16:30:09 -070010863 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010864}
10865
Larry Hastings2f936352014-08-05 14:04:04 +100010866
10867/*[clinic input]
10868os.setxattr
10869
10870 path: path_t(allow_fd=True)
10871 attribute: path_t
10872 value: Py_buffer
10873 flags: int = 0
10874 *
10875 follow_symlinks: bool = True
10876
10877Set extended attribute attribute on path to value.
10878
10879path may be either a string or an open file descriptor.
10880If follow_symlinks is False, and the last element of the path is a symbolic
10881 link, setxattr will modify the symbolic link itself instead of the file
10882 the link points to.
10883
10884[clinic start generated code]*/
10885
Benjamin Peterson799bd802011-08-31 22:15:17 -040010886static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010887os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010888 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010889/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010890{
Larry Hastings2f936352014-08-05 14:04:04 +100010891 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010892
Larry Hastings2f936352014-08-05 14:04:04 +100010893 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010894 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010895
Benjamin Peterson799bd802011-08-31 22:15:17 -040010896 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010897 if (path->fd > -1)
10898 result = fsetxattr(path->fd, attribute->narrow,
10899 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010900 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010901 result = setxattr(path->narrow, attribute->narrow,
10902 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010903 else
Larry Hastings2f936352014-08-05 14:04:04 +100010904 result = lsetxattr(path->narrow, attribute->narrow,
10905 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010906 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010907
Larry Hastings9cf065c2012-06-22 16:30:09 -070010908 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010909 path_error(path);
10910 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010911 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010912
Larry Hastings2f936352014-08-05 14:04:04 +100010913 Py_RETURN_NONE;
10914}
10915
10916
10917/*[clinic input]
10918os.removexattr
10919
10920 path: path_t(allow_fd=True)
10921 attribute: path_t
10922 *
10923 follow_symlinks: bool = True
10924
10925Remove extended attribute attribute on path.
10926
10927path may be either a string or an open file descriptor.
10928If follow_symlinks is False, and the last element of the path is a symbolic
10929 link, removexattr will modify the symbolic link itself instead of the file
10930 the link points to.
10931
10932[clinic start generated code]*/
10933
Larry Hastings2f936352014-08-05 14:04:04 +100010934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010935os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010936 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010937/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010938{
10939 ssize_t result;
10940
10941 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10942 return NULL;
10943
10944 Py_BEGIN_ALLOW_THREADS;
10945 if (path->fd > -1)
10946 result = fremovexattr(path->fd, attribute->narrow);
10947 else if (follow_symlinks)
10948 result = removexattr(path->narrow, attribute->narrow);
10949 else
10950 result = lremovexattr(path->narrow, attribute->narrow);
10951 Py_END_ALLOW_THREADS;
10952
10953 if (result) {
10954 return path_error(path);
10955 }
10956
10957 Py_RETURN_NONE;
10958}
10959
10960
10961/*[clinic input]
10962os.listxattr
10963
10964 path: path_t(allow_fd=True, nullable=True) = None
10965 *
10966 follow_symlinks: bool = True
10967
10968Return a list of extended attributes on path.
10969
10970path may be either None, a string, or an open file descriptor.
10971if path is None, listxattr will examine the current directory.
10972If follow_symlinks is False, and the last element of the path is a symbolic
10973 link, listxattr will examine the symbolic link itself instead of the file
10974 the link points to.
10975[clinic start generated code]*/
10976
Larry Hastings2f936352014-08-05 14:04:04 +100010977static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010978os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10979/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010980{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010981 Py_ssize_t i;
10982 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010983 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010984 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010985
Larry Hastings2f936352014-08-05 14:04:04 +100010986 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010988
Larry Hastings2f936352014-08-05 14:04:04 +100010989 name = path->narrow ? path->narrow : ".";
10990
Larry Hastings9cf065c2012-06-22 16:30:09 -070010991 for (i = 0; ; i++) {
10992 char *start, *trace, *end;
10993 ssize_t length;
10994 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10995 Py_ssize_t buffer_size = buffer_sizes[i];
10996 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010997 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010998 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 break;
11000 }
11001 buffer = PyMem_MALLOC(buffer_size);
11002 if (!buffer) {
11003 PyErr_NoMemory();
11004 break;
11005 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011006
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011008 if (path->fd > -1)
11009 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011010 else if (follow_symlinks)
11011 length = listxattr(name, buffer, buffer_size);
11012 else
11013 length = llistxattr(name, buffer, buffer_size);
11014 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011015
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011017 if (errno == ERANGE) {
11018 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011019 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011021 }
Larry Hastings2f936352014-08-05 14:04:04 +100011022 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011023 break;
11024 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011025
Larry Hastings9cf065c2012-06-22 16:30:09 -070011026 result = PyList_New(0);
11027 if (!result) {
11028 goto exit;
11029 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011030
Larry Hastings9cf065c2012-06-22 16:30:09 -070011031 end = buffer + length;
11032 for (trace = start = buffer; trace != end; trace++) {
11033 if (!*trace) {
11034 int error;
11035 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11036 trace - start);
11037 if (!attribute) {
11038 Py_DECREF(result);
11039 result = NULL;
11040 goto exit;
11041 }
11042 error = PyList_Append(result, attribute);
11043 Py_DECREF(attribute);
11044 if (error) {
11045 Py_DECREF(result);
11046 result = NULL;
11047 goto exit;
11048 }
11049 start = trace + 1;
11050 }
11051 }
11052 break;
11053 }
11054exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011055 if (buffer)
11056 PyMem_FREE(buffer);
11057 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011058}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011059#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011060
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011061
Larry Hastings2f936352014-08-05 14:04:04 +100011062/*[clinic input]
11063os.urandom
11064
11065 size: Py_ssize_t
11066 /
11067
11068Return a bytes object containing random bytes suitable for cryptographic use.
11069[clinic start generated code]*/
11070
Larry Hastings2f936352014-08-05 14:04:04 +100011071static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011072os_urandom_impl(PyObject *module, Py_ssize_t size)
11073/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011074{
11075 PyObject *bytes;
11076 int result;
11077
Georg Brandl2fb477c2012-02-21 00:33:36 +010011078 if (size < 0)
11079 return PyErr_Format(PyExc_ValueError,
11080 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011081 bytes = PyBytes_FromStringAndSize(NULL, size);
11082 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011083 return NULL;
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11086 PyBytes_GET_SIZE(bytes));
11087 if (result == -1) {
11088 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011089 return NULL;
11090 }
Larry Hastings2f936352014-08-05 14:04:04 +100011091 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011092}
11093
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011094/* Terminal size querying */
11095
11096static PyTypeObject TerminalSizeType;
11097
11098PyDoc_STRVAR(TerminalSize_docstring,
11099 "A tuple of (columns, lines) for holding terminal window size");
11100
11101static PyStructSequence_Field TerminalSize_fields[] = {
11102 {"columns", "width of the terminal window in characters"},
11103 {"lines", "height of the terminal window in characters"},
11104 {NULL, NULL}
11105};
11106
11107static PyStructSequence_Desc TerminalSize_desc = {
11108 "os.terminal_size",
11109 TerminalSize_docstring,
11110 TerminalSize_fields,
11111 2,
11112};
11113
11114#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011115/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011116PyDoc_STRVAR(termsize__doc__,
11117 "Return the size of the terminal window as (columns, lines).\n" \
11118 "\n" \
11119 "The optional argument fd (default standard output) specifies\n" \
11120 "which file descriptor should be queried.\n" \
11121 "\n" \
11122 "If the file descriptor is not connected to a terminal, an OSError\n" \
11123 "is thrown.\n" \
11124 "\n" \
11125 "This function will only be defined if an implementation is\n" \
11126 "available for this system.\n" \
11127 "\n" \
11128 "shutil.get_terminal_size is the high-level function which should \n" \
11129 "normally be used, os.get_terminal_size is the low-level implementation.");
11130
11131static PyObject*
11132get_terminal_size(PyObject *self, PyObject *args)
11133{
11134 int columns, lines;
11135 PyObject *termsize;
11136
11137 int fd = fileno(stdout);
11138 /* Under some conditions stdout may not be connected and
11139 * fileno(stdout) may point to an invalid file descriptor. For example
11140 * GUI apps don't have valid standard streams by default.
11141 *
11142 * If this happens, and the optional fd argument is not present,
11143 * the ioctl below will fail returning EBADF. This is what we want.
11144 */
11145
11146 if (!PyArg_ParseTuple(args, "|i", &fd))
11147 return NULL;
11148
11149#ifdef TERMSIZE_USE_IOCTL
11150 {
11151 struct winsize w;
11152 if (ioctl(fd, TIOCGWINSZ, &w))
11153 return PyErr_SetFromErrno(PyExc_OSError);
11154 columns = w.ws_col;
11155 lines = w.ws_row;
11156 }
11157#endif /* TERMSIZE_USE_IOCTL */
11158
11159#ifdef TERMSIZE_USE_CONIO
11160 {
11161 DWORD nhandle;
11162 HANDLE handle;
11163 CONSOLE_SCREEN_BUFFER_INFO csbi;
11164 switch (fd) {
11165 case 0: nhandle = STD_INPUT_HANDLE;
11166 break;
11167 case 1: nhandle = STD_OUTPUT_HANDLE;
11168 break;
11169 case 2: nhandle = STD_ERROR_HANDLE;
11170 break;
11171 default:
11172 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11173 }
11174 handle = GetStdHandle(nhandle);
11175 if (handle == NULL)
11176 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11177 if (handle == INVALID_HANDLE_VALUE)
11178 return PyErr_SetFromWindowsErr(0);
11179
11180 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11181 return PyErr_SetFromWindowsErr(0);
11182
11183 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11184 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11185 }
11186#endif /* TERMSIZE_USE_CONIO */
11187
11188 termsize = PyStructSequence_New(&TerminalSizeType);
11189 if (termsize == NULL)
11190 return NULL;
11191 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11192 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11193 if (PyErr_Occurred()) {
11194 Py_DECREF(termsize);
11195 return NULL;
11196 }
11197 return termsize;
11198}
11199#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11200
Larry Hastings2f936352014-08-05 14:04:04 +100011201
11202/*[clinic input]
11203os.cpu_count
11204
11205Return the number of CPUs in the system; return None if indeterminable.
11206[clinic start generated code]*/
11207
Larry Hastings2f936352014-08-05 14:04:04 +100011208static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011209os_cpu_count_impl(PyObject *module)
11210/*[clinic end generated code: output=5fc29463c3936a9c input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011211{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011212 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011213#ifdef MS_WINDOWS
11214 SYSTEM_INFO sysinfo;
11215 GetSystemInfo(&sysinfo);
11216 ncpu = sysinfo.dwNumberOfProcessors;
11217#elif defined(__hpux)
11218 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11219#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11220 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011221#elif defined(__DragonFly__) || \
11222 defined(__OpenBSD__) || \
11223 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011224 defined(__NetBSD__) || \
11225 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011226 int mib[2];
11227 size_t len = sizeof(ncpu);
11228 mib[0] = CTL_HW;
11229 mib[1] = HW_NCPU;
11230 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11231 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011232#endif
11233 if (ncpu >= 1)
11234 return PyLong_FromLong(ncpu);
11235 else
11236 Py_RETURN_NONE;
11237}
11238
Victor Stinnerdaf45552013-08-28 00:53:59 +020011239
Larry Hastings2f936352014-08-05 14:04:04 +100011240/*[clinic input]
11241os.get_inheritable -> bool
11242
11243 fd: int
11244 /
11245
11246Get the close-on-exe flag of the specified file descriptor.
11247[clinic start generated code]*/
11248
Larry Hastings2f936352014-08-05 14:04:04 +100011249static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011250os_get_inheritable_impl(PyObject *module, int fd)
11251/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011252{
Steve Dower8fc89802015-04-12 00:26:27 -040011253 int return_value;
11254 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011255 posix_error();
11256 return -1;
11257 }
11258
Steve Dower8fc89802015-04-12 00:26:27 -040011259 _Py_BEGIN_SUPPRESS_IPH
11260 return_value = _Py_get_inheritable(fd);
11261 _Py_END_SUPPRESS_IPH
11262 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011263}
11264
11265
11266/*[clinic input]
11267os.set_inheritable
11268 fd: int
11269 inheritable: int
11270 /
11271
11272Set the inheritable flag of the specified file descriptor.
11273[clinic start generated code]*/
11274
Larry Hastings2f936352014-08-05 14:04:04 +100011275static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011276os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11277/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011278{
Steve Dower8fc89802015-04-12 00:26:27 -040011279 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011280 if (!_PyVerify_fd(fd))
11281 return posix_error();
11282
Steve Dower8fc89802015-04-12 00:26:27 -040011283 _Py_BEGIN_SUPPRESS_IPH
11284 result = _Py_set_inheritable(fd, inheritable, NULL);
11285 _Py_END_SUPPRESS_IPH
11286 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011287 return NULL;
11288 Py_RETURN_NONE;
11289}
11290
11291
11292#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011293/*[clinic input]
11294os.get_handle_inheritable -> bool
11295 handle: Py_intptr_t
11296 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011297
Larry Hastings2f936352014-08-05 14:04:04 +100011298Get the close-on-exe flag of the specified file descriptor.
11299[clinic start generated code]*/
11300
Larry Hastings2f936352014-08-05 14:04:04 +100011301static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011302os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11303/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011304{
11305 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011306
11307 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11308 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011309 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011310 }
11311
Larry Hastings2f936352014-08-05 14:04:04 +100011312 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011313}
11314
Victor Stinnerdaf45552013-08-28 00:53:59 +020011315
Larry Hastings2f936352014-08-05 14:04:04 +100011316/*[clinic input]
11317os.set_handle_inheritable
11318 handle: Py_intptr_t
11319 inheritable: bool
11320 /
11321
11322Set the inheritable flag of the specified handle.
11323[clinic start generated code]*/
11324
Larry Hastings2f936352014-08-05 14:04:04 +100011325static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011326os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011327 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011328/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011329{
11330 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011331 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11332 PyErr_SetFromWindowsErr(0);
11333 return NULL;
11334 }
11335 Py_RETURN_NONE;
11336}
Larry Hastings2f936352014-08-05 14:04:04 +100011337#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011338
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011339#ifndef MS_WINDOWS
11340PyDoc_STRVAR(get_blocking__doc__,
11341 "get_blocking(fd) -> bool\n" \
11342 "\n" \
11343 "Get the blocking mode of the file descriptor:\n" \
11344 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11345
11346static PyObject*
11347posix_get_blocking(PyObject *self, PyObject *args)
11348{
11349 int fd;
11350 int blocking;
11351
11352 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11353 return NULL;
11354
11355 if (!_PyVerify_fd(fd))
11356 return posix_error();
11357
Steve Dower8fc89802015-04-12 00:26:27 -040011358 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011359 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011360 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011361 if (blocking < 0)
11362 return NULL;
11363 return PyBool_FromLong(blocking);
11364}
11365
11366PyDoc_STRVAR(set_blocking__doc__,
11367 "set_blocking(fd, blocking)\n" \
11368 "\n" \
11369 "Set the blocking mode of the specified file descriptor.\n" \
11370 "Set the O_NONBLOCK flag if blocking is False,\n" \
11371 "clear the O_NONBLOCK flag otherwise.");
11372
11373static PyObject*
11374posix_set_blocking(PyObject *self, PyObject *args)
11375{
Steve Dower8fc89802015-04-12 00:26:27 -040011376 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011377
11378 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11379 return NULL;
11380
11381 if (!_PyVerify_fd(fd))
11382 return posix_error();
11383
Steve Dower8fc89802015-04-12 00:26:27 -040011384 _Py_BEGIN_SUPPRESS_IPH
11385 result = _Py_set_blocking(fd, blocking);
11386 _Py_END_SUPPRESS_IPH
11387 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011388 return NULL;
11389 Py_RETURN_NONE;
11390}
11391#endif /* !MS_WINDOWS */
11392
11393
Victor Stinner6036e442015-03-08 01:58:04 +010011394PyDoc_STRVAR(posix_scandir__doc__,
11395"scandir(path='.') -> iterator of DirEntry objects for given path");
11396
11397static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11398
11399typedef struct {
11400 PyObject_HEAD
11401 PyObject *name;
11402 PyObject *path;
11403 PyObject *stat;
11404 PyObject *lstat;
11405#ifdef MS_WINDOWS
11406 struct _Py_stat_struct win32_lstat;
11407 __int64 win32_file_index;
11408 int got_file_index;
11409#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011410#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011411 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011412#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011413 ino_t d_ino;
11414#endif
11415} DirEntry;
11416
11417static void
11418DirEntry_dealloc(DirEntry *entry)
11419{
11420 Py_XDECREF(entry->name);
11421 Py_XDECREF(entry->path);
11422 Py_XDECREF(entry->stat);
11423 Py_XDECREF(entry->lstat);
11424 Py_TYPE(entry)->tp_free((PyObject *)entry);
11425}
11426
11427/* Forward reference */
11428static int
11429DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11430
11431/* Set exception and return -1 on error, 0 for False, 1 for True */
11432static int
11433DirEntry_is_symlink(DirEntry *self)
11434{
11435#ifdef MS_WINDOWS
11436 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011437#elif defined(HAVE_DIRENT_D_TYPE)
11438 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011439 if (self->d_type != DT_UNKNOWN)
11440 return self->d_type == DT_LNK;
11441 else
11442 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011443#else
11444 /* POSIX without d_type */
11445 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011446#endif
11447}
11448
11449static PyObject *
11450DirEntry_py_is_symlink(DirEntry *self)
11451{
11452 int result;
11453
11454 result = DirEntry_is_symlink(self);
11455 if (result == -1)
11456 return NULL;
11457 return PyBool_FromLong(result);
11458}
11459
11460static PyObject *
11461DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11462{
11463 int result;
11464 struct _Py_stat_struct st;
11465
11466#ifdef MS_WINDOWS
11467 wchar_t *path;
11468
11469 path = PyUnicode_AsUnicode(self->path);
11470 if (!path)
11471 return NULL;
11472
11473 if (follow_symlinks)
11474 result = win32_stat_w(path, &st);
11475 else
11476 result = win32_lstat_w(path, &st);
11477
11478 if (result != 0) {
11479 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11480 0, self->path);
11481 }
11482#else /* POSIX */
11483 PyObject *bytes;
11484 char *path;
11485
11486 if (!PyUnicode_FSConverter(self->path, &bytes))
11487 return NULL;
11488 path = PyBytes_AS_STRING(bytes);
11489
11490 if (follow_symlinks)
11491 result = STAT(path, &st);
11492 else
11493 result = LSTAT(path, &st);
11494 Py_DECREF(bytes);
11495
11496 if (result != 0)
11497 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11498#endif
11499
11500 return _pystat_fromstructstat(&st);
11501}
11502
11503static PyObject *
11504DirEntry_get_lstat(DirEntry *self)
11505{
11506 if (!self->lstat) {
11507#ifdef MS_WINDOWS
11508 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11509#else /* POSIX */
11510 self->lstat = DirEntry_fetch_stat(self, 0);
11511#endif
11512 }
11513 Py_XINCREF(self->lstat);
11514 return self->lstat;
11515}
11516
11517static PyObject *
11518DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11519{
11520 if (!follow_symlinks)
11521 return DirEntry_get_lstat(self);
11522
11523 if (!self->stat) {
11524 int result = DirEntry_is_symlink(self);
11525 if (result == -1)
11526 return NULL;
11527 else if (result)
11528 self->stat = DirEntry_fetch_stat(self, 1);
11529 else
11530 self->stat = DirEntry_get_lstat(self);
11531 }
11532
11533 Py_XINCREF(self->stat);
11534 return self->stat;
11535}
11536
11537static PyObject *
11538DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11539{
11540 int follow_symlinks = 1;
11541
11542 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11543 follow_symlinks_keywords, &follow_symlinks))
11544 return NULL;
11545
11546 return DirEntry_get_stat(self, follow_symlinks);
11547}
11548
11549/* Set exception and return -1 on error, 0 for False, 1 for True */
11550static int
11551DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11552{
11553 PyObject *stat = NULL;
11554 PyObject *st_mode = NULL;
11555 long mode;
11556 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011557#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011558 int is_symlink;
11559 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011560#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011561#ifdef MS_WINDOWS
11562 unsigned long dir_bits;
11563#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011564 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011565
11566#ifdef MS_WINDOWS
11567 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11568 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011569#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011570 is_symlink = self->d_type == DT_LNK;
11571 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11572#endif
11573
Victor Stinner35a97c02015-03-08 02:59:09 +010011574#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011575 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011576#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011577 stat = DirEntry_get_stat(self, follow_symlinks);
11578 if (!stat) {
11579 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11580 /* If file doesn't exist (anymore), then return False
11581 (i.e., say it's not a file/directory) */
11582 PyErr_Clear();
11583 return 0;
11584 }
11585 goto error;
11586 }
11587 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11588 if (!st_mode)
11589 goto error;
11590
11591 mode = PyLong_AsLong(st_mode);
11592 if (mode == -1 && PyErr_Occurred())
11593 goto error;
11594 Py_CLEAR(st_mode);
11595 Py_CLEAR(stat);
11596 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011597#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011598 }
11599 else if (is_symlink) {
11600 assert(mode_bits != S_IFLNK);
11601 result = 0;
11602 }
11603 else {
11604 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11605#ifdef MS_WINDOWS
11606 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11607 if (mode_bits == S_IFDIR)
11608 result = dir_bits != 0;
11609 else
11610 result = dir_bits == 0;
11611#else /* POSIX */
11612 if (mode_bits == S_IFDIR)
11613 result = self->d_type == DT_DIR;
11614 else
11615 result = self->d_type == DT_REG;
11616#endif
11617 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011618#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011619
11620 return result;
11621
11622error:
11623 Py_XDECREF(st_mode);
11624 Py_XDECREF(stat);
11625 return -1;
11626}
11627
11628static PyObject *
11629DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11630{
11631 int result;
11632
11633 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11634 if (result == -1)
11635 return NULL;
11636 return PyBool_FromLong(result);
11637}
11638
11639static PyObject *
11640DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11641{
11642 int follow_symlinks = 1;
11643
11644 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11645 follow_symlinks_keywords, &follow_symlinks))
11646 return NULL;
11647
11648 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11649}
11650
11651static PyObject *
11652DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11653{
11654 int follow_symlinks = 1;
11655
11656 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11657 follow_symlinks_keywords, &follow_symlinks))
11658 return NULL;
11659
11660 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11661}
11662
11663static PyObject *
11664DirEntry_inode(DirEntry *self)
11665{
11666#ifdef MS_WINDOWS
11667 if (!self->got_file_index) {
11668 wchar_t *path;
11669 struct _Py_stat_struct stat;
11670
11671 path = PyUnicode_AsUnicode(self->path);
11672 if (!path)
11673 return NULL;
11674
11675 if (win32_lstat_w(path, &stat) != 0) {
11676 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11677 0, self->path);
11678 }
11679
11680 self->win32_file_index = stat.st_ino;
11681 self->got_file_index = 1;
11682 }
11683 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11684#else /* POSIX */
11685#ifdef HAVE_LARGEFILE_SUPPORT
11686 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11687#else
11688 return PyLong_FromLong((long)self->d_ino);
11689#endif
11690#endif
11691}
11692
11693static PyObject *
11694DirEntry_repr(DirEntry *self)
11695{
11696 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11697}
11698
11699static PyMemberDef DirEntry_members[] = {
11700 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11701 "the entry's base filename, relative to scandir() \"path\" argument"},
11702 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11703 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11704 {NULL}
11705};
11706
11707static PyMethodDef DirEntry_methods[] = {
11708 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11709 "return True if the entry is a directory; cached per entry"
11710 },
11711 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11712 "return True if the entry is a file; cached per entry"
11713 },
11714 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11715 "return True if the entry is a symbolic link; cached per entry"
11716 },
11717 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11718 "return stat_result object for the entry; cached per entry"
11719 },
11720 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11721 "return inode of the entry; cached per entry",
11722 },
11723 {NULL}
11724};
11725
Benjamin Peterson5646de42015-04-12 17:56:34 -040011726static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011727 PyVarObject_HEAD_INIT(NULL, 0)
11728 MODNAME ".DirEntry", /* tp_name */
11729 sizeof(DirEntry), /* tp_basicsize */
11730 0, /* tp_itemsize */
11731 /* methods */
11732 (destructor)DirEntry_dealloc, /* tp_dealloc */
11733 0, /* tp_print */
11734 0, /* tp_getattr */
11735 0, /* tp_setattr */
11736 0, /* tp_compare */
11737 (reprfunc)DirEntry_repr, /* tp_repr */
11738 0, /* tp_as_number */
11739 0, /* tp_as_sequence */
11740 0, /* tp_as_mapping */
11741 0, /* tp_hash */
11742 0, /* tp_call */
11743 0, /* tp_str */
11744 0, /* tp_getattro */
11745 0, /* tp_setattro */
11746 0, /* tp_as_buffer */
11747 Py_TPFLAGS_DEFAULT, /* tp_flags */
11748 0, /* tp_doc */
11749 0, /* tp_traverse */
11750 0, /* tp_clear */
11751 0, /* tp_richcompare */
11752 0, /* tp_weaklistoffset */
11753 0, /* tp_iter */
11754 0, /* tp_iternext */
11755 DirEntry_methods, /* tp_methods */
11756 DirEntry_members, /* tp_members */
11757};
11758
11759#ifdef MS_WINDOWS
11760
11761static wchar_t *
11762join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11763{
11764 Py_ssize_t path_len;
11765 Py_ssize_t size;
11766 wchar_t *result;
11767 wchar_t ch;
11768
11769 if (!path_wide) { /* Default arg: "." */
11770 path_wide = L".";
11771 path_len = 1;
11772 }
11773 else {
11774 path_len = wcslen(path_wide);
11775 }
11776
11777 /* The +1's are for the path separator and the NUL */
11778 size = path_len + 1 + wcslen(filename) + 1;
11779 result = PyMem_New(wchar_t, size);
11780 if (!result) {
11781 PyErr_NoMemory();
11782 return NULL;
11783 }
11784 wcscpy(result, path_wide);
11785 if (path_len > 0) {
11786 ch = result[path_len - 1];
11787 if (ch != SEP && ch != ALTSEP && ch != L':')
11788 result[path_len++] = SEP;
11789 wcscpy(result + path_len, filename);
11790 }
11791 return result;
11792}
11793
11794static PyObject *
11795DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11796{
11797 DirEntry *entry;
11798 BY_HANDLE_FILE_INFORMATION file_info;
11799 ULONG reparse_tag;
11800 wchar_t *joined_path;
11801
11802 entry = PyObject_New(DirEntry, &DirEntryType);
11803 if (!entry)
11804 return NULL;
11805 entry->name = NULL;
11806 entry->path = NULL;
11807 entry->stat = NULL;
11808 entry->lstat = NULL;
11809 entry->got_file_index = 0;
11810
11811 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11812 if (!entry->name)
11813 goto error;
11814
11815 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11816 if (!joined_path)
11817 goto error;
11818
11819 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11820 PyMem_Free(joined_path);
11821 if (!entry->path)
11822 goto error;
11823
11824 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11825 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11826
11827 return (PyObject *)entry;
11828
11829error:
11830 Py_DECREF(entry);
11831 return NULL;
11832}
11833
11834#else /* POSIX */
11835
11836static char *
11837join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11838{
11839 Py_ssize_t path_len;
11840 Py_ssize_t size;
11841 char *result;
11842
11843 if (!path_narrow) { /* Default arg: "." */
11844 path_narrow = ".";
11845 path_len = 1;
11846 }
11847 else {
11848 path_len = strlen(path_narrow);
11849 }
11850
11851 if (filename_len == -1)
11852 filename_len = strlen(filename);
11853
11854 /* The +1's are for the path separator and the NUL */
11855 size = path_len + 1 + filename_len + 1;
11856 result = PyMem_New(char, size);
11857 if (!result) {
11858 PyErr_NoMemory();
11859 return NULL;
11860 }
11861 strcpy(result, path_narrow);
11862 if (path_len > 0 && result[path_len - 1] != '/')
11863 result[path_len++] = '/';
11864 strcpy(result + path_len, filename);
11865 return result;
11866}
11867
11868static PyObject *
11869DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011870 ino_t d_ino
11871#ifdef HAVE_DIRENT_D_TYPE
11872 , unsigned char d_type
11873#endif
11874 )
Victor Stinner6036e442015-03-08 01:58:04 +010011875{
11876 DirEntry *entry;
11877 char *joined_path;
11878
11879 entry = PyObject_New(DirEntry, &DirEntryType);
11880 if (!entry)
11881 return NULL;
11882 entry->name = NULL;
11883 entry->path = NULL;
11884 entry->stat = NULL;
11885 entry->lstat = NULL;
11886
11887 joined_path = join_path_filename(path->narrow, name, name_len);
11888 if (!joined_path)
11889 goto error;
11890
11891 if (!path->narrow || !PyBytes_Check(path->object)) {
11892 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11893 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11894 }
11895 else {
11896 entry->name = PyBytes_FromStringAndSize(name, name_len);
11897 entry->path = PyBytes_FromString(joined_path);
11898 }
11899 PyMem_Free(joined_path);
11900 if (!entry->name || !entry->path)
11901 goto error;
11902
Victor Stinner35a97c02015-03-08 02:59:09 +010011903#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011904 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011905#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011906 entry->d_ino = d_ino;
11907
11908 return (PyObject *)entry;
11909
11910error:
11911 Py_XDECREF(entry);
11912 return NULL;
11913}
11914
11915#endif
11916
11917
11918typedef struct {
11919 PyObject_HEAD
11920 path_t path;
11921#ifdef MS_WINDOWS
11922 HANDLE handle;
11923 WIN32_FIND_DATAW file_data;
11924 int first_time;
11925#else /* POSIX */
11926 DIR *dirp;
11927#endif
11928} ScandirIterator;
11929
11930#ifdef MS_WINDOWS
11931
11932static void
11933ScandirIterator_close(ScandirIterator *iterator)
11934{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011935 HANDLE handle = iterator->handle;
11936
11937 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011938 return;
11939
Victor Stinner6036e442015-03-08 01:58:04 +010011940 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011941 Py_BEGIN_ALLOW_THREADS
11942 FindClose(handle);
11943 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011944}
11945
11946static PyObject *
11947ScandirIterator_iternext(ScandirIterator *iterator)
11948{
11949 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11950 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011951 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011952
11953 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011954 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011955 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011956
11957 while (1) {
11958 if (!iterator->first_time) {
11959 Py_BEGIN_ALLOW_THREADS
11960 success = FindNextFileW(iterator->handle, file_data);
11961 Py_END_ALLOW_THREADS
11962 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011963 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011964 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011965 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011966 break;
11967 }
11968 }
11969 iterator->first_time = 0;
11970
11971 /* Skip over . and .. */
11972 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011973 wcscmp(file_data->cFileName, L"..") != 0) {
11974 entry = DirEntry_from_find_data(&iterator->path, file_data);
11975 if (!entry)
11976 break;
11977 return entry;
11978 }
Victor Stinner6036e442015-03-08 01:58:04 +010011979
11980 /* Loop till we get a non-dot directory or finish iterating */
11981 }
11982
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011983 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011984 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011985 return NULL;
11986}
11987
11988#else /* POSIX */
11989
11990static void
11991ScandirIterator_close(ScandirIterator *iterator)
11992{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011993 DIR *dirp = iterator->dirp;
11994
11995 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011996 return;
11997
Victor Stinner6036e442015-03-08 01:58:04 +010011998 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011999 Py_BEGIN_ALLOW_THREADS
12000 closedir(dirp);
12001 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012002 return;
12003}
12004
12005static PyObject *
12006ScandirIterator_iternext(ScandirIterator *iterator)
12007{
12008 struct dirent *direntp;
12009 Py_ssize_t name_len;
12010 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012011 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012012
12013 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012014 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012015 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012016
12017 while (1) {
12018 errno = 0;
12019 Py_BEGIN_ALLOW_THREADS
12020 direntp = readdir(iterator->dirp);
12021 Py_END_ALLOW_THREADS
12022
12023 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012024 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012025 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012026 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012027 break;
12028 }
12029
12030 /* Skip over . and .. */
12031 name_len = NAMLEN(direntp);
12032 is_dot = direntp->d_name[0] == '.' &&
12033 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12034 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012035 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012036 name_len, direntp->d_ino
12037#ifdef HAVE_DIRENT_D_TYPE
12038 , direntp->d_type
12039#endif
12040 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012041 if (!entry)
12042 break;
12043 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012044 }
12045
12046 /* Loop till we get a non-dot directory or finish iterating */
12047 }
12048
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012049 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012050 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012051 return NULL;
12052}
12053
12054#endif
12055
12056static void
12057ScandirIterator_dealloc(ScandirIterator *iterator)
12058{
12059 ScandirIterator_close(iterator);
12060 Py_XDECREF(iterator->path.object);
12061 path_cleanup(&iterator->path);
12062 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12063}
12064
Benjamin Peterson5646de42015-04-12 17:56:34 -040012065static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012066 PyVarObject_HEAD_INIT(NULL, 0)
12067 MODNAME ".ScandirIterator", /* tp_name */
12068 sizeof(ScandirIterator), /* tp_basicsize */
12069 0, /* tp_itemsize */
12070 /* methods */
12071 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12072 0, /* tp_print */
12073 0, /* tp_getattr */
12074 0, /* tp_setattr */
12075 0, /* tp_compare */
12076 0, /* tp_repr */
12077 0, /* tp_as_number */
12078 0, /* tp_as_sequence */
12079 0, /* tp_as_mapping */
12080 0, /* tp_hash */
12081 0, /* tp_call */
12082 0, /* tp_str */
12083 0, /* tp_getattro */
12084 0, /* tp_setattro */
12085 0, /* tp_as_buffer */
12086 Py_TPFLAGS_DEFAULT, /* tp_flags */
12087 0, /* tp_doc */
12088 0, /* tp_traverse */
12089 0, /* tp_clear */
12090 0, /* tp_richcompare */
12091 0, /* tp_weaklistoffset */
12092 PyObject_SelfIter, /* tp_iter */
12093 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12094};
12095
12096static PyObject *
12097posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12098{
12099 ScandirIterator *iterator;
12100 static char *keywords[] = {"path", NULL};
12101#ifdef MS_WINDOWS
12102 wchar_t *path_strW;
12103#else
12104 char *path;
12105#endif
12106
12107 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12108 if (!iterator)
12109 return NULL;
12110 memset(&iterator->path, 0, sizeof(path_t));
12111 iterator->path.function_name = "scandir";
12112 iterator->path.nullable = 1;
12113
12114#ifdef MS_WINDOWS
12115 iterator->handle = INVALID_HANDLE_VALUE;
12116#else
12117 iterator->dirp = NULL;
12118#endif
12119
12120 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12121 path_converter, &iterator->path))
12122 goto error;
12123
12124 /* path_converter doesn't keep path.object around, so do it
12125 manually for the lifetime of the iterator here (the refcount
12126 is decremented in ScandirIterator_dealloc)
12127 */
12128 Py_XINCREF(iterator->path.object);
12129
12130#ifdef MS_WINDOWS
12131 if (iterator->path.narrow) {
12132 PyErr_SetString(PyExc_TypeError,
12133 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12134 goto error;
12135 }
12136 iterator->first_time = 1;
12137
12138 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12139 if (!path_strW)
12140 goto error;
12141
12142 Py_BEGIN_ALLOW_THREADS
12143 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12144 Py_END_ALLOW_THREADS
12145
12146 PyMem_Free(path_strW);
12147
12148 if (iterator->handle == INVALID_HANDLE_VALUE) {
12149 path_error(&iterator->path);
12150 goto error;
12151 }
12152#else /* POSIX */
12153 if (iterator->path.narrow)
12154 path = iterator->path.narrow;
12155 else
12156 path = ".";
12157
12158 errno = 0;
12159 Py_BEGIN_ALLOW_THREADS
12160 iterator->dirp = opendir(path);
12161 Py_END_ALLOW_THREADS
12162
12163 if (!iterator->dirp) {
12164 path_error(&iterator->path);
12165 goto error;
12166 }
12167#endif
12168
12169 return (PyObject *)iterator;
12170
12171error:
12172 Py_DECREF(iterator);
12173 return NULL;
12174}
12175
12176
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012177#include "clinic/posixmodule.c.h"
12178
Larry Hastings7726ac92014-01-31 22:03:12 -080012179/*[clinic input]
12180dump buffer
12181[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012182/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012183
Larry Hastings31826802013-10-19 00:09:25 -070012184
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012185static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012186
12187 OS_STAT_METHODDEF
12188 OS_ACCESS_METHODDEF
12189 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012190 OS_CHDIR_METHODDEF
12191 OS_CHFLAGS_METHODDEF
12192 OS_CHMOD_METHODDEF
12193 OS_FCHMOD_METHODDEF
12194 OS_LCHMOD_METHODDEF
12195 OS_CHOWN_METHODDEF
12196 OS_FCHOWN_METHODDEF
12197 OS_LCHOWN_METHODDEF
12198 OS_LCHFLAGS_METHODDEF
12199 OS_CHROOT_METHODDEF
12200 OS_CTERMID_METHODDEF
12201 OS_GETCWD_METHODDEF
12202 OS_GETCWDB_METHODDEF
12203 OS_LINK_METHODDEF
12204 OS_LISTDIR_METHODDEF
12205 OS_LSTAT_METHODDEF
12206 OS_MKDIR_METHODDEF
12207 OS_NICE_METHODDEF
12208 OS_GETPRIORITY_METHODDEF
12209 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012210#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012211 {"readlink", (PyCFunction)posix_readlink,
12212 METH_VARARGS | METH_KEYWORDS,
12213 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012214#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012215#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012216 {"readlink", (PyCFunction)win_readlink,
12217 METH_VARARGS | METH_KEYWORDS,
12218 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012219#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012220 OS_RENAME_METHODDEF
12221 OS_REPLACE_METHODDEF
12222 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012223 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012224 OS_SYMLINK_METHODDEF
12225 OS_SYSTEM_METHODDEF
12226 OS_UMASK_METHODDEF
12227 OS_UNAME_METHODDEF
12228 OS_UNLINK_METHODDEF
12229 OS_REMOVE_METHODDEF
12230 OS_UTIME_METHODDEF
12231 OS_TIMES_METHODDEF
12232 OS__EXIT_METHODDEF
12233 OS_EXECV_METHODDEF
12234 OS_EXECVE_METHODDEF
12235 OS_SPAWNV_METHODDEF
12236 OS_SPAWNVE_METHODDEF
12237 OS_FORK1_METHODDEF
12238 OS_FORK_METHODDEF
12239 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12240 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12241 OS_SCHED_GETPARAM_METHODDEF
12242 OS_SCHED_GETSCHEDULER_METHODDEF
12243 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12244 OS_SCHED_SETPARAM_METHODDEF
12245 OS_SCHED_SETSCHEDULER_METHODDEF
12246 OS_SCHED_YIELD_METHODDEF
12247 OS_SCHED_SETAFFINITY_METHODDEF
12248 OS_SCHED_GETAFFINITY_METHODDEF
12249 OS_OPENPTY_METHODDEF
12250 OS_FORKPTY_METHODDEF
12251 OS_GETEGID_METHODDEF
12252 OS_GETEUID_METHODDEF
12253 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012254#ifdef HAVE_GETGROUPLIST
12255 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12256#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012257 OS_GETGROUPS_METHODDEF
12258 OS_GETPID_METHODDEF
12259 OS_GETPGRP_METHODDEF
12260 OS_GETPPID_METHODDEF
12261 OS_GETUID_METHODDEF
12262 OS_GETLOGIN_METHODDEF
12263 OS_KILL_METHODDEF
12264 OS_KILLPG_METHODDEF
12265 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012266#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012267 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012268#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012269 OS_SETUID_METHODDEF
12270 OS_SETEUID_METHODDEF
12271 OS_SETREUID_METHODDEF
12272 OS_SETGID_METHODDEF
12273 OS_SETEGID_METHODDEF
12274 OS_SETREGID_METHODDEF
12275 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012276#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012277 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012278#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012279 OS_GETPGID_METHODDEF
12280 OS_SETPGRP_METHODDEF
12281 OS_WAIT_METHODDEF
12282 OS_WAIT3_METHODDEF
12283 OS_WAIT4_METHODDEF
12284 OS_WAITID_METHODDEF
12285 OS_WAITPID_METHODDEF
12286 OS_GETSID_METHODDEF
12287 OS_SETSID_METHODDEF
12288 OS_SETPGID_METHODDEF
12289 OS_TCGETPGRP_METHODDEF
12290 OS_TCSETPGRP_METHODDEF
12291 OS_OPEN_METHODDEF
12292 OS_CLOSE_METHODDEF
12293 OS_CLOSERANGE_METHODDEF
12294 OS_DEVICE_ENCODING_METHODDEF
12295 OS_DUP_METHODDEF
12296 OS_DUP2_METHODDEF
12297 OS_LOCKF_METHODDEF
12298 OS_LSEEK_METHODDEF
12299 OS_READ_METHODDEF
12300 OS_READV_METHODDEF
12301 OS_PREAD_METHODDEF
12302 OS_WRITE_METHODDEF
12303 OS_WRITEV_METHODDEF
12304 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012305#ifdef HAVE_SENDFILE
12306 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12307 posix_sendfile__doc__},
12308#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012309 OS_FSTAT_METHODDEF
12310 OS_ISATTY_METHODDEF
12311 OS_PIPE_METHODDEF
12312 OS_PIPE2_METHODDEF
12313 OS_MKFIFO_METHODDEF
12314 OS_MKNOD_METHODDEF
12315 OS_MAJOR_METHODDEF
12316 OS_MINOR_METHODDEF
12317 OS_MAKEDEV_METHODDEF
12318 OS_FTRUNCATE_METHODDEF
12319 OS_TRUNCATE_METHODDEF
12320 OS_POSIX_FALLOCATE_METHODDEF
12321 OS_POSIX_FADVISE_METHODDEF
12322 OS_PUTENV_METHODDEF
12323 OS_UNSETENV_METHODDEF
12324 OS_STRERROR_METHODDEF
12325 OS_FCHDIR_METHODDEF
12326 OS_FSYNC_METHODDEF
12327 OS_SYNC_METHODDEF
12328 OS_FDATASYNC_METHODDEF
12329 OS_WCOREDUMP_METHODDEF
12330 OS_WIFCONTINUED_METHODDEF
12331 OS_WIFSTOPPED_METHODDEF
12332 OS_WIFSIGNALED_METHODDEF
12333 OS_WIFEXITED_METHODDEF
12334 OS_WEXITSTATUS_METHODDEF
12335 OS_WTERMSIG_METHODDEF
12336 OS_WSTOPSIG_METHODDEF
12337 OS_FSTATVFS_METHODDEF
12338 OS_STATVFS_METHODDEF
12339 OS_CONFSTR_METHODDEF
12340 OS_SYSCONF_METHODDEF
12341 OS_FPATHCONF_METHODDEF
12342 OS_PATHCONF_METHODDEF
12343 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012344 OS__GETFULLPATHNAME_METHODDEF
12345 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012346 OS__GETDISKUSAGE_METHODDEF
12347 OS__GETFINALPATHNAME_METHODDEF
12348 OS__GETVOLUMEPATHNAME_METHODDEF
12349 OS_GETLOADAVG_METHODDEF
12350 OS_URANDOM_METHODDEF
12351 OS_SETRESUID_METHODDEF
12352 OS_SETRESGID_METHODDEF
12353 OS_GETRESUID_METHODDEF
12354 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012355
Larry Hastings2f936352014-08-05 14:04:04 +100012356 OS_GETXATTR_METHODDEF
12357 OS_SETXATTR_METHODDEF
12358 OS_REMOVEXATTR_METHODDEF
12359 OS_LISTXATTR_METHODDEF
12360
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012361#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12362 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12363#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012364 OS_CPU_COUNT_METHODDEF
12365 OS_GET_INHERITABLE_METHODDEF
12366 OS_SET_INHERITABLE_METHODDEF
12367 OS_GET_HANDLE_INHERITABLE_METHODDEF
12368 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012369#ifndef MS_WINDOWS
12370 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12371 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12372#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012373 {"scandir", (PyCFunction)posix_scandir,
12374 METH_VARARGS | METH_KEYWORDS,
12375 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012376 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012377};
12378
12379
Brian Curtin52173d42010-12-02 18:29:18 +000012380#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012381static int
Brian Curtin52173d42010-12-02 18:29:18 +000012382enable_symlink()
12383{
12384 HANDLE tok;
12385 TOKEN_PRIVILEGES tok_priv;
12386 LUID luid;
12387 int meth_idx = 0;
12388
12389 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012390 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012391
12392 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012393 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012394
12395 tok_priv.PrivilegeCount = 1;
12396 tok_priv.Privileges[0].Luid = luid;
12397 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12398
12399 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12400 sizeof(TOKEN_PRIVILEGES),
12401 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012402 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012403
Brian Curtin3b4499c2010-12-28 14:31:47 +000012404 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12405 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012406}
12407#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12408
Barry Warsaw4a342091996-12-19 23:50:02 +000012409static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012410all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012411{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012412#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012413 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012414#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012415#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012416 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012417#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012418#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012419 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012420#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012421#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012422 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012423#endif
Fred Drakec9680921999-12-13 16:37:25 +000012424#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012425 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012426#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012427#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012428 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012429#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012430#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012431 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012432#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012433#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012434 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012435#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012436#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012437 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012438#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012439#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012441#endif
12442#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012443 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012444#endif
12445#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012446 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012447#endif
12448#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012449 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012450#endif
12451#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012453#endif
12454#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012456#endif
12457#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012459#endif
12460#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012462#endif
12463#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012464 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012465#endif
12466#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012468#endif
12469#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012471#endif
12472#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012473 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012474#endif
12475#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012477#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012478#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012480#endif
12481#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012483#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012484#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012486#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012487#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012489#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012490#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012492#endif
12493#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012494 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012495#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012496#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012498#endif
12499#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012501#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012502#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012503 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012504#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012505#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012507#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012508#ifdef O_TMPFILE
12509 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12510#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012511#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012512 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012513#endif
12514#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012516#endif
12517#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012518 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012519#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012520#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012522#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012523#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012525#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012526
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012527
Jesus Cea94363612012-06-22 18:32:07 +020012528#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012530#endif
12531#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012532 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012533#endif
12534
Tim Peters5aa91602002-01-30 05:46:57 +000012535/* MS Windows */
12536#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012537 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012538 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012539#endif
12540#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012541 /* Optimize for short life (keep in memory). */
12542 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012544#endif
12545#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012548#endif
12549#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012550 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012551 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012552#endif
12553#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012554 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012556#endif
12557
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012558/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012559#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012560 /* Send a SIGIO signal whenever input or output
12561 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012563#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012564#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012567#endif
12568#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012569 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012571#endif
12572#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012573 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012575#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012576#ifdef O_NOLINKS
12577 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012579#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012580#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012581 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012583#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012584
Victor Stinner8c62be82010-05-06 00:08:46 +000012585 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012586#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012588#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012589#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012591#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012592#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012594#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012595#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012597#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012598#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012600#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012601#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012603#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012604#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012606#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012607#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012609#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012610#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012612#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012613#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012615#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012616#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012618#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012619#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012621#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012622#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012624#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012625#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012626 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012627#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012628#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012629 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012630#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012631#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012633#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012634#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012636#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012637
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012638 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012639#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012641#endif /* ST_RDONLY */
12642#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012644#endif /* ST_NOSUID */
12645
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012646 /* GNU extensions */
12647#ifdef ST_NODEV
12648 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12649#endif /* ST_NODEV */
12650#ifdef ST_NOEXEC
12651 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12652#endif /* ST_NOEXEC */
12653#ifdef ST_SYNCHRONOUS
12654 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12655#endif /* ST_SYNCHRONOUS */
12656#ifdef ST_MANDLOCK
12657 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12658#endif /* ST_MANDLOCK */
12659#ifdef ST_WRITE
12660 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12661#endif /* ST_WRITE */
12662#ifdef ST_APPEND
12663 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12664#endif /* ST_APPEND */
12665#ifdef ST_NOATIME
12666 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12667#endif /* ST_NOATIME */
12668#ifdef ST_NODIRATIME
12669 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12670#endif /* ST_NODIRATIME */
12671#ifdef ST_RELATIME
12672 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12673#endif /* ST_RELATIME */
12674
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012675 /* FreeBSD sendfile() constants */
12676#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012678#endif
12679#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012681#endif
12682#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012684#endif
12685
Ross Lagerwall7807c352011-03-17 20:20:30 +020012686 /* constants for posix_fadvise */
12687#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012689#endif
12690#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012692#endif
12693#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012695#endif
12696#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012698#endif
12699#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012701#endif
12702#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012704#endif
12705
12706 /* constants for waitid */
12707#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12709 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12710 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012711#endif
12712#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012714#endif
12715#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012717#endif
12718#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012719 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012720#endif
12721#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012723#endif
12724#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012726#endif
12727#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012729#endif
12730#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012732#endif
12733
12734 /* constants for lockf */
12735#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012736 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012737#endif
12738#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012739 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012740#endif
12741#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012742 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012743#endif
12744#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012745 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012746#endif
12747
Guido van Rossum246bc171999-02-01 23:54:31 +000012748#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12750 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12751 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12752 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12753 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012754#endif
12755
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012756#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012757#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012758 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012759#endif
12760#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012762#endif
12763#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012765#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012766#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012768#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012769#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012771#endif
12772#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012774#endif
12775#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012777#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012778#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012780#endif
12781#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012783#endif
12784#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012786#endif
12787#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012789#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012790#endif
12791
Benjamin Peterson9428d532011-09-14 11:45:52 -040012792#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012793 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12794 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12795 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012796#endif
12797
Victor Stinner8b905bd2011-10-25 13:34:04 +020012798#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012800#endif
12801#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012802 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012803#endif
12804#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012805 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012806#endif
12807#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012809#endif
12810#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012812#endif
12813#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012814 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012815#endif
12816#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012817 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012818#endif
12819
Victor Stinner8c62be82010-05-06 00:08:46 +000012820 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012821}
12822
12823
Martin v. Löwis1a214512008-06-11 05:26:20 +000012824static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012825 PyModuleDef_HEAD_INIT,
12826 MODNAME,
12827 posix__doc__,
12828 -1,
12829 posix_methods,
12830 NULL,
12831 NULL,
12832 NULL,
12833 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012834};
12835
12836
Larry Hastings9cf065c2012-06-22 16:30:09 -070012837static char *have_functions[] = {
12838
12839#ifdef HAVE_FACCESSAT
12840 "HAVE_FACCESSAT",
12841#endif
12842
12843#ifdef HAVE_FCHDIR
12844 "HAVE_FCHDIR",
12845#endif
12846
12847#ifdef HAVE_FCHMOD
12848 "HAVE_FCHMOD",
12849#endif
12850
12851#ifdef HAVE_FCHMODAT
12852 "HAVE_FCHMODAT",
12853#endif
12854
12855#ifdef HAVE_FCHOWN
12856 "HAVE_FCHOWN",
12857#endif
12858
Larry Hastings00964ed2013-08-12 13:49:30 -040012859#ifdef HAVE_FCHOWNAT
12860 "HAVE_FCHOWNAT",
12861#endif
12862
Larry Hastings9cf065c2012-06-22 16:30:09 -070012863#ifdef HAVE_FEXECVE
12864 "HAVE_FEXECVE",
12865#endif
12866
12867#ifdef HAVE_FDOPENDIR
12868 "HAVE_FDOPENDIR",
12869#endif
12870
Georg Brandl306336b2012-06-24 12:55:33 +020012871#ifdef HAVE_FPATHCONF
12872 "HAVE_FPATHCONF",
12873#endif
12874
Larry Hastings9cf065c2012-06-22 16:30:09 -070012875#ifdef HAVE_FSTATAT
12876 "HAVE_FSTATAT",
12877#endif
12878
12879#ifdef HAVE_FSTATVFS
12880 "HAVE_FSTATVFS",
12881#endif
12882
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012883#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012884 "HAVE_FTRUNCATE",
12885#endif
12886
Larry Hastings9cf065c2012-06-22 16:30:09 -070012887#ifdef HAVE_FUTIMENS
12888 "HAVE_FUTIMENS",
12889#endif
12890
12891#ifdef HAVE_FUTIMES
12892 "HAVE_FUTIMES",
12893#endif
12894
12895#ifdef HAVE_FUTIMESAT
12896 "HAVE_FUTIMESAT",
12897#endif
12898
12899#ifdef HAVE_LINKAT
12900 "HAVE_LINKAT",
12901#endif
12902
12903#ifdef HAVE_LCHFLAGS
12904 "HAVE_LCHFLAGS",
12905#endif
12906
12907#ifdef HAVE_LCHMOD
12908 "HAVE_LCHMOD",
12909#endif
12910
12911#ifdef HAVE_LCHOWN
12912 "HAVE_LCHOWN",
12913#endif
12914
12915#ifdef HAVE_LSTAT
12916 "HAVE_LSTAT",
12917#endif
12918
12919#ifdef HAVE_LUTIMES
12920 "HAVE_LUTIMES",
12921#endif
12922
12923#ifdef HAVE_MKDIRAT
12924 "HAVE_MKDIRAT",
12925#endif
12926
12927#ifdef HAVE_MKFIFOAT
12928 "HAVE_MKFIFOAT",
12929#endif
12930
12931#ifdef HAVE_MKNODAT
12932 "HAVE_MKNODAT",
12933#endif
12934
12935#ifdef HAVE_OPENAT
12936 "HAVE_OPENAT",
12937#endif
12938
12939#ifdef HAVE_READLINKAT
12940 "HAVE_READLINKAT",
12941#endif
12942
12943#ifdef HAVE_RENAMEAT
12944 "HAVE_RENAMEAT",
12945#endif
12946
12947#ifdef HAVE_SYMLINKAT
12948 "HAVE_SYMLINKAT",
12949#endif
12950
12951#ifdef HAVE_UNLINKAT
12952 "HAVE_UNLINKAT",
12953#endif
12954
12955#ifdef HAVE_UTIMENSAT
12956 "HAVE_UTIMENSAT",
12957#endif
12958
12959#ifdef MS_WINDOWS
12960 "MS_WINDOWS",
12961#endif
12962
12963 NULL
12964};
12965
12966
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012967PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012968INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012969{
Victor Stinner8c62be82010-05-06 00:08:46 +000012970 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012971 PyObject *list;
12972 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012973
Brian Curtin52173d42010-12-02 18:29:18 +000012974#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012975 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012976#endif
12977
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 m = PyModule_Create(&posixmodule);
12979 if (m == NULL)
12980 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012981
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 /* Initialize environ dictionary */
12983 v = convertenviron();
12984 Py_XINCREF(v);
12985 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12986 return NULL;
12987 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012988
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 if (all_ins(m))
12990 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012991
Victor Stinner8c62be82010-05-06 00:08:46 +000012992 if (setup_confname_tables(m))
12993 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012994
Victor Stinner8c62be82010-05-06 00:08:46 +000012995 Py_INCREF(PyExc_OSError);
12996 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012997
Guido van Rossumb3d39562000-01-31 18:41:26 +000012998#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012999 if (posix_putenv_garbage == NULL)
13000 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013001#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013002
Victor Stinner8c62be82010-05-06 00:08:46 +000013003 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013004#if defined(HAVE_WAITID) && !defined(__APPLE__)
13005 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013006 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13007 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013008#endif
13009
Christian Heimes25827622013-10-12 01:27:08 +020013010 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013011 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13012 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13013 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013014 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13015 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013016 structseq_new = StatResultType.tp_new;
13017 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013018
Christian Heimes25827622013-10-12 01:27:08 +020013019 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013020 if (PyStructSequence_InitType2(&StatVFSResultType,
13021 &statvfs_result_desc) < 0)
13022 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013023#ifdef NEED_TICKS_PER_SECOND
13024# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013025 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013026# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013027 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013028# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013029 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013030# endif
13031#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013032
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013033#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013034 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013035 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13036 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013037 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013038#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013039
13040 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013041 if (PyStructSequence_InitType2(&TerminalSizeType,
13042 &TerminalSize_desc) < 0)
13043 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013044
13045 /* initialize scandir types */
13046 if (PyType_Ready(&ScandirIteratorType) < 0)
13047 return NULL;
13048 if (PyType_Ready(&DirEntryType) < 0)
13049 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013050 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013051#if defined(HAVE_WAITID) && !defined(__APPLE__)
13052 Py_INCREF((PyObject*) &WaitidResultType);
13053 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13054#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013055 Py_INCREF((PyObject*) &StatResultType);
13056 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13057 Py_INCREF((PyObject*) &StatVFSResultType);
13058 PyModule_AddObject(m, "statvfs_result",
13059 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013060
13061#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013062 Py_INCREF(&SchedParamType);
13063 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013064#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013065
Larry Hastings605a62d2012-06-24 04:33:36 -070013066 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013067 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13068 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013069 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13070
13071 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013072 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13073 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013074 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13075
Thomas Wouters477c8d52006-05-27 19:21:47 +000013076#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013077 /*
13078 * Step 2 of weak-linking support on Mac OS X.
13079 *
13080 * The code below removes functions that are not available on the
13081 * currently active platform.
13082 *
13083 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013084 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013085 * OSX 10.4.
13086 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013087#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013088 if (fstatvfs == NULL) {
13089 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13090 return NULL;
13091 }
13092 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013093#endif /* HAVE_FSTATVFS */
13094
13095#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013096 if (statvfs == NULL) {
13097 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13098 return NULL;
13099 }
13100 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013101#endif /* HAVE_STATVFS */
13102
13103# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013104 if (lchown == NULL) {
13105 if (PyObject_DelAttrString(m, "lchown") == -1) {
13106 return NULL;
13107 }
13108 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013109#endif /* HAVE_LCHOWN */
13110
13111
13112#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013113
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013114 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013115 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13116
Larry Hastings6fe20b32012-04-19 15:07:49 -070013117 billion = PyLong_FromLong(1000000000);
13118 if (!billion)
13119 return NULL;
13120
Larry Hastings9cf065c2012-06-22 16:30:09 -070013121 /* suppress "function not used" warnings */
13122 {
13123 int ignored;
13124 fd_specified("", -1);
13125 follow_symlinks_specified("", 1);
13126 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13127 dir_fd_converter(Py_None, &ignored);
13128 dir_fd_unavailable(Py_None, &ignored);
13129 }
13130
13131 /*
13132 * provide list of locally available functions
13133 * so os.py can populate support_* lists
13134 */
13135 list = PyList_New(0);
13136 if (!list)
13137 return NULL;
13138 for (trace = have_functions; *trace; trace++) {
13139 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13140 if (!unicode)
13141 return NULL;
13142 if (PyList_Append(list, unicode))
13143 return NULL;
13144 Py_DECREF(unicode);
13145 }
13146 PyModule_AddObject(m, "_have_functions", list);
13147
13148 initialized = 1;
13149
Victor Stinner8c62be82010-05-06 00:08:46 +000013150 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013151}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013152
13153#ifdef __cplusplus
13154}
13155#endif