blob: becf65489c164abe599020801fb02818dc440b27 [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. */
1610 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001611 return -1;
1612 /* Could not get attributes on open file. Fall back to
1613 reading the directory. */
1614 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1615 /* Very strange. This should not fail now */
1616 return -1;
1617 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1618 if (traverse) {
1619 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001620 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001621 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001622 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001623 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 } else {
1625 if (!GetFileInformationByHandle(hFile, &info)) {
1626 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001627 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001628 }
1629 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001630 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1631 return -1;
1632
1633 /* Close the outer open file handle now that we're about to
1634 reopen it with different flags. */
1635 if (!CloseHandle(hFile))
1636 return -1;
1637
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001638 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001639 /* In order to call GetFinalPathNameByHandle we need to open
1640 the file without the reparse handling flag set. */
1641 hFile2 = CreateFileW(
1642 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1643 NULL, OPEN_EXISTING,
1644 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1645 NULL);
1646 if (hFile2 == INVALID_HANDLE_VALUE)
1647 return -1;
1648
1649 if (!get_target_path(hFile2, &target_path))
1650 return -1;
1651
1652 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001653 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001654 return code;
1655 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001656 } else
1657 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001658 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001659 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660
1661 /* Set S_IEXEC if it is an .exe, .bat, ... */
1662 dot = wcsrchr(path, '.');
1663 if (dot) {
1664 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1665 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1666 result->st_mode |= 0111;
1667 }
1668 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669}
1670
1671static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001672win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001673{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674 /* Protocol violation: we explicitly clear errno, instead of
1675 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001676 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677 errno = 0;
1678 return code;
1679}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001680
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001681static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001682win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683{
1684 /* Protocol violation: we explicitly clear errno, instead of
1685 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001686 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001687 errno = 0;
1688 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001689}
Brian Curtind25aef52011-06-13 15:16:04 -05001690/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001691
1692 In Posix, stat automatically traverses symlinks and returns the stat
1693 structure for the target. In Windows, the equivalent GetFileAttributes by
1694 default does not traverse symlinks and instead returns attributes for
1695 the symlink.
1696
1697 Therefore, win32_lstat will get the attributes traditionally, and
1698 win32_stat will first explicitly resolve the symlink target and then will
1699 call win32_lstat on that result.
1700
Ezio Melotti4969f702011-03-15 05:59:46 +02001701 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001702
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001703static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001704win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001705{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001706 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001707}
1708
Victor Stinner8c62be82010-05-06 00:08:46 +00001709static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001710win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001711{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001712 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001713}
1714
1715static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001716win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001717{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001718 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001719}
1720
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001721static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001722win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001723{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001724 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001725}
1726
Martin v. Löwis14694662006-02-03 12:54:16 +00001727#endif /* MS_WINDOWS */
1728
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001729PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001730"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001731This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001732 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001733or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1734\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001735Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1736or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001737\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001738See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001739
1740static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001741 {"st_mode", "protection bits"},
1742 {"st_ino", "inode"},
1743 {"st_dev", "device"},
1744 {"st_nlink", "number of hard links"},
1745 {"st_uid", "user ID of owner"},
1746 {"st_gid", "group ID of owner"},
1747 {"st_size", "total size, in bytes"},
1748 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1749 {NULL, "integer time of last access"},
1750 {NULL, "integer time of last modification"},
1751 {NULL, "integer time of last change"},
1752 {"st_atime", "time of last access"},
1753 {"st_mtime", "time of last modification"},
1754 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001755 {"st_atime_ns", "time of last access in nanoseconds"},
1756 {"st_mtime_ns", "time of last modification in nanoseconds"},
1757 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001758#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001759 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001760#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001761#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001762 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001763#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001764#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001765 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001766#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001767#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001769#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001770#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001771 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001772#endif
1773#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001775#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001776#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1777 {"st_file_attributes", "Windows file attribute bits"},
1778#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001779 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780};
1781
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001782#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001783#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001784#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001785#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#endif
1787
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001788#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1790#else
1791#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1792#endif
1793
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001794#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001795#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1796#else
1797#define ST_RDEV_IDX ST_BLOCKS_IDX
1798#endif
1799
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001800#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1801#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1802#else
1803#define ST_FLAGS_IDX ST_RDEV_IDX
1804#endif
1805
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001806#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001807#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001808#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001809#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001810#endif
1811
1812#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1813#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1814#else
1815#define ST_BIRTHTIME_IDX ST_GEN_IDX
1816#endif
1817
Zachary Ware63f277b2014-06-19 09:46:37 -05001818#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1819#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1820#else
1821#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1822#endif
1823
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001824static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001825 "stat_result", /* name */
1826 stat_result__doc__, /* doc */
1827 stat_result_fields,
1828 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829};
1830
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001831PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001832"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1833This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001834 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001835or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001836\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001837See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001838
1839static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001840 {"f_bsize", },
1841 {"f_frsize", },
1842 {"f_blocks", },
1843 {"f_bfree", },
1844 {"f_bavail", },
1845 {"f_files", },
1846 {"f_ffree", },
1847 {"f_favail", },
1848 {"f_flag", },
1849 {"f_namemax",},
1850 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001851};
1852
1853static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001854 "statvfs_result", /* name */
1855 statvfs_result__doc__, /* doc */
1856 statvfs_result_fields,
1857 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001858};
1859
Ross Lagerwall7807c352011-03-17 20:20:30 +02001860#if defined(HAVE_WAITID) && !defined(__APPLE__)
1861PyDoc_STRVAR(waitid_result__doc__,
1862"waitid_result: Result from waitid.\n\n\
1863This object may be accessed either as a tuple of\n\
1864 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1865or via the attributes si_pid, si_uid, and so on.\n\
1866\n\
1867See os.waitid for more information.");
1868
1869static PyStructSequence_Field waitid_result_fields[] = {
1870 {"si_pid", },
1871 {"si_uid", },
1872 {"si_signo", },
1873 {"si_status", },
1874 {"si_code", },
1875 {0}
1876};
1877
1878static PyStructSequence_Desc waitid_result_desc = {
1879 "waitid_result", /* name */
1880 waitid_result__doc__, /* doc */
1881 waitid_result_fields,
1882 5
1883};
1884static PyTypeObject WaitidResultType;
1885#endif
1886
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001887static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001888static PyTypeObject StatResultType;
1889static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001890#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001891static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001892#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001893static newfunc structseq_new;
1894
1895static PyObject *
1896statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1897{
Victor Stinner8c62be82010-05-06 00:08:46 +00001898 PyStructSequence *result;
1899 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001900
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 result = (PyStructSequence*)structseq_new(type, args, kwds);
1902 if (!result)
1903 return NULL;
1904 /* If we have been initialized from a tuple,
1905 st_?time might be set to None. Initialize it
1906 from the int slots. */
1907 for (i = 7; i <= 9; i++) {
1908 if (result->ob_item[i+3] == Py_None) {
1909 Py_DECREF(Py_None);
1910 Py_INCREF(result->ob_item[i]);
1911 result->ob_item[i+3] = result->ob_item[i];
1912 }
1913 }
1914 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001915}
1916
1917
1918
1919/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001920static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001921
1922PyDoc_STRVAR(stat_float_times__doc__,
1923"stat_float_times([newval]) -> oldval\n\n\
1924Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001925\n\
1926If value is True, future calls to stat() return floats; if it is False,\n\
1927future calls return ints.\n\
1928If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001929
Larry Hastings2f936352014-08-05 14:04:04 +10001930/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001931static PyObject*
1932stat_float_times(PyObject* self, PyObject *args)
1933{
Victor Stinner8c62be82010-05-06 00:08:46 +00001934 int newval = -1;
1935 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1936 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001937 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1938 "stat_float_times() is deprecated",
1939 1))
1940 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001941 if (newval == -1)
1942 /* Return old value */
1943 return PyBool_FromLong(_stat_float_times);
1944 _stat_float_times = newval;
1945 Py_INCREF(Py_None);
1946 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001947}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001948
Larry Hastings6fe20b32012-04-19 15:07:49 -07001949static PyObject *billion = NULL;
1950
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001951static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001952fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001953{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001954 PyObject *s = _PyLong_FromTime_t(sec);
1955 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1956 PyObject *s_in_ns = NULL;
1957 PyObject *ns_total = NULL;
1958 PyObject *float_s = NULL;
1959
1960 if (!(s && ns_fractional))
1961 goto exit;
1962
1963 s_in_ns = PyNumber_Multiply(s, billion);
1964 if (!s_in_ns)
1965 goto exit;
1966
1967 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1968 if (!ns_total)
1969 goto exit;
1970
Victor Stinner4195b5c2012-02-08 23:03:19 +01001971 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001972 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1973 if (!float_s)
1974 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001975 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001976 else {
1977 float_s = s;
1978 Py_INCREF(float_s);
1979 }
1980
1981 PyStructSequence_SET_ITEM(v, index, s);
1982 PyStructSequence_SET_ITEM(v, index+3, float_s);
1983 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1984 s = NULL;
1985 float_s = NULL;
1986 ns_total = NULL;
1987exit:
1988 Py_XDECREF(s);
1989 Py_XDECREF(ns_fractional);
1990 Py_XDECREF(s_in_ns);
1991 Py_XDECREF(ns_total);
1992 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001993}
1994
Tim Peters5aa91602002-01-30 05:46:57 +00001995/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001996 (used by posix_stat() and posix_fstat()) */
1997static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001998_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001999{
Victor Stinner8c62be82010-05-06 00:08:46 +00002000 unsigned long ansec, mnsec, cnsec;
2001 PyObject *v = PyStructSequence_New(&StatResultType);
2002 if (v == NULL)
2003 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002004
Victor Stinner8c62be82010-05-06 00:08:46 +00002005 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002006#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 PyStructSequence_SET_ITEM(v, 1,
2008 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002009#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002011#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002012#ifdef MS_WINDOWS
2013 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002014#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002015 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002016#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002018#if defined(MS_WINDOWS)
2019 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2020 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2021#else
2022 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2023 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2024#endif
Fred Drake699f3522000-06-29 21:12:41 +00002025#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002026 PyStructSequence_SET_ITEM(v, 6,
2027 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002028#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002030#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002031
Martin v. Löwis14694662006-02-03 12:54:16 +00002032#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 ansec = st->st_atim.tv_nsec;
2034 mnsec = st->st_mtim.tv_nsec;
2035 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002036#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 ansec = st->st_atimespec.tv_nsec;
2038 mnsec = st->st_mtimespec.tv_nsec;
2039 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002040#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 ansec = st->st_atime_nsec;
2042 mnsec = st->st_mtime_nsec;
2043 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002044#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002045 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002046#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002047 fill_time(v, 7, st->st_atime, ansec);
2048 fill_time(v, 8, st->st_mtime, mnsec);
2049 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002050
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002051#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2053 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002055#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2057 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002058#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002059#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2061 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002062#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2065 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002066#endif
2067#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002068 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002069 PyObject *val;
2070 unsigned long bsec,bnsec;
2071 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002072#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002073 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002075 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002077 if (_stat_float_times) {
2078 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2079 } else {
2080 val = PyLong_FromLong((long)bsec);
2081 }
2082 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2083 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002084 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002085#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002086#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2088 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002089#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002090#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2091 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2092 PyLong_FromUnsignedLong(st->st_file_attributes));
2093#endif
Fred Drake699f3522000-06-29 21:12:41 +00002094
Victor Stinner8c62be82010-05-06 00:08:46 +00002095 if (PyErr_Occurred()) {
2096 Py_DECREF(v);
2097 return NULL;
2098 }
Fred Drake699f3522000-06-29 21:12:41 +00002099
Victor Stinner8c62be82010-05-06 00:08:46 +00002100 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002101}
2102
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002103/* POSIX methods */
2104
Guido van Rossum94f6f721999-01-06 18:42:14 +00002105
2106static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002107posix_do_stat(char *function_name, path_t *path,
2108 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002109{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002110 STRUCT_STAT st;
2111 int result;
2112
2113#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2114 if (follow_symlinks_specified(function_name, follow_symlinks))
2115 return NULL;
2116#endif
2117
2118 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2119 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2120 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2121 return NULL;
2122
2123 Py_BEGIN_ALLOW_THREADS
2124 if (path->fd != -1)
2125 result = FSTAT(path->fd, &st);
2126 else
2127#ifdef MS_WINDOWS
2128 if (path->wide) {
2129 if (follow_symlinks)
2130 result = win32_stat_w(path->wide, &st);
2131 else
2132 result = win32_lstat_w(path->wide, &st);
2133 }
2134 else
2135#endif
2136#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2137 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2138 result = LSTAT(path->narrow, &st);
2139 else
2140#endif
2141#ifdef HAVE_FSTATAT
2142 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2143 result = fstatat(dir_fd, path->narrow, &st,
2144 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2145 else
2146#endif
2147 result = STAT(path->narrow, &st);
2148 Py_END_ALLOW_THREADS
2149
Victor Stinner292c8352012-10-30 02:17:38 +01002150 if (result != 0) {
2151 return path_error(path);
2152 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002153
2154 return _pystat_fromstructstat(&st);
2155}
2156
Larry Hastings2f936352014-08-05 14:04:04 +10002157/*[python input]
2158
2159for s in """
2160
2161FACCESSAT
2162FCHMODAT
2163FCHOWNAT
2164FSTATAT
2165LINKAT
2166MKDIRAT
2167MKFIFOAT
2168MKNODAT
2169OPENAT
2170READLINKAT
2171SYMLINKAT
2172UNLINKAT
2173
2174""".strip().split():
2175 s = s.strip()
2176 print("""
2177#ifdef HAVE_{s}
2178 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002179#else
Larry Hastings2f936352014-08-05 14:04:04 +10002180 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002181#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002182""".rstrip().format(s=s))
2183
2184for s in """
2185
2186FCHDIR
2187FCHMOD
2188FCHOWN
2189FDOPENDIR
2190FEXECVE
2191FPATHCONF
2192FSTATVFS
2193FTRUNCATE
2194
2195""".strip().split():
2196 s = s.strip()
2197 print("""
2198#ifdef HAVE_{s}
2199 #define PATH_HAVE_{s} 1
2200#else
2201 #define PATH_HAVE_{s} 0
2202#endif
2203
2204""".rstrip().format(s=s))
2205[python start generated code]*/
2206
2207#ifdef HAVE_FACCESSAT
2208 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2209#else
2210 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2211#endif
2212
2213#ifdef HAVE_FCHMODAT
2214 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2215#else
2216 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2217#endif
2218
2219#ifdef HAVE_FCHOWNAT
2220 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2221#else
2222 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2223#endif
2224
2225#ifdef HAVE_FSTATAT
2226 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2227#else
2228 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2229#endif
2230
2231#ifdef HAVE_LINKAT
2232 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2233#else
2234 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2235#endif
2236
2237#ifdef HAVE_MKDIRAT
2238 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2239#else
2240 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2241#endif
2242
2243#ifdef HAVE_MKFIFOAT
2244 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2245#else
2246 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2247#endif
2248
2249#ifdef HAVE_MKNODAT
2250 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2251#else
2252 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2253#endif
2254
2255#ifdef HAVE_OPENAT
2256 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2257#else
2258 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2259#endif
2260
2261#ifdef HAVE_READLINKAT
2262 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2263#else
2264 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2265#endif
2266
2267#ifdef HAVE_SYMLINKAT
2268 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2269#else
2270 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2271#endif
2272
2273#ifdef HAVE_UNLINKAT
2274 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2275#else
2276 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2277#endif
2278
2279#ifdef HAVE_FCHDIR
2280 #define PATH_HAVE_FCHDIR 1
2281#else
2282 #define PATH_HAVE_FCHDIR 0
2283#endif
2284
2285#ifdef HAVE_FCHMOD
2286 #define PATH_HAVE_FCHMOD 1
2287#else
2288 #define PATH_HAVE_FCHMOD 0
2289#endif
2290
2291#ifdef HAVE_FCHOWN
2292 #define PATH_HAVE_FCHOWN 1
2293#else
2294 #define PATH_HAVE_FCHOWN 0
2295#endif
2296
2297#ifdef HAVE_FDOPENDIR
2298 #define PATH_HAVE_FDOPENDIR 1
2299#else
2300 #define PATH_HAVE_FDOPENDIR 0
2301#endif
2302
2303#ifdef HAVE_FEXECVE
2304 #define PATH_HAVE_FEXECVE 1
2305#else
2306 #define PATH_HAVE_FEXECVE 0
2307#endif
2308
2309#ifdef HAVE_FPATHCONF
2310 #define PATH_HAVE_FPATHCONF 1
2311#else
2312 #define PATH_HAVE_FPATHCONF 0
2313#endif
2314
2315#ifdef HAVE_FSTATVFS
2316 #define PATH_HAVE_FSTATVFS 1
2317#else
2318 #define PATH_HAVE_FSTATVFS 0
2319#endif
2320
2321#ifdef HAVE_FTRUNCATE
2322 #define PATH_HAVE_FTRUNCATE 1
2323#else
2324 #define PATH_HAVE_FTRUNCATE 0
2325#endif
2326/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002327
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002328#ifdef MS_WINDOWS
2329 #undef PATH_HAVE_FTRUNCATE
2330 #define PATH_HAVE_FTRUNCATE 1
2331#endif
Larry Hastings31826802013-10-19 00:09:25 -07002332
Larry Hastings61272b72014-01-07 12:41:53 -08002333/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002334
2335class path_t_converter(CConverter):
2336
2337 type = "path_t"
2338 impl_by_reference = True
2339 parse_by_reference = True
2340
2341 converter = 'path_converter'
2342
2343 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002344 # right now path_t doesn't support default values.
2345 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002346 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002347 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002348
Larry Hastings2f936352014-08-05 14:04:04 +10002349 if self.c_default not in (None, 'Py_None'):
2350 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002351
2352 self.nullable = nullable
2353 self.allow_fd = allow_fd
2354
Larry Hastings7726ac92014-01-31 22:03:12 -08002355 def pre_render(self):
2356 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002357 if isinstance(value, str):
2358 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002359 return str(int(bool(value)))
2360
2361 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002362 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002363 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002364 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002365 strify(self.nullable),
2366 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002367 )
2368
2369 def cleanup(self):
2370 return "path_cleanup(&" + self.name + ");\n"
2371
2372
2373class dir_fd_converter(CConverter):
2374 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002375
Larry Hastings2f936352014-08-05 14:04:04 +10002376 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002377 if self.default in (unspecified, None):
2378 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002379 if isinstance(requires, str):
2380 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2381 else:
2382 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002383
Larry Hastings2f936352014-08-05 14:04:04 +10002384class fildes_converter(CConverter):
2385 type = 'int'
2386 converter = 'fildes_converter'
2387
2388class uid_t_converter(CConverter):
2389 type = "uid_t"
2390 converter = '_Py_Uid_Converter'
2391
2392class gid_t_converter(CConverter):
2393 type = "gid_t"
2394 converter = '_Py_Gid_Converter'
2395
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002396class dev_t_converter(CConverter):
2397 type = 'dev_t'
2398 converter = '_Py_Dev_Converter'
2399
2400class dev_t_return_converter(unsigned_long_return_converter):
2401 type = 'dev_t'
2402 conversion_fn = '_PyLong_FromDev'
2403 unsigned_cast = '(dev_t)'
2404
Larry Hastings2f936352014-08-05 14:04:04 +10002405class FSConverter_converter(CConverter):
2406 type = 'PyObject *'
2407 converter = 'PyUnicode_FSConverter'
2408 def converter_init(self):
2409 if self.default is not unspecified:
2410 fail("FSConverter_converter does not support default values")
2411 self.c_default = 'NULL'
2412
2413 def cleanup(self):
2414 return "Py_XDECREF(" + self.name + ");\n"
2415
2416class pid_t_converter(CConverter):
2417 type = 'pid_t'
2418 format_unit = '" _Py_PARSE_PID "'
2419
2420class idtype_t_converter(int_converter):
2421 type = 'idtype_t'
2422
2423class id_t_converter(CConverter):
2424 type = 'id_t'
2425 format_unit = '" _Py_PARSE_PID "'
2426
2427class Py_intptr_t_converter(CConverter):
2428 type = 'Py_intptr_t'
2429 format_unit = '" _Py_PARSE_INTPTR "'
2430
2431class Py_off_t_converter(CConverter):
2432 type = 'Py_off_t'
2433 converter = 'Py_off_t_converter'
2434
2435class Py_off_t_return_converter(long_return_converter):
2436 type = 'Py_off_t'
2437 conversion_fn = 'PyLong_FromPy_off_t'
2438
2439class path_confname_converter(CConverter):
2440 type="int"
2441 converter="conv_path_confname"
2442
2443class confstr_confname_converter(path_confname_converter):
2444 converter='conv_confstr_confname'
2445
2446class sysconf_confname_converter(path_confname_converter):
2447 converter="conv_sysconf_confname"
2448
2449class sched_param_converter(CConverter):
2450 type = 'struct sched_param'
2451 converter = 'convert_sched_param'
2452 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002453
Larry Hastings61272b72014-01-07 12:41:53 -08002454[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002455/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002456
Larry Hastings61272b72014-01-07 12:41:53 -08002457/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002458
Larry Hastings2a727912014-01-16 11:32:01 -08002459os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002460
2461 path : path_t(allow_fd=True)
2462 Path to be examined; can be string, bytes, or open-file-descriptor int.
2463
2464 *
2465
Larry Hastings2f936352014-08-05 14:04:04 +10002466 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002467 If not None, it should be a file descriptor open to a directory,
2468 and path should be a relative string; path will then be relative to
2469 that directory.
2470
2471 follow_symlinks: bool = True
2472 If False, and the last element of the path is a symbolic link,
2473 stat will examine the symbolic link itself instead of the file
2474 the link points to.
2475
2476Perform a stat system call on the given path.
2477
2478dir_fd and follow_symlinks may not be implemented
2479 on your platform. If they are unavailable, using them will raise a
2480 NotImplementedError.
2481
2482It's an error to use dir_fd or follow_symlinks when specifying path as
2483 an open file descriptor.
2484
Larry Hastings61272b72014-01-07 12:41:53 -08002485[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002486
Larry Hastings31826802013-10-19 00:09:25 -07002487static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002488os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2489/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002490{
2491 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2492}
2493
Larry Hastings2f936352014-08-05 14:04:04 +10002494
2495/*[clinic input]
2496os.lstat
2497
2498 path : path_t
2499
2500 *
2501
2502 dir_fd : dir_fd(requires='fstatat') = None
2503
2504Perform a stat system call on the given path, without following symbolic links.
2505
2506Like stat(), but do not follow symbolic links.
2507Equivalent to stat(path, follow_symlinks=False).
2508[clinic start generated code]*/
2509
Larry Hastings2f936352014-08-05 14:04:04 +10002510static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002511os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2512/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002513{
2514 int follow_symlinks = 0;
2515 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2516}
Larry Hastings31826802013-10-19 00:09:25 -07002517
Larry Hastings2f936352014-08-05 14:04:04 +10002518
Larry Hastings61272b72014-01-07 12:41:53 -08002519/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002520os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002521
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002522 path: path_t
2523 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002524
2525 mode: int
2526 Operating-system mode bitfield. Can be F_OK to test existence,
2527 or the inclusive-OR of R_OK, W_OK, and X_OK.
2528
2529 *
2530
Larry Hastings2f936352014-08-05 14:04:04 +10002531 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002532 If not None, it should be a file descriptor open to a directory,
2533 and path should be relative; path will then be relative to that
2534 directory.
2535
2536 effective_ids: bool = False
2537 If True, access will use the effective uid/gid instead of
2538 the real uid/gid.
2539
2540 follow_symlinks: bool = True
2541 If False, and the last element of the path is a symbolic link,
2542 access will examine the symbolic link itself instead of the file
2543 the link points to.
2544
2545Use the real uid/gid to test for access to a path.
2546
2547{parameters}
2548dir_fd, effective_ids, and follow_symlinks may not be implemented
2549 on your platform. If they are unavailable, using them will raise a
2550 NotImplementedError.
2551
2552Note that most operations will use the effective uid/gid, therefore this
2553 routine can be used in a suid/sgid environment to test if the invoking user
2554 has the specified access to the path.
2555
Larry Hastings61272b72014-01-07 12:41:53 -08002556[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002557
Larry Hastings2f936352014-08-05 14:04:04 +10002558static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002559os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002560 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002561/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002562{
Larry Hastings2f936352014-08-05 14:04:04 +10002563 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002564
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002565#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002566 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002567#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002568 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002569#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570
Larry Hastings9cf065c2012-06-22 16:30:09 -07002571#ifndef HAVE_FACCESSAT
2572 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002573 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002574
2575 if (effective_ids) {
2576 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002577 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002578 }
2579#endif
2580
2581#ifdef MS_WINDOWS
2582 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002583 if (path->wide != NULL)
2584 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002585 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002586 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002587 Py_END_ALLOW_THREADS
2588
2589 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002590 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591 * * we didn't get a -1, and
2592 * * write access wasn't requested,
2593 * * or the file isn't read-only,
2594 * * or it's a directory.
2595 * (Directories cannot be read-only on Windows.)
2596 */
Larry Hastings2f936352014-08-05 14:04:04 +10002597 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002598 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002599 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002600 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601#else
2602
2603 Py_BEGIN_ALLOW_THREADS
2604#ifdef HAVE_FACCESSAT
2605 if ((dir_fd != DEFAULT_DIR_FD) ||
2606 effective_ids ||
2607 !follow_symlinks) {
2608 int flags = 0;
2609 if (!follow_symlinks)
2610 flags |= AT_SYMLINK_NOFOLLOW;
2611 if (effective_ids)
2612 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002613 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002614 }
2615 else
2616#endif
Larry Hastings31826802013-10-19 00:09:25 -07002617 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002619 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620#endif
2621
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002623}
2624
Guido van Rossumd371ff11999-01-25 16:12:23 +00002625#ifndef F_OK
2626#define F_OK 0
2627#endif
2628#ifndef R_OK
2629#define R_OK 4
2630#endif
2631#ifndef W_OK
2632#define W_OK 2
2633#endif
2634#ifndef X_OK
2635#define X_OK 1
2636#endif
2637
Larry Hastings31826802013-10-19 00:09:25 -07002638
Guido van Rossumd371ff11999-01-25 16:12:23 +00002639#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002640/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002641os.ttyname -> DecodeFSDefault
2642
2643 fd: int
2644 Integer file descriptor handle.
2645
2646 /
2647
2648Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002649[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002650
Larry Hastings31826802013-10-19 00:09:25 -07002651static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002652os_ttyname_impl(PyObject *module, int fd)
2653/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002654{
2655 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002656
Larry Hastings31826802013-10-19 00:09:25 -07002657 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002658 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002659 posix_error();
2660 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002661}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002662#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002663
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002664#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002665/*[clinic input]
2666os.ctermid
2667
2668Return the name of the controlling terminal for this process.
2669[clinic start generated code]*/
2670
Larry Hastings2f936352014-08-05 14:04:04 +10002671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002672os_ctermid_impl(PyObject *module)
2673/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002674{
Victor Stinner8c62be82010-05-06 00:08:46 +00002675 char *ret;
2676 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677
Greg Wardb48bc172000-03-01 21:51:56 +00002678#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002679 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002680#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002682#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 if (ret == NULL)
2684 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002685 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686}
Larry Hastings2f936352014-08-05 14:04:04 +10002687#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002688
Larry Hastings2f936352014-08-05 14:04:04 +10002689
2690/*[clinic input]
2691os.chdir
2692
2693 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2694
2695Change the current working directory to the specified path.
2696
2697path may always be specified as a string.
2698On some platforms, path may also be specified as an open file descriptor.
2699 If this functionality is unavailable, using it raises an exception.
2700[clinic start generated code]*/
2701
Larry Hastings2f936352014-08-05 14:04:04 +10002702static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002703os_chdir_impl(PyObject *module, path_t *path)
2704/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002705{
2706 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002707
2708 Py_BEGIN_ALLOW_THREADS
2709#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002710 if (path->wide)
2711 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712 else
Larry Hastings2f936352014-08-05 14:04:04 +10002713 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002714 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002715#else
2716#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002717 if (path->fd != -1)
2718 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719 else
2720#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002721 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002722#endif
2723 Py_END_ALLOW_THREADS
2724
2725 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002726 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002727 }
2728
Larry Hastings2f936352014-08-05 14:04:04 +10002729 Py_RETURN_NONE;
2730}
2731
2732
2733#ifdef HAVE_FCHDIR
2734/*[clinic input]
2735os.fchdir
2736
2737 fd: fildes
2738
2739Change to the directory of the given file descriptor.
2740
2741fd must be opened on a directory, not a file.
2742Equivalent to os.chdir(fd).
2743
2744[clinic start generated code]*/
2745
Fred Drake4d1e64b2002-04-15 19:40:07 +00002746static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002747os_fchdir_impl(PyObject *module, int fd)
2748/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002749{
Larry Hastings2f936352014-08-05 14:04:04 +10002750 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002751}
2752#endif /* HAVE_FCHDIR */
2753
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002754
Larry Hastings2f936352014-08-05 14:04:04 +10002755/*[clinic input]
2756os.chmod
2757
2758 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2759 Path to be modified. May always be specified as a str or bytes.
2760 On some platforms, path may also be specified as an open file descriptor.
2761 If this functionality is unavailable, using it raises an exception.
2762
2763 mode: int
2764 Operating-system mode bitfield.
2765
2766 *
2767
2768 dir_fd : dir_fd(requires='fchmodat') = None
2769 If not None, it should be a file descriptor open to a directory,
2770 and path should be relative; path will then be relative to that
2771 directory.
2772
2773 follow_symlinks: bool = True
2774 If False, and the last element of the path is a symbolic link,
2775 chmod will modify the symbolic link itself instead of the file
2776 the link points to.
2777
2778Change the access permissions of a file.
2779
2780It is an error to use dir_fd or follow_symlinks when specifying path as
2781 an open file descriptor.
2782dir_fd and follow_symlinks may not be implemented on your platform.
2783 If they are unavailable, using them will raise a NotImplementedError.
2784
2785[clinic start generated code]*/
2786
Larry Hastings2f936352014-08-05 14:04:04 +10002787static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002788os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002789 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002790/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002791{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002792 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002794#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002795 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002796#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002797
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798#ifdef HAVE_FCHMODAT
2799 int fchmodat_nofollow_unsupported = 0;
2800#endif
2801
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2803 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002804 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002805#endif
2806
2807#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002808 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002809 if (path->wide)
2810 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 else
Larry Hastings2f936352014-08-05 14:04:04 +10002812 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002813 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002814 result = 0;
2815 else {
2816 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002817 attr &= ~FILE_ATTRIBUTE_READONLY;
2818 else
2819 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002820 if (path->wide)
2821 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002822 else
Larry Hastings2f936352014-08-05 14:04:04 +10002823 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 }
2825 Py_END_ALLOW_THREADS
2826
2827 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002828 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 }
2830#else /* MS_WINDOWS */
2831 Py_BEGIN_ALLOW_THREADS
2832#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002833 if (path->fd != -1)
2834 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002835 else
2836#endif
2837#ifdef HAVE_LCHMOD
2838 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002839 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002840 else
2841#endif
2842#ifdef HAVE_FCHMODAT
2843 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2844 /*
2845 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2846 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002847 * and then says it isn't implemented yet.
2848 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002849 *
2850 * Once it is supported, os.chmod will automatically
2851 * support dir_fd and follow_symlinks=False. (Hopefully.)
2852 * Until then, we need to be careful what exception we raise.
2853 */
Larry Hastings2f936352014-08-05 14:04:04 +10002854 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002855 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2856 /*
2857 * But wait! We can't throw the exception without allowing threads,
2858 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2859 */
2860 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002861 result &&
2862 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2863 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002864 }
2865 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002866#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002867 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002868 Py_END_ALLOW_THREADS
2869
2870 if (result) {
2871#ifdef HAVE_FCHMODAT
2872 if (fchmodat_nofollow_unsupported) {
2873 if (dir_fd != DEFAULT_DIR_FD)
2874 dir_fd_and_follow_symlinks_invalid("chmod",
2875 dir_fd, follow_symlinks);
2876 else
2877 follow_symlinks_specified("chmod", follow_symlinks);
2878 }
2879 else
2880#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002881 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002882 }
2883#endif
2884
Larry Hastings2f936352014-08-05 14:04:04 +10002885 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002886}
2887
Larry Hastings9cf065c2012-06-22 16:30:09 -07002888
Christian Heimes4e30a842007-11-30 22:12:06 +00002889#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002890/*[clinic input]
2891os.fchmod
2892
2893 fd: int
2894 mode: int
2895
2896Change the access permissions of the file given by file descriptor fd.
2897
2898Equivalent to os.chmod(fd, mode).
2899[clinic start generated code]*/
2900
Larry Hastings2f936352014-08-05 14:04:04 +10002901static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002902os_fchmod_impl(PyObject *module, int fd, int mode)
2903/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002904{
2905 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002906 int async_err = 0;
2907
2908 do {
2909 Py_BEGIN_ALLOW_THREADS
2910 res = fchmod(fd, mode);
2911 Py_END_ALLOW_THREADS
2912 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2913 if (res != 0)
2914 return (!async_err) ? posix_error() : NULL;
2915
Victor Stinner8c62be82010-05-06 00:08:46 +00002916 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002917}
2918#endif /* HAVE_FCHMOD */
2919
Larry Hastings2f936352014-08-05 14:04:04 +10002920
Christian Heimes4e30a842007-11-30 22:12:06 +00002921#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002922/*[clinic input]
2923os.lchmod
2924
2925 path: path_t
2926 mode: int
2927
2928Change the access permissions of a file, without following symbolic links.
2929
2930If path is a symlink, this affects the link itself rather than the target.
2931Equivalent to chmod(path, mode, follow_symlinks=False)."
2932[clinic start generated code]*/
2933
Larry Hastings2f936352014-08-05 14:04:04 +10002934static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002935os_lchmod_impl(PyObject *module, path_t *path, int mode)
2936/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002937{
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002939 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002940 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002942 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002943 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002944 return NULL;
2945 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002946 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002947}
2948#endif /* HAVE_LCHMOD */
2949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002950
Thomas Wouterscf297e42007-02-23 15:07:44 +00002951#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002952/*[clinic input]
2953os.chflags
2954
2955 path: path_t
2956 flags: unsigned_long(bitwise=True)
2957 follow_symlinks: bool=True
2958
2959Set file flags.
2960
2961If follow_symlinks is False, and the last element of the path is a symbolic
2962 link, chflags will change flags on the symbolic link itself instead of the
2963 file the link points to.
2964follow_symlinks may not be implemented on your platform. If it is
2965unavailable, using it will raise a NotImplementedError.
2966
2967[clinic start generated code]*/
2968
Larry Hastings2f936352014-08-05 14:04:04 +10002969static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002970os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002971 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002972/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002973{
2974 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002975
2976#ifndef HAVE_LCHFLAGS
2977 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002978 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979#endif
2980
Victor Stinner8c62be82010-05-06 00:08:46 +00002981 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002982#ifdef HAVE_LCHFLAGS
2983 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002984 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002985 else
2986#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002987 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002988 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989
Larry Hastings2f936352014-08-05 14:04:04 +10002990 if (result)
2991 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002992
Larry Hastings2f936352014-08-05 14:04:04 +10002993 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002994}
2995#endif /* HAVE_CHFLAGS */
2996
Larry Hastings2f936352014-08-05 14:04:04 +10002997
Thomas Wouterscf297e42007-02-23 15:07:44 +00002998#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002999/*[clinic input]
3000os.lchflags
3001
3002 path: path_t
3003 flags: unsigned_long(bitwise=True)
3004
3005Set file flags.
3006
3007This function will not follow symbolic links.
3008Equivalent to chflags(path, flags, follow_symlinks=False).
3009[clinic start generated code]*/
3010
Larry Hastings2f936352014-08-05 14:04:04 +10003011static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003012os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3013/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003014{
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003016 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003017 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003019 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003020 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003021 }
Victor Stinner292c8352012-10-30 02:17:38 +01003022 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003023}
3024#endif /* HAVE_LCHFLAGS */
3025
Larry Hastings2f936352014-08-05 14:04:04 +10003026
Martin v. Löwis244edc82001-10-04 22:44:26 +00003027#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003028/*[clinic input]
3029os.chroot
3030 path: path_t
3031
3032Change root directory to path.
3033
3034[clinic start generated code]*/
3035
Larry Hastings2f936352014-08-05 14:04:04 +10003036static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003037os_chroot_impl(PyObject *module, path_t *path)
3038/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003039{
3040 int res;
3041 Py_BEGIN_ALLOW_THREADS
3042 res = chroot(path->narrow);
3043 Py_END_ALLOW_THREADS
3044 if (res < 0)
3045 return path_error(path);
3046 Py_RETURN_NONE;
3047}
3048#endif /* HAVE_CHROOT */
3049
Martin v. Löwis244edc82001-10-04 22:44:26 +00003050
Guido van Rossum21142a01999-01-08 21:05:37 +00003051#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003052/*[clinic input]
3053os.fsync
3054
3055 fd: fildes
3056
3057Force write of fd to disk.
3058[clinic start generated code]*/
3059
Larry Hastings2f936352014-08-05 14:04:04 +10003060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003061os_fsync_impl(PyObject *module, int fd)
3062/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003063{
3064 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003065}
3066#endif /* HAVE_FSYNC */
3067
Larry Hastings2f936352014-08-05 14:04:04 +10003068
Ross Lagerwall7807c352011-03-17 20:20:30 +02003069#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003070/*[clinic input]
3071os.sync
3072
3073Force write of everything to disk.
3074[clinic start generated code]*/
3075
Larry Hastings2f936352014-08-05 14:04:04 +10003076static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003077os_sync_impl(PyObject *module)
3078/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003079{
3080 Py_BEGIN_ALLOW_THREADS
3081 sync();
3082 Py_END_ALLOW_THREADS
3083 Py_RETURN_NONE;
3084}
Larry Hastings2f936352014-08-05 14:04:04 +10003085#endif /* HAVE_SYNC */
3086
Ross Lagerwall7807c352011-03-17 20:20:30 +02003087
Guido van Rossum21142a01999-01-08 21:05:37 +00003088#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003089#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003090extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3091#endif
3092
Larry Hastings2f936352014-08-05 14:04:04 +10003093/*[clinic input]
3094os.fdatasync
3095
3096 fd: fildes
3097
3098Force write of fd to disk without forcing update of metadata.
3099[clinic start generated code]*/
3100
Larry Hastings2f936352014-08-05 14:04:04 +10003101static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003102os_fdatasync_impl(PyObject *module, int fd)
3103/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003104{
3105 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003106}
3107#endif /* HAVE_FDATASYNC */
3108
3109
Fredrik Lundh10723342000-07-10 16:38:09 +00003110#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003111/*[clinic input]
3112os.chown
3113
3114 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3115 Path to be examined; can be string, bytes, or open-file-descriptor int.
3116
3117 uid: uid_t
3118
3119 gid: gid_t
3120
3121 *
3122
3123 dir_fd : dir_fd(requires='fchownat') = None
3124 If not None, it should be a file descriptor open to a directory,
3125 and path should be relative; path will then be relative to that
3126 directory.
3127
3128 follow_symlinks: bool = True
3129 If False, and the last element of the path is a symbolic link,
3130 stat will examine the symbolic link itself instead of the file
3131 the link points to.
3132
3133Change the owner and group id of path to the numeric uid and gid.\
3134
3135path may always be specified as a string.
3136On some platforms, path may also be specified as an open file descriptor.
3137 If this functionality is unavailable, using it raises an exception.
3138If dir_fd is not None, it should be a file descriptor open to a directory,
3139 and path should be relative; path will then be relative to that directory.
3140If follow_symlinks is False, and the last element of the path is a symbolic
3141 link, chown will modify the symbolic link itself instead of the file the
3142 link points to.
3143It is an error to use dir_fd or follow_symlinks when specifying path as
3144 an open file descriptor.
3145dir_fd and follow_symlinks may not be implemented on your platform.
3146 If they are unavailable, using them will raise a NotImplementedError.
3147
3148[clinic start generated code]*/
3149
Larry Hastings2f936352014-08-05 14:04:04 +10003150static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003151os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003152 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003154{
3155 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003156
3157#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3158 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003159 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003160#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003161 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3162 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3163 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164
3165#ifdef __APPLE__
3166 /*
3167 * This is for Mac OS X 10.3, which doesn't have lchown.
3168 * (But we still have an lchown symbol because of weak-linking.)
3169 * It doesn't have fchownat either. So there's no possibility
3170 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003171 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172 if ((!follow_symlinks) && (lchown == NULL)) {
3173 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003174 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003175 }
3176#endif
3177
Victor Stinner8c62be82010-05-06 00:08:46 +00003178 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003180 if (path->fd != -1)
3181 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003182 else
3183#endif
3184#ifdef HAVE_LCHOWN
3185 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003186 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187 else
3188#endif
3189#ifdef HAVE_FCHOWNAT
3190 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003191 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003192 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3193 else
3194#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003195 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003196 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197
Larry Hastings2f936352014-08-05 14:04:04 +10003198 if (result)
3199 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003200
Larry Hastings2f936352014-08-05 14:04:04 +10003201 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003202}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003203#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204
Larry Hastings2f936352014-08-05 14:04:04 +10003205
Christian Heimes4e30a842007-11-30 22:12:06 +00003206#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003207/*[clinic input]
3208os.fchown
3209
3210 fd: int
3211 uid: uid_t
3212 gid: gid_t
3213
3214Change the owner and group id of the file specified by file descriptor.
3215
3216Equivalent to os.chown(fd, uid, gid).
3217
3218[clinic start generated code]*/
3219
Larry Hastings2f936352014-08-05 14:04:04 +10003220static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003221os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3222/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003223{
Victor Stinner8c62be82010-05-06 00:08:46 +00003224 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003225 int async_err = 0;
3226
3227 do {
3228 Py_BEGIN_ALLOW_THREADS
3229 res = fchown(fd, uid, gid);
3230 Py_END_ALLOW_THREADS
3231 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3232 if (res != 0)
3233 return (!async_err) ? posix_error() : NULL;
3234
Victor Stinner8c62be82010-05-06 00:08:46 +00003235 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003236}
3237#endif /* HAVE_FCHOWN */
3238
Larry Hastings2f936352014-08-05 14:04:04 +10003239
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003240#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003241/*[clinic input]
3242os.lchown
3243
3244 path : path_t
3245 uid: uid_t
3246 gid: gid_t
3247
3248Change the owner and group id of path to the numeric uid and gid.
3249
3250This function will not follow symbolic links.
3251Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3252[clinic start generated code]*/
3253
Larry Hastings2f936352014-08-05 14:04:04 +10003254static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003255os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3256/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003257{
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003259 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003260 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003262 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003263 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003264 }
Larry Hastings2f936352014-08-05 14:04:04 +10003265 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003266}
3267#endif /* HAVE_LCHOWN */
3268
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003269
Barry Warsaw53699e91996-12-10 23:23:01 +00003270static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003271posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003272{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003273 char *buf, *tmpbuf;
3274 char *cwd;
3275 const size_t chunk = 1024;
3276 size_t buflen = 0;
3277 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003278
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003279#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003280 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003281 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 wchar_t *wbuf2 = wbuf;
3283 PyObject *resobj;
3284 DWORD len;
3285 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003286 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003287 /* If the buffer is large enough, len does not include the
3288 terminating \0. If the buffer is too small, len includes
3289 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003290 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003291 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 if (wbuf2)
3293 len = GetCurrentDirectoryW(len, wbuf2);
3294 }
3295 Py_END_ALLOW_THREADS
3296 if (!wbuf2) {
3297 PyErr_NoMemory();
3298 return NULL;
3299 }
3300 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003301 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003302 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003304 }
3305 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003306 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003307 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 return resobj;
3309 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003310
3311 if (win32_warn_bytes_api())
3312 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003313#endif
3314
Victor Stinner4403d7d2015-04-25 00:16:10 +02003315 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003316 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003317 do {
3318 buflen += chunk;
3319 tmpbuf = PyMem_RawRealloc(buf, buflen);
3320 if (tmpbuf == NULL)
3321 break;
3322
3323 buf = tmpbuf;
3324 cwd = getcwd(buf, buflen);
3325 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003326 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003327
3328 if (cwd == NULL) {
3329 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003330 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003331 }
3332
Victor Stinner8c62be82010-05-06 00:08:46 +00003333 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003334 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3335 else
3336 obj = PyUnicode_DecodeFSDefault(buf);
3337 PyMem_RawFree(buf);
3338
3339 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003340}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003341
Larry Hastings2f936352014-08-05 14:04:04 +10003342
3343/*[clinic input]
3344os.getcwd
3345
3346Return a unicode string representing the current working directory.
3347[clinic start generated code]*/
3348
Larry Hastings2f936352014-08-05 14:04:04 +10003349static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003350os_getcwd_impl(PyObject *module)
3351/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003352{
3353 return posix_getcwd(0);
3354}
3355
Larry Hastings2f936352014-08-05 14:04:04 +10003356
3357/*[clinic input]
3358os.getcwdb
3359
3360Return a bytes string representing the current working directory.
3361[clinic start generated code]*/
3362
Larry Hastings2f936352014-08-05 14:04:04 +10003363static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003364os_getcwdb_impl(PyObject *module)
3365/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003366{
3367 return posix_getcwd(1);
3368}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003369
Larry Hastings2f936352014-08-05 14:04:04 +10003370
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3372#define HAVE_LINK 1
3373#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003374
Guido van Rossumb6775db1994-08-01 11:34:53 +00003375#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003376/*[clinic input]
3377
3378os.link
3379
3380 src : path_t
3381 dst : path_t
3382 *
3383 src_dir_fd : dir_fd = None
3384 dst_dir_fd : dir_fd = None
3385 follow_symlinks: bool = True
3386
3387Create a hard link to a file.
3388
3389If either src_dir_fd or dst_dir_fd is not None, it should be a file
3390 descriptor open to a directory, and the respective path string (src or dst)
3391 should be relative; the path will then be relative to that directory.
3392If follow_symlinks is False, and the last element of src is a symbolic
3393 link, link will create a link to the symbolic link itself instead of the
3394 file the link points to.
3395src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3396 platform. If they are unavailable, using them will raise a
3397 NotImplementedError.
3398[clinic start generated code]*/
3399
Larry Hastings2f936352014-08-05 14:04:04 +10003400static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003401os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003402 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003403/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003404{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003405#ifdef MS_WINDOWS
3406 BOOL result;
3407#else
3408 int result;
3409#endif
3410
Larry Hastings9cf065c2012-06-22 16:30:09 -07003411#ifndef HAVE_LINKAT
3412 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3413 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003414 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415 }
3416#endif
3417
Larry Hastings2f936352014-08-05 14:04:04 +10003418 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419 PyErr_SetString(PyExc_NotImplementedError,
3420 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003421 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003423
Brian Curtin1b9df392010-11-24 20:24:31 +00003424#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003426 if (src->wide)
3427 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003428 else
Larry Hastings2f936352014-08-05 14:04:04 +10003429 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003431
Larry Hastings2f936352014-08-05 14:04:04 +10003432 if (!result)
3433 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434#else
3435 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003436#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3438 (dst_dir_fd != DEFAULT_DIR_FD) ||
3439 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003440 result = linkat(src_dir_fd, src->narrow,
3441 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3443 else
3444#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003445 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003447
Larry Hastings2f936352014-08-05 14:04:04 +10003448 if (result)
3449 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450#endif
3451
Larry Hastings2f936352014-08-05 14:04:04 +10003452 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003453}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454#endif
3455
Brian Curtin1b9df392010-11-24 20:24:31 +00003456
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003457#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003458static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003459_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003460{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003461 PyObject *v;
3462 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3463 BOOL result;
3464 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003465 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 char *bufptr = namebuf;
3467 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003468 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 PyObject *po = NULL;
3470 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471
Gregory P. Smith40a21602013-03-20 20:52:50 -07003472 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003473 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003475
Gregory P. Smith40a21602013-03-20 20:52:50 -07003476 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003477 po_wchars = L".";
3478 len = 1;
3479 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003480 po_wchars = path->wide;
3481 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003482 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003484 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 if (!wnamebuf) {
3486 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003489 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003491 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003492 if (wch != SEP && wch != ALTSEP && wch != L':')
3493 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003494 wcscpy(wnamebuf + len, L"*.*");
3495 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003496 if ((list = PyList_New(0)) == NULL) {
3497 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003498 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003499 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003501 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 if (hFindFile == INVALID_HANDLE_VALUE) {
3503 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003504 if (error == ERROR_FILE_NOT_FOUND)
3505 goto exit;
3506 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003507 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003509 }
3510 do {
3511 /* Skip over . and .. */
3512 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3513 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 v = PyUnicode_FromWideChar(wFileData.cFileName,
3515 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003517 Py_DECREF(list);
3518 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 break;
3520 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003521 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 Py_DECREF(list);
3524 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003525 break;
3526 }
3527 Py_DECREF(v);
3528 }
3529 Py_BEGIN_ALLOW_THREADS
3530 result = FindNextFileW(hFindFile, &wFileData);
3531 Py_END_ALLOW_THREADS
3532 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3533 it got to the end of the directory. */
3534 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003536 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003538 }
3539 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003540
Larry Hastings9cf065c2012-06-22 16:30:09 -07003541 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003543 strcpy(namebuf, path->narrow);
3544 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003545 if (len > 0) {
3546 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003547 if (ch != '\\' && ch != '/' && ch != ':')
3548 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003549 strcpy(namebuf + len, "*.*");
3550 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003551
Larry Hastings9cf065c2012-06-22 16:30:09 -07003552 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003554
Antoine Pitroub73caab2010-08-09 23:39:31 +00003555 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003556 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003557 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 if (hFindFile == INVALID_HANDLE_VALUE) {
3559 int error = GetLastError();
3560 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 goto exit;
3562 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003563 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 }
3566 do {
3567 /* Skip over . and .. */
3568 if (strcmp(FileData.cFileName, ".") != 0 &&
3569 strcmp(FileData.cFileName, "..") != 0) {
3570 v = PyBytes_FromString(FileData.cFileName);
3571 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003572 Py_DECREF(list);
3573 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 break;
3575 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 Py_DECREF(list);
3579 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003580 break;
3581 }
3582 Py_DECREF(v);
3583 }
3584 Py_BEGIN_ALLOW_THREADS
3585 result = FindNextFile(hFindFile, &FileData);
3586 Py_END_ALLOW_THREADS
3587 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3588 it got to the end of the directory. */
3589 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003591 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003593 }
3594 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003595
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596exit:
3597 if (hFindFile != INVALID_HANDLE_VALUE) {
3598 if (FindClose(hFindFile) == FALSE) {
3599 if (list != NULL) {
3600 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003601 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 }
3603 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003604 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003605 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003606
Larry Hastings9cf065c2012-06-22 16:30:09 -07003607 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003608} /* end of _listdir_windows_no_opendir */
3609
3610#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3611
3612static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003613_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003614{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003615 PyObject *v;
3616 DIR *dirp = NULL;
3617 struct dirent *ep;
3618 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003619#ifdef HAVE_FDOPENDIR
3620 int fd = -1;
3621#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003622
Victor Stinner8c62be82010-05-06 00:08:46 +00003623 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003624#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003625 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003627 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003628 if (fd == -1)
3629 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630
Larry Hastingsfdaea062012-06-25 04:42:23 -07003631 return_str = 1;
3632
Larry Hastings9cf065c2012-06-22 16:30:09 -07003633 Py_BEGIN_ALLOW_THREADS
3634 dirp = fdopendir(fd);
3635 Py_END_ALLOW_THREADS
3636 }
3637 else
3638#endif
3639 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003640 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003641 if (path->narrow) {
3642 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003643 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003644 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003645 }
3646 else {
3647 name = ".";
3648 return_str = 1;
3649 }
3650
Larry Hastings9cf065c2012-06-22 16:30:09 -07003651 Py_BEGIN_ALLOW_THREADS
3652 dirp = opendir(name);
3653 Py_END_ALLOW_THREADS
3654 }
3655
3656 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003657 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003658#ifdef HAVE_FDOPENDIR
3659 if (fd != -1) {
3660 Py_BEGIN_ALLOW_THREADS
3661 close(fd);
3662 Py_END_ALLOW_THREADS
3663 }
3664#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003665 goto exit;
3666 }
3667 if ((list = PyList_New(0)) == NULL) {
3668 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003669 }
3670 for (;;) {
3671 errno = 0;
3672 Py_BEGIN_ALLOW_THREADS
3673 ep = readdir(dirp);
3674 Py_END_ALLOW_THREADS
3675 if (ep == NULL) {
3676 if (errno == 0) {
3677 break;
3678 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003679 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003680 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003682 }
3683 }
3684 if (ep->d_name[0] == '.' &&
3685 (NAMLEN(ep) == 1 ||
3686 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3687 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003688 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003689 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3690 else
3691 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 break;
3695 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003696 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003697 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 break;
3700 }
3701 Py_DECREF(v);
3702 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003703
Larry Hastings9cf065c2012-06-22 16:30:09 -07003704exit:
3705 if (dirp != NULL) {
3706 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003707#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 if (fd > -1)
3709 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003710#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003711 closedir(dirp);
3712 Py_END_ALLOW_THREADS
3713 }
3714
Larry Hastings9cf065c2012-06-22 16:30:09 -07003715 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003716} /* end of _posix_listdir */
3717#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003718
Larry Hastings2f936352014-08-05 14:04:04 +10003719
3720/*[clinic input]
3721os.listdir
3722
3723 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3724
3725Return a list containing the names of the files in the directory.
3726
3727path can be specified as either str or bytes. If path is bytes,
3728 the filenames returned will also be bytes; in all other circumstances
3729 the filenames returned will be str.
3730If path is None, uses the path='.'.
3731On some platforms, path may also be specified as an open file descriptor;\
3732 the file descriptor must refer to a directory.
3733 If this functionality is unavailable, using it raises NotImplementedError.
3734
3735The list is in arbitrary order. It does not include the special
3736entries '.' and '..' even if they are present in the directory.
3737
3738
3739[clinic start generated code]*/
3740
Larry Hastings2f936352014-08-05 14:04:04 +10003741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003742os_listdir_impl(PyObject *module, path_t *path)
3743/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003744{
3745#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3746 return _listdir_windows_no_opendir(path, NULL);
3747#else
3748 return _posix_listdir(path, NULL);
3749#endif
3750}
3751
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003752#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003753/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003754/*[clinic input]
3755os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003756
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003757 path: path_t
3758 /
3759
3760[clinic start generated code]*/
3761
3762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003763os__getfullpathname_impl(PyObject *module, path_t *path)
3764/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003765{
3766 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003767 {
Victor Stinner75875072013-11-24 19:23:25 +01003768 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003770 DWORD result;
3771 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003772
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003773 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003774 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003776 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003777 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 if (!woutbufp)
3779 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003780 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 }
3782 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003783 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003784 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003785 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003787 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 return v;
3789 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003790 else {
3791 char outbuf[MAX_PATH];
3792 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003793
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003794 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3795 outbuf, &temp)) {
3796 win32_error_object("GetFullPathName", path->object);
3797 return NULL;
3798 }
3799 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 }
Larry Hastings2f936352014-08-05 14:04:04 +10003801}
Brian Curtind40e6f72010-07-08 21:39:08 +00003802
Brian Curtind25aef52011-06-13 15:16:04 -05003803
Larry Hastings2f936352014-08-05 14:04:04 +10003804/*[clinic input]
3805os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003806
Larry Hastings2f936352014-08-05 14:04:04 +10003807 path: unicode
3808 /
3809
3810A helper function for samepath on windows.
3811[clinic start generated code]*/
3812
Larry Hastings2f936352014-08-05 14:04:04 +10003813static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003814os__getfinalpathname_impl(PyObject *module, PyObject *path)
3815/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003816{
3817 HANDLE hFile;
3818 int buf_size;
3819 wchar_t *target_path;
3820 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003821 PyObject *result;
3822 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003823
Larry Hastings2f936352014-08-05 14:04:04 +10003824 path_wchar = PyUnicode_AsUnicode(path);
3825 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003826 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003827
Brian Curtind40e6f72010-07-08 21:39:08 +00003828 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003829 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003830 0, /* desired access */
3831 0, /* share mode */
3832 NULL, /* security attributes */
3833 OPEN_EXISTING,
3834 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3835 FILE_FLAG_BACKUP_SEMANTICS,
3836 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003837
Victor Stinnereb5657a2011-09-30 01:44:27 +02003838 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003839 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003840
3841 /* We have a good handle to the target, use it to determine the
3842 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003843 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003844
3845 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003846 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003847
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003848 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003849 if(!target_path)
3850 return PyErr_NoMemory();
3851
Steve Dower2ea51c92015-03-20 21:49:12 -07003852 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3853 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003854 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003855 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856
3857 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003858 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003859
3860 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003861 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003862 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003863 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003864}
Brian Curtin62857742010-09-06 17:07:27 +00003865
Brian Curtin95d028f2011-06-09 09:10:38 -05003866PyDoc_STRVAR(posix__isdir__doc__,
3867"Return true if the pathname refers to an existing directory.");
3868
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003869/*[clinic input]
3870os._isdir
3871
3872 path: path_t
3873 /
3874
3875[clinic start generated code]*/
3876
Brian Curtin9c669cc2011-06-08 18:17:18 -05003877static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003878os__isdir_impl(PyObject *module, path_t *path)
3879/*[clinic end generated code: output=75f56f32720836cb input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003880{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003881 DWORD attributes;
3882
Steve Dowerb22a6772016-07-17 20:49:38 -07003883 Py_BEGIN_ALLOW_THREADS
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003884 if (!path->narrow)
3885 attributes = GetFileAttributesW(path->wide);
3886 else
3887 attributes = GetFileAttributesA(path->narrow);
Steve Dowerb22a6772016-07-17 20:49:38 -07003888 Py_END_ALLOW_THREADS
Brian Curtin9c669cc2011-06-08 18:17:18 -05003889
Brian Curtin9c669cc2011-06-08 18:17:18 -05003890 if (attributes == INVALID_FILE_ATTRIBUTES)
3891 Py_RETURN_FALSE;
3892
Brian Curtin9c669cc2011-06-08 18:17:18 -05003893 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3894 Py_RETURN_TRUE;
3895 else
3896 Py_RETURN_FALSE;
3897}
Tim Golden6b528062013-08-01 12:44:00 +01003898
Tim Golden6b528062013-08-01 12:44:00 +01003899
Larry Hastings2f936352014-08-05 14:04:04 +10003900/*[clinic input]
3901os._getvolumepathname
3902
3903 path: unicode
3904
3905A helper function for ismount on Win32.
3906[clinic start generated code]*/
3907
Larry Hastings2f936352014-08-05 14:04:04 +10003908static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003909os__getvolumepathname_impl(PyObject *module, PyObject *path)
3910/*[clinic end generated code: output=cbdcbd1059ceef4c input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003911{
3912 PyObject *result;
3913 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003914 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003915 BOOL ret;
3916
Larry Hastings2f936352014-08-05 14:04:04 +10003917 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3918 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003919 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003920 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003921
3922 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003923 buflen = Py_MAX(buflen, MAX_PATH);
3924
3925 if (buflen > DWORD_MAX) {
3926 PyErr_SetString(PyExc_OverflowError, "path too long");
3927 return NULL;
3928 }
3929
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003930 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003931 if (mountpath == NULL)
3932 return PyErr_NoMemory();
3933
3934 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003935 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003936 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003937 Py_END_ALLOW_THREADS
3938
3939 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003940 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003941 goto exit;
3942 }
3943 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3944
3945exit:
3946 PyMem_Free(mountpath);
3947 return result;
3948}
Tim Golden6b528062013-08-01 12:44:00 +01003949
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003950#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003951
Larry Hastings2f936352014-08-05 14:04:04 +10003952
3953/*[clinic input]
3954os.mkdir
3955
3956 path : path_t
3957
3958 mode: int = 0o777
3959
3960 *
3961
3962 dir_fd : dir_fd(requires='mkdirat') = None
3963
3964# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3965
3966Create a directory.
3967
3968If dir_fd is not None, it should be a file descriptor open to a directory,
3969 and path should be relative; path will then be relative to that directory.
3970dir_fd may not be implemented on your platform.
3971 If it is unavailable, using it will raise a NotImplementedError.
3972
3973The mode argument is ignored on Windows.
3974[clinic start generated code]*/
3975
Larry Hastings2f936352014-08-05 14:04:04 +10003976static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003977os_mkdir_impl(PyObject *module, path_t *path, int mode, int dir_fd)
3978/*[clinic end generated code: output=a70446903abe821f input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003979{
3980 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003981
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003982#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003984 if (path->wide)
3985 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986 else
Larry Hastings2f936352014-08-05 14:04:04 +10003987 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003988 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003989
Larry Hastings2f936352014-08-05 14:04:04 +10003990 if (!result)
3991 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003993 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994#if HAVE_MKDIRAT
3995 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003996 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003997 else
3998#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003999#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004000 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004001#else
Larry Hastings2f936352014-08-05 14:04:04 +10004002 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004003#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004005 if (result < 0)
4006 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004007#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004008 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004009}
4010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004011
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004012/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4013#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004014#include <sys/resource.h>
4015#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004016
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004017
4018#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004019/*[clinic input]
4020os.nice
4021
4022 increment: int
4023 /
4024
4025Add increment to the priority of process and return the new priority.
4026[clinic start generated code]*/
4027
Larry Hastings2f936352014-08-05 14:04:04 +10004028static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004029os_nice_impl(PyObject *module, int increment)
4030/*[clinic end generated code: output=9dad8a9da8109943 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004031{
4032 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004033
Victor Stinner8c62be82010-05-06 00:08:46 +00004034 /* There are two flavours of 'nice': one that returns the new
4035 priority (as required by almost all standards out there) and the
4036 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4037 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004038
Victor Stinner8c62be82010-05-06 00:08:46 +00004039 If we are of the nice family that returns the new priority, we
4040 need to clear errno before the call, and check if errno is filled
4041 before calling posix_error() on a returnvalue of -1, because the
4042 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004043
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 errno = 0;
4045 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004046#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004047 if (value == 0)
4048 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004049#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004050 if (value == -1 && errno != 0)
4051 /* either nice() or getpriority() returned an error */
4052 return posix_error();
4053 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004054}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004055#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004056
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004057
4058#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004059/*[clinic input]
4060os.getpriority
4061
4062 which: int
4063 who: int
4064
4065Return program scheduling priority.
4066[clinic start generated code]*/
4067
Larry Hastings2f936352014-08-05 14:04:04 +10004068static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004069os_getpriority_impl(PyObject *module, int which, int who)
4070/*[clinic end generated code: output=c41b7b63c7420228 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004071{
4072 int retval;
4073
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004074 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004075 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004076 if (errno != 0)
4077 return posix_error();
4078 return PyLong_FromLong((long)retval);
4079}
4080#endif /* HAVE_GETPRIORITY */
4081
4082
4083#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004084/*[clinic input]
4085os.setpriority
4086
4087 which: int
4088 who: int
4089 priority: int
4090
4091Set program scheduling priority.
4092[clinic start generated code]*/
4093
Larry Hastings2f936352014-08-05 14:04:04 +10004094static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004095os_setpriority_impl(PyObject *module, int which, int who, int priority)
4096/*[clinic end generated code: output=3d910d95a7771eb2 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004097{
4098 int retval;
4099
4100 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004101 if (retval == -1)
4102 return posix_error();
4103 Py_RETURN_NONE;
4104}
4105#endif /* HAVE_SETPRIORITY */
4106
4107
Barry Warsaw53699e91996-12-10 23:23:01 +00004108static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004109internal_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 +00004110{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004112 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004114#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004115 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004116 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004117#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004119#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4122 (dst_dir_fd != DEFAULT_DIR_FD);
4123#ifndef HAVE_RENAMEAT
4124 if (dir_fd_specified) {
4125 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004126 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 }
4128#endif
4129
Larry Hastings2f936352014-08-05 14:04:04 +10004130 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 PyErr_Format(PyExc_ValueError,
4132 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004133 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 }
4135
4136#ifdef MS_WINDOWS
4137 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004138 if (src->wide)
4139 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140 else
Larry Hastings2f936352014-08-05 14:04:04 +10004141 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004142 Py_END_ALLOW_THREADS
4143
Larry Hastings2f936352014-08-05 14:04:04 +10004144 if (!result)
4145 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146
4147#else
4148 Py_BEGIN_ALLOW_THREADS
4149#ifdef HAVE_RENAMEAT
4150 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004151 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152 else
4153#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004154 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 Py_END_ALLOW_THREADS
4156
Larry Hastings2f936352014-08-05 14:04:04 +10004157 if (result)
4158 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004159#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004160 Py_RETURN_NONE;
4161}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162
Larry Hastings2f936352014-08-05 14:04:04 +10004163
4164/*[clinic input]
4165os.rename
4166
4167 src : path_t
4168 dst : path_t
4169 *
4170 src_dir_fd : dir_fd = None
4171 dst_dir_fd : dir_fd = None
4172
4173Rename a file or directory.
4174
4175If either src_dir_fd or dst_dir_fd is not None, it should be a file
4176 descriptor open to a directory, and the respective path string (src or dst)
4177 should be relative; the path will then be relative to that directory.
4178src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4179 If they are unavailable, using them will raise a NotImplementedError.
4180[clinic start generated code]*/
4181
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004182static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004183os_rename_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04004184 int dst_dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004185/*[clinic end generated code: output=59e803072cf41230 input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004186{
Larry Hastings2f936352014-08-05 14:04:04 +10004187 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004188}
4189
Larry Hastings2f936352014-08-05 14:04:04 +10004190
4191/*[clinic input]
4192os.replace = os.rename
4193
4194Rename a file or directory, overwriting the destination.
4195
4196If either src_dir_fd or dst_dir_fd is not None, it should be a file
4197 descriptor open to a directory, and the respective path string (src or dst)
4198 should be relative; the path will then be relative to that directory.
4199src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4200 If they are unavailable, using them will raise a NotImplementedError."
4201[clinic start generated code]*/
4202
Larry Hastings2f936352014-08-05 14:04:04 +10004203static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004204os_replace_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
4205 int dst_dir_fd)
4206/*[clinic end generated code: output=1968c02e7857422b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4209}
4210
4211
4212/*[clinic input]
4213os.rmdir
4214
4215 path: path_t
4216 *
4217 dir_fd: dir_fd(requires='unlinkat') = None
4218
4219Remove a directory.
4220
4221If dir_fd is not None, it should be a file descriptor open to a directory,
4222 and path should be relative; path will then be relative to that directory.
4223dir_fd may not be implemented on your platform.
4224 If it is unavailable, using it will raise a NotImplementedError.
4225[clinic start generated code]*/
4226
Larry Hastings2f936352014-08-05 14:04:04 +10004227static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004228os_rmdir_impl(PyObject *module, path_t *path, int dir_fd)
4229/*[clinic end generated code: output=080eb54f506e8301 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004230{
4231 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004232
4233 Py_BEGIN_ALLOW_THREADS
4234#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004235 if (path->wide)
4236 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004237 else
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004239 result = !result; /* Windows, success=1, UNIX, success=0 */
4240#else
4241#ifdef HAVE_UNLINKAT
4242 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004243 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004244 else
4245#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004246 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247#endif
4248 Py_END_ALLOW_THREADS
4249
Larry Hastings2f936352014-08-05 14:04:04 +10004250 if (result)
4251 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252
Larry Hastings2f936352014-08-05 14:04:04 +10004253 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004254}
4255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004257#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004258#ifdef MS_WINDOWS
4259/*[clinic input]
4260os.system -> long
4261
4262 command: Py_UNICODE
4263
4264Execute the command in a subshell.
4265[clinic start generated code]*/
4266
Larry Hastings2f936352014-08-05 14:04:04 +10004267static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004268os_system_impl(PyObject *module, Py_UNICODE *command)
4269/*[clinic end generated code: output=96c4dffee36dfb48 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004270{
4271 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004272 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004273 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004275 return result;
4276}
4277#else /* MS_WINDOWS */
4278/*[clinic input]
4279os.system -> long
4280
4281 command: FSConverter
4282
4283Execute the command in a subshell.
4284[clinic start generated code]*/
4285
Larry Hastings2f936352014-08-05 14:04:04 +10004286static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004287os_system_impl(PyObject *module, PyObject *command)
4288/*[clinic end generated code: output=290fc437dd4f33a0 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004289{
4290 long result;
4291 char *bytes = PyBytes_AsString(command);
4292 Py_BEGIN_ALLOW_THREADS
4293 result = system(bytes);
4294 Py_END_ALLOW_THREADS
4295 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004296}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004297#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004298#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Larry Hastings2f936352014-08-05 14:04:04 +10004301/*[clinic input]
4302os.umask
4303
4304 mask: int
4305 /
4306
4307Set the current numeric umask and return the previous umask.
4308[clinic start generated code]*/
4309
Larry Hastings2f936352014-08-05 14:04:04 +10004310static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004311os_umask_impl(PyObject *module, int mask)
4312/*[clinic end generated code: output=a2e33ce3bc1a6e33 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004313{
4314 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004315 if (i < 0)
4316 return posix_error();
4317 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004318}
4319
Brian Curtind40e6f72010-07-08 21:39:08 +00004320#ifdef MS_WINDOWS
4321
4322/* override the default DeleteFileW behavior so that directory
4323symlinks can be removed with this function, the same as with
4324Unix symlinks */
4325BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4326{
4327 WIN32_FILE_ATTRIBUTE_DATA info;
4328 WIN32_FIND_DATAW find_data;
4329 HANDLE find_data_handle;
4330 int is_directory = 0;
4331 int is_link = 0;
4332
4333 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4334 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004335
Brian Curtind40e6f72010-07-08 21:39:08 +00004336 /* Get WIN32_FIND_DATA structure for the path to determine if
4337 it is a symlink */
4338 if(is_directory &&
4339 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4340 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4341
4342 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004343 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4344 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4345 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4346 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004347 FindClose(find_data_handle);
4348 }
4349 }
4350 }
4351
4352 if (is_directory && is_link)
4353 return RemoveDirectoryW(lpFileName);
4354
4355 return DeleteFileW(lpFileName);
4356}
4357#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004359
Larry Hastings2f936352014-08-05 14:04:04 +10004360/*[clinic input]
4361os.unlink
4362
4363 path: path_t
4364 *
4365 dir_fd: dir_fd(requires='unlinkat')=None
4366
4367Remove a file (same as remove()).
4368
4369If dir_fd is not None, it should be a file descriptor open to a directory,
4370 and path should be relative; path will then be relative to that directory.
4371dir_fd may not be implemented on your platform.
4372 If it is unavailable, using it will raise a NotImplementedError.
4373
4374[clinic start generated code]*/
4375
Larry Hastings2f936352014-08-05 14:04:04 +10004376static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004377os_unlink_impl(PyObject *module, path_t *path, int dir_fd)
4378/*[clinic end generated code: output=621797807b9963b1 input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004379{
4380 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004381
4382 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004383 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004385 if (path->wide)
4386 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004387 else
Larry Hastings2f936352014-08-05 14:04:04 +10004388 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 result = !result; /* Windows, success=1, UNIX, success=0 */
4390#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391#ifdef HAVE_UNLINKAT
4392 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004393 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 else
4395#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004396 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004398 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399 Py_END_ALLOW_THREADS
4400
Larry Hastings2f936352014-08-05 14:04:04 +10004401 if (result)
4402 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403
Larry Hastings2f936352014-08-05 14:04:04 +10004404 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004405}
4406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004407
Larry Hastings2f936352014-08-05 14:04:04 +10004408/*[clinic input]
4409os.remove = os.unlink
4410
4411Remove a file (same as unlink()).
4412
4413If dir_fd is not None, it should be a file descriptor open to a directory,
4414 and path should be relative; path will then be relative to that directory.
4415dir_fd may not be implemented on your platform.
4416 If it is unavailable, using it will raise a NotImplementedError.
4417[clinic start generated code]*/
4418
Larry Hastings2f936352014-08-05 14:04:04 +10004419static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004420os_remove_impl(PyObject *module, path_t *path, int dir_fd)
4421/*[clinic end generated code: output=a8535b28f0068883 input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004422{
4423 return os_unlink_impl(module, path, dir_fd);
4424}
4425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004426
Larry Hastings605a62d2012-06-24 04:33:36 -07004427static PyStructSequence_Field uname_result_fields[] = {
4428 {"sysname", "operating system name"},
4429 {"nodename", "name of machine on network (implementation-defined)"},
4430 {"release", "operating system release"},
4431 {"version", "operating system version"},
4432 {"machine", "hardware identifier"},
4433 {NULL}
4434};
4435
4436PyDoc_STRVAR(uname_result__doc__,
4437"uname_result: Result from os.uname().\n\n\
4438This object may be accessed either as a tuple of\n\
4439 (sysname, nodename, release, version, machine),\n\
4440or via the attributes sysname, nodename, release, version, and machine.\n\
4441\n\
4442See os.uname for more information.");
4443
4444static PyStructSequence_Desc uname_result_desc = {
4445 "uname_result", /* name */
4446 uname_result__doc__, /* doc */
4447 uname_result_fields,
4448 5
4449};
4450
4451static PyTypeObject UnameResultType;
4452
4453
4454#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004455/*[clinic input]
4456os.uname
4457
4458Return an object identifying the current operating system.
4459
4460The object behaves like a named tuple with the following fields:
4461 (sysname, nodename, release, version, machine)
4462
4463[clinic start generated code]*/
4464
Larry Hastings2f936352014-08-05 14:04:04 +10004465static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004466os_uname_impl(PyObject *module)
4467/*[clinic end generated code: output=e6a49cf1a1508a19 input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004468{
Victor Stinner8c62be82010-05-06 00:08:46 +00004469 struct utsname u;
4470 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004471 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004472
Victor Stinner8c62be82010-05-06 00:08:46 +00004473 Py_BEGIN_ALLOW_THREADS
4474 res = uname(&u);
4475 Py_END_ALLOW_THREADS
4476 if (res < 0)
4477 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004478
4479 value = PyStructSequence_New(&UnameResultType);
4480 if (value == NULL)
4481 return NULL;
4482
4483#define SET(i, field) \
4484 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004485 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004486 if (!o) { \
4487 Py_DECREF(value); \
4488 return NULL; \
4489 } \
4490 PyStructSequence_SET_ITEM(value, i, o); \
4491 } \
4492
4493 SET(0, u.sysname);
4494 SET(1, u.nodename);
4495 SET(2, u.release);
4496 SET(3, u.version);
4497 SET(4, u.machine);
4498
4499#undef SET
4500
4501 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004502}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004503#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004504
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004505
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506
4507typedef struct {
4508 int now;
4509 time_t atime_s;
4510 long atime_ns;
4511 time_t mtime_s;
4512 long mtime_ns;
4513} utime_t;
4514
4515/*
Victor Stinner484df002014-10-09 13:52:31 +02004516 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 * they also intentionally leak the declaration of a pointer named "time"
4518 */
4519#define UTIME_TO_TIMESPEC \
4520 struct timespec ts[2]; \
4521 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004522 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 time = NULL; \
4524 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004525 ts[0].tv_sec = ut->atime_s; \
4526 ts[0].tv_nsec = ut->atime_ns; \
4527 ts[1].tv_sec = ut->mtime_s; \
4528 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 time = ts; \
4530 } \
4531
4532#define UTIME_TO_TIMEVAL \
4533 struct timeval tv[2]; \
4534 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004535 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536 time = NULL; \
4537 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004538 tv[0].tv_sec = ut->atime_s; \
4539 tv[0].tv_usec = ut->atime_ns / 1000; \
4540 tv[1].tv_sec = ut->mtime_s; \
4541 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 time = tv; \
4543 } \
4544
4545#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004546 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004548 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 time = NULL; \
4550 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004551 u.actime = ut->atime_s; \
4552 u.modtime = ut->mtime_s; \
4553 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 }
4555
4556#define UTIME_TO_TIME_T \
4557 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004558 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004559 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 time = NULL; \
4561 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004562 timet[0] = ut->atime_s; \
4563 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004564 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565 } \
4566
4567
Victor Stinner528a9ab2015-09-03 21:30:26 +02004568#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569
4570static int
Victor Stinner484df002014-10-09 13:52:31 +02004571utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572{
4573#ifdef HAVE_UTIMENSAT
4574 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4575 UTIME_TO_TIMESPEC;
4576 return utimensat(dir_fd, path, time, flags);
4577#elif defined(HAVE_FUTIMESAT)
4578 UTIME_TO_TIMEVAL;
4579 /*
4580 * follow_symlinks will never be false here;
4581 * we only allow !follow_symlinks and dir_fd together
4582 * if we have utimensat()
4583 */
4584 assert(follow_symlinks);
4585 return futimesat(dir_fd, path, time);
4586#endif
4587}
4588
Larry Hastings2f936352014-08-05 14:04:04 +10004589 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4590#else
4591 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592#endif
4593
Victor Stinner528a9ab2015-09-03 21:30:26 +02004594#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595
4596static int
Victor Stinner484df002014-10-09 13:52:31 +02004597utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598{
4599#ifdef HAVE_FUTIMENS
4600 UTIME_TO_TIMESPEC;
4601 return futimens(fd, time);
4602#else
4603 UTIME_TO_TIMEVAL;
4604 return futimes(fd, time);
4605#endif
4606}
4607
Larry Hastings2f936352014-08-05 14:04:04 +10004608 #define PATH_UTIME_HAVE_FD 1
4609#else
4610 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611#endif
4612
4613
4614#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4615 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4616
4617#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4618
4619static int
Victor Stinner484df002014-10-09 13:52:31 +02004620utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621{
4622#ifdef HAVE_UTIMENSAT
4623 UTIME_TO_TIMESPEC;
4624 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4625#else
4626 UTIME_TO_TIMEVAL;
4627 return lutimes(path, time);
4628#endif
4629}
4630
4631#endif
4632
4633#ifndef MS_WINDOWS
4634
4635static int
Victor Stinner484df002014-10-09 13:52:31 +02004636utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637{
4638#ifdef HAVE_UTIMENSAT
4639 UTIME_TO_TIMESPEC;
4640 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4641#elif defined(HAVE_UTIMES)
4642 UTIME_TO_TIMEVAL;
4643 return utimes(path, time);
4644#elif defined(HAVE_UTIME_H)
4645 UTIME_TO_UTIMBUF;
4646 return utime(path, time);
4647#else
4648 UTIME_TO_TIME_T;
4649 return utime(path, time);
4650#endif
4651}
4652
4653#endif
4654
Larry Hastings76ad59b2012-05-03 00:30:07 -07004655static int
4656split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4657{
4658 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004659 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004660 divmod = PyNumber_Divmod(py_long, billion);
4661 if (!divmod)
4662 goto exit;
4663 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4664 if ((*s == -1) && PyErr_Occurred())
4665 goto exit;
4666 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004667 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 goto exit;
4669
4670 result = 1;
4671exit:
4672 Py_XDECREF(divmod);
4673 return result;
4674}
4675
Larry Hastings2f936352014-08-05 14:04:04 +10004676
4677/*[clinic input]
4678os.utime
4679
4680 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4681 times: object = NULL
4682 *
4683 ns: object = NULL
4684 dir_fd: dir_fd(requires='futimensat') = None
4685 follow_symlinks: bool=True
4686
Martin Panter0ff89092015-09-09 01:56:53 +00004687# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004688
4689Set the access and modified time of path.
4690
4691path may always be specified as a string.
4692On some platforms, path may also be specified as an open file descriptor.
4693 If this functionality is unavailable, using it raises an exception.
4694
4695If times is not None, it must be a tuple (atime, mtime);
4696 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004697If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004698 atime_ns and mtime_ns should be expressed as integer nanoseconds
4699 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004700If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004701Specifying tuples for both times and ns is an error.
4702
4703If dir_fd is not None, it should be a file descriptor open to a directory,
4704 and path should be relative; path will then be relative to that directory.
4705If follow_symlinks is False, and the last element of the path is a symbolic
4706 link, utime will modify the symbolic link itself instead of the file the
4707 link points to.
4708It is an error to use dir_fd or follow_symlinks when specifying path
4709 as an open file descriptor.
4710dir_fd and follow_symlinks may not be available on your platform.
4711 If they are unavailable, using them will raise a NotImplementedError.
4712
4713[clinic start generated code]*/
4714
Larry Hastings2f936352014-08-05 14:04:04 +10004715static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004716os_utime_impl(PyObject *module, path_t *path, PyObject *times, PyObject *ns,
4717 int dir_fd, int follow_symlinks)
4718/*[clinic end generated code: output=cfcac69d027b82cf input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004719{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720#ifdef MS_WINDOWS
4721 HANDLE hFile;
4722 FILETIME atime, mtime;
4723#else
4724 int result;
4725#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004726
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004728 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004729
Christian Heimesb3c87242013-08-01 00:08:16 +02004730 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 if (times && (times != Py_None) && ns) {
4733 PyErr_SetString(PyExc_ValueError,
4734 "utime: you may specify either 'times'"
4735 " or 'ns' but not both");
4736 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004737 }
4738
4739 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004740 time_t a_sec, m_sec;
4741 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 PyErr_SetString(PyExc_TypeError,
4744 "utime: 'times' must be either"
4745 " a tuple of two ints or None");
4746 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004747 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004749 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004750 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004751 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004752 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004754 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004755 utime.atime_s = a_sec;
4756 utime.atime_ns = a_nsec;
4757 utime.mtime_s = m_sec;
4758 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004759 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 PyErr_SetString(PyExc_TypeError,
4763 "utime: 'ns' must be a tuple of two ints");
4764 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004765 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004767 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004769 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 &utime.mtime_s, &utime.mtime_ns)) {
4771 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004772 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 }
4774 else {
4775 /* times and ns are both None/unspecified. use "now". */
4776 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777 }
4778
Larry Hastings9cf065c2012-06-22 16:30:09 -07004779#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4780 if (follow_symlinks_specified("utime", follow_symlinks))
4781 goto exit;
4782#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004783
Larry Hastings2f936352014-08-05 14:04:04 +10004784 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4785 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4786 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004788
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789#if !defined(HAVE_UTIMENSAT)
4790 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004791 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 "utime: cannot use dir_fd and follow_symlinks "
4793 "together on this platform");
4794 goto exit;
4795 }
4796#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004798#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004800 if (path->wide)
4801 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 NULL, OPEN_EXISTING,
4803 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 else
Larry Hastings2f936352014-08-05 14:04:04 +10004805 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004806 NULL, OPEN_EXISTING,
4807 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808 Py_END_ALLOW_THREADS
4809 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004810 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004812 }
4813
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004815 GetSystemTimeAsFileTime(&mtime);
4816 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004819 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4820 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 }
4822 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4823 /* Avoid putting the file name into the error here,
4824 as that may confuse the user into believing that
4825 something is wrong with the file, when it also
4826 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004827 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004830#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004832
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4834 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004835 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004836 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004837#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838
Victor Stinner528a9ab2015-09-03 21:30:26 +02004839#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004841 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 else
4843#endif
4844
Victor Stinner528a9ab2015-09-03 21:30:26 +02004845#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004846 if (path->fd != -1)
4847 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 else
4849#endif
4850
Larry Hastings2f936352014-08-05 14:04:04 +10004851 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852
4853 Py_END_ALLOW_THREADS
4854
4855 if (result < 0) {
4856 /* see previous comment about not putting filename in error here */
4857 return_value = posix_error();
4858 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004860
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004861#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862
4863 Py_INCREF(Py_None);
4864 return_value = Py_None;
4865
4866exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004867#ifdef MS_WINDOWS
4868 if (hFile != INVALID_HANDLE_VALUE)
4869 CloseHandle(hFile);
4870#endif
4871 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004872}
4873
Guido van Rossum3b066191991-06-04 19:40:25 +00004874/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004875
Larry Hastings2f936352014-08-05 14:04:04 +10004876
4877/*[clinic input]
4878os._exit
4879
4880 status: int
4881
4882Exit to the system with specified status, without normal exit processing.
4883[clinic start generated code]*/
4884
Larry Hastings2f936352014-08-05 14:04:04 +10004885static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03004886os__exit_impl(PyObject *module, int status)
4887/*[clinic end generated code: output=116e52d9c2260d54 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004888{
4889 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004891}
4892
Martin v. Löwis114619e2002-10-07 06:44:21 +00004893#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4894static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004895free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004896{
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 Py_ssize_t i;
4898 for (i = 0; i < count; i++)
4899 PyMem_Free(array[i]);
4900 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004901}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004902
Antoine Pitrou69f71142009-05-24 21:25:49 +00004903static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004904int fsconvert_strdup(PyObject *o, char**out)
4905{
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 PyObject *bytes;
4907 Py_ssize_t size;
4908 if (!PyUnicode_FSConverter(o, &bytes))
4909 return 0;
4910 size = PyBytes_GET_SIZE(bytes);
4911 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004912 if (!*out) {
4913 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004915 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 memcpy(*out, PyBytes_AsString(bytes), size+1);
4917 Py_DECREF(bytes);
4918 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004919}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004920#endif
4921
Ross Lagerwall7807c352011-03-17 20:20:30 +02004922#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004923static char**
4924parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4925{
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 char **envlist;
4927 Py_ssize_t i, pos, envc;
4928 PyObject *keys=NULL, *vals=NULL;
4929 PyObject *key, *val, *key2, *val2;
4930 char *p, *k, *v;
4931 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004932
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 i = PyMapping_Size(env);
4934 if (i < 0)
4935 return NULL;
4936 envlist = PyMem_NEW(char *, i + 1);
4937 if (envlist == NULL) {
4938 PyErr_NoMemory();
4939 return NULL;
4940 }
4941 envc = 0;
4942 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004943 if (!keys)
4944 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004946 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 goto error;
4948 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4949 PyErr_Format(PyExc_TypeError,
4950 "env.keys() or env.values() is not a list");
4951 goto error;
4952 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 for (pos = 0; pos < i; pos++) {
4955 key = PyList_GetItem(keys, pos);
4956 val = PyList_GetItem(vals, pos);
4957 if (!key || !val)
4958 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004959
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 if (PyUnicode_FSConverter(key, &key2) == 0)
4961 goto error;
4962 if (PyUnicode_FSConverter(val, &val2) == 0) {
4963 Py_DECREF(key2);
4964 goto error;
4965 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004966
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 k = PyBytes_AsString(key2);
4968 v = PyBytes_AsString(val2);
4969 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004970
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 p = PyMem_NEW(char, len);
4972 if (p == NULL) {
4973 PyErr_NoMemory();
4974 Py_DECREF(key2);
4975 Py_DECREF(val2);
4976 goto error;
4977 }
4978 PyOS_snprintf(p, len, "%s=%s", k, v);
4979 envlist[envc++] = p;
4980 Py_DECREF(key2);
4981 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 }
4983 Py_DECREF(vals);
4984 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 envlist[envc] = 0;
4987 *envc_ptr = envc;
4988 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004989
4990error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 Py_XDECREF(keys);
4992 Py_XDECREF(vals);
4993 while (--envc >= 0)
4994 PyMem_DEL(envlist[envc]);
4995 PyMem_DEL(envlist);
4996 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004997}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004998
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999static char**
5000parse_arglist(PyObject* argv, Py_ssize_t *argc)
5001{
5002 int i;
5003 char **argvlist = PyMem_NEW(char *, *argc+1);
5004 if (argvlist == NULL) {
5005 PyErr_NoMemory();
5006 return NULL;
5007 }
5008 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005009 PyObject* item = PySequence_ITEM(argv, i);
5010 if (item == NULL)
5011 goto fail;
5012 if (!fsconvert_strdup(item, &argvlist[i])) {
5013 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014 goto fail;
5015 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005016 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017 }
5018 argvlist[*argc] = NULL;
5019 return argvlist;
5020fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005021 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022 free_string_array(argvlist, *argc);
5023 return NULL;
5024}
5025#endif
5026
Larry Hastings2f936352014-08-05 14:04:04 +10005027
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005029/*[clinic input]
5030os.execv
5031
5032 path: FSConverter
5033 Path of executable file.
5034 argv: object
5035 Tuple or list of strings.
5036 /
5037
5038Execute an executable path with arguments, replacing current process.
5039[clinic start generated code]*/
5040
Larry Hastings2f936352014-08-05 14:04:04 +10005041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005042os_execv_impl(PyObject *module, PyObject *path, PyObject *argv)
5043/*[clinic end generated code: output=b21dc34deeb5b004 input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005044{
5045 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046 char **argvlist;
5047 Py_ssize_t argc;
5048
5049 /* execv has two arguments: (path, argv), where
5050 argv is a list or tuple of strings. */
5051
Larry Hastings2f936352014-08-05 14:04:04 +10005052 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5054 PyErr_SetString(PyExc_TypeError,
5055 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 return NULL;
5057 }
5058 argc = PySequence_Size(argv);
5059 if (argc < 1) {
5060 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 return NULL;
5062 }
5063
5064 argvlist = parse_arglist(argv, &argc);
5065 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 return NULL;
5067 }
5068
Larry Hastings2f936352014-08-05 14:04:04 +10005069 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070
5071 /* If we get here it's definitely an error */
5072
5073 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074 return posix_error();
5075}
5076
Larry Hastings2f936352014-08-05 14:04:04 +10005077
5078/*[clinic input]
5079os.execve
5080
5081 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5082 Path of executable file.
5083 argv: object
5084 Tuple or list of strings.
5085 env: object
5086 Dictionary of strings mapping to strings.
5087
5088Execute an executable path with arguments, replacing current process.
5089[clinic start generated code]*/
5090
Larry Hastings2f936352014-08-05 14:04:04 +10005091static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005092os_execve_impl(PyObject *module, path_t *path, PyObject *argv, PyObject *env)
5093/*[clinic end generated code: output=ff9fa8e4da8bde58 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005094{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005095 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005098
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 /* execve has three arguments: (path, argv, env), where
5100 argv is a list or tuple of strings and env is a dictionary
5101 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005102
Ross Lagerwall7807c352011-03-17 20:20:30 +02005103 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005104 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005105 "execve: argv must be a tuple or list");
5106 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 if (!PyMapping_Check(env)) {
5110 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005111 "execve: environment must be a mapping object");
5112 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005113 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005114
Ross Lagerwall7807c352011-03-17 20:20:30 +02005115 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005117 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005119
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 envlist = parse_envlist(env, &envc);
5121 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005122 goto fail;
5123
Larry Hastings9cf065c2012-06-22 16:30:09 -07005124#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005125 if (path->fd > -1)
5126 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005127 else
5128#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005129 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005130
5131 /* If we get here it's definitely an error */
5132
Larry Hastings2f936352014-08-05 14:04:04 +10005133 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005134
5135 while (--envc >= 0)
5136 PyMem_DEL(envlist[envc]);
5137 PyMem_DEL(envlist);
5138 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005139 if (argvlist)
5140 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141 return NULL;
5142}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005143#endif /* HAVE_EXECV */
5144
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005145
Guido van Rossuma1065681999-01-25 23:20:23 +00005146#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005147/*[clinic input]
5148os.spawnv
5149
5150 mode: int
5151 Mode of process creation.
5152 path: FSConverter
5153 Path of executable file.
5154 argv: object
5155 Tuple or list of strings.
5156 /
5157
5158Execute the program specified by path in a new process.
5159[clinic start generated code]*/
5160
Larry Hastings2f936352014-08-05 14:04:04 +10005161static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005162os_spawnv_impl(PyObject *module, int mode, PyObject *path, PyObject *argv)
5163/*[clinic end generated code: output=c427c0ce40f10638 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005164{
5165 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005167 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 Py_ssize_t argc;
5169 Py_intptr_t spawnval;
5170 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005171
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 /* spawnv has three arguments: (mode, path, argv), where
5173 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005174
Larry Hastings2f936352014-08-05 14:04:04 +10005175 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005176 if (PyList_Check(argv)) {
5177 argc = PyList_Size(argv);
5178 getitem = PyList_GetItem;
5179 }
5180 else if (PyTuple_Check(argv)) {
5181 argc = PyTuple_Size(argv);
5182 getitem = PyTuple_GetItem;
5183 }
5184 else {
5185 PyErr_SetString(PyExc_TypeError,
5186 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 return NULL;
5188 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005189
Victor Stinner8c62be82010-05-06 00:08:46 +00005190 argvlist = PyMem_NEW(char *, argc+1);
5191 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 return PyErr_NoMemory();
5193 }
5194 for (i = 0; i < argc; i++) {
5195 if (!fsconvert_strdup((*getitem)(argv, i),
5196 &argvlist[i])) {
5197 free_string_array(argvlist, i);
5198 PyErr_SetString(
5199 PyExc_TypeError,
5200 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 return NULL;
5202 }
5203 }
5204 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005205
Victor Stinner8c62be82010-05-06 00:08:46 +00005206 if (mode == _OLD_P_OVERLAY)
5207 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005210 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005212
Victor Stinner8c62be82010-05-06 00:08:46 +00005213 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005214
Victor Stinner8c62be82010-05-06 00:08:46 +00005215 if (spawnval == -1)
5216 return posix_error();
5217 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005218 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005219}
5220
5221
Larry Hastings2f936352014-08-05 14:04:04 +10005222/*[clinic input]
5223os.spawnve
5224
5225 mode: int
5226 Mode of process creation.
5227 path: FSConverter
5228 Path of executable file.
5229 argv: object
5230 Tuple or list of strings.
5231 env: object
5232 Dictionary of strings mapping to strings.
5233 /
5234
5235Execute the program specified by path in a new process.
5236[clinic start generated code]*/
5237
Larry Hastings2f936352014-08-05 14:04:04 +10005238static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005239os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5240 PyObject *env)
5241/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005242{
5243 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 char **argvlist;
5245 char **envlist;
5246 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005247 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 Py_intptr_t spawnval;
5249 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5250 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005251
Victor Stinner8c62be82010-05-06 00:08:46 +00005252 /* spawnve has four arguments: (mode, path, argv, env), where
5253 argv is a list or tuple of strings and env is a dictionary
5254 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005255
Larry Hastings2f936352014-08-05 14:04:04 +10005256 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005257 if (PyList_Check(argv)) {
5258 argc = PyList_Size(argv);
5259 getitem = PyList_GetItem;
5260 }
5261 else if (PyTuple_Check(argv)) {
5262 argc = PyTuple_Size(argv);
5263 getitem = PyTuple_GetItem;
5264 }
5265 else {
5266 PyErr_SetString(PyExc_TypeError,
5267 "spawnve() arg 2 must be a tuple or list");
5268 goto fail_0;
5269 }
5270 if (!PyMapping_Check(env)) {
5271 PyErr_SetString(PyExc_TypeError,
5272 "spawnve() arg 3 must be a mapping object");
5273 goto fail_0;
5274 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005275
Victor Stinner8c62be82010-05-06 00:08:46 +00005276 argvlist = PyMem_NEW(char *, argc+1);
5277 if (argvlist == NULL) {
5278 PyErr_NoMemory();
5279 goto fail_0;
5280 }
5281 for (i = 0; i < argc; i++) {
5282 if (!fsconvert_strdup((*getitem)(argv, i),
5283 &argvlist[i]))
5284 {
5285 lastarg = i;
5286 goto fail_1;
5287 }
5288 }
5289 lastarg = argc;
5290 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 envlist = parse_envlist(env, &envc);
5293 if (envlist == NULL)
5294 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005295
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 if (mode == _OLD_P_OVERLAY)
5297 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005300 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005301 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005302
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 if (spawnval == -1)
5304 (void) posix_error();
5305 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005306 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005307
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 while (--envc >= 0)
5309 PyMem_DEL(envlist[envc]);
5310 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005311 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005313 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005315}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005316
Guido van Rossuma1065681999-01-25 23:20:23 +00005317#endif /* HAVE_SPAWNV */
5318
5319
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005320#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005321/*[clinic input]
5322os.fork1
5323
5324Fork a child process with a single multiplexed (i.e., not bound) thread.
5325
5326Return 0 to child process and PID of child to parent process.
5327[clinic start generated code]*/
5328
Larry Hastings2f936352014-08-05 14:04:04 +10005329static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005330os_fork1_impl(PyObject *module)
5331/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005332{
Victor Stinner8c62be82010-05-06 00:08:46 +00005333 pid_t pid;
5334 int result = 0;
5335 _PyImport_AcquireLock();
5336 pid = fork1();
5337 if (pid == 0) {
5338 /* child: this clobbers and resets the import lock. */
5339 PyOS_AfterFork();
5340 } else {
5341 /* parent: release the import lock. */
5342 result = _PyImport_ReleaseLock();
5343 }
5344 if (pid == -1)
5345 return posix_error();
5346 if (result < 0) {
5347 /* Don't clobber the OSError if the fork failed. */
5348 PyErr_SetString(PyExc_RuntimeError,
5349 "not holding the import lock");
5350 return NULL;
5351 }
5352 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005353}
Larry Hastings2f936352014-08-05 14:04:04 +10005354#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005355
5356
Guido van Rossumad0ee831995-03-01 10:34:45 +00005357#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005358/*[clinic input]
5359os.fork
5360
5361Fork a child process.
5362
5363Return 0 to child process and PID of child to parent process.
5364[clinic start generated code]*/
5365
Larry Hastings2f936352014-08-05 14:04:04 +10005366static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005367os_fork_impl(PyObject *module)
5368/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005369{
Victor Stinner8c62be82010-05-06 00:08:46 +00005370 pid_t pid;
5371 int result = 0;
5372 _PyImport_AcquireLock();
5373 pid = fork();
5374 if (pid == 0) {
5375 /* child: this clobbers and resets the import lock. */
5376 PyOS_AfterFork();
5377 } else {
5378 /* parent: release the import lock. */
5379 result = _PyImport_ReleaseLock();
5380 }
5381 if (pid == -1)
5382 return posix_error();
5383 if (result < 0) {
5384 /* Don't clobber the OSError if the fork failed. */
5385 PyErr_SetString(PyExc_RuntimeError,
5386 "not holding the import lock");
5387 return NULL;
5388 }
5389 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005390}
Larry Hastings2f936352014-08-05 14:04:04 +10005391#endif /* HAVE_FORK */
5392
Guido van Rossum85e3b011991-06-03 12:42:10 +00005393
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005394#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005395#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005396/*[clinic input]
5397os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005398
Larry Hastings2f936352014-08-05 14:04:04 +10005399 policy: int
5400
5401Get the maximum scheduling priority for policy.
5402[clinic start generated code]*/
5403
Larry Hastings2f936352014-08-05 14:04:04 +10005404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005405os_sched_get_priority_max_impl(PyObject *module, int policy)
5406/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005407{
5408 int max;
5409
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005410 max = sched_get_priority_max(policy);
5411 if (max < 0)
5412 return posix_error();
5413 return PyLong_FromLong(max);
5414}
5415
Larry Hastings2f936352014-08-05 14:04:04 +10005416
5417/*[clinic input]
5418os.sched_get_priority_min
5419
5420 policy: int
5421
5422Get the minimum scheduling priority for policy.
5423[clinic start generated code]*/
5424
Larry Hastings2f936352014-08-05 14:04:04 +10005425static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005426os_sched_get_priority_min_impl(PyObject *module, int policy)
5427/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005428{
5429 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005430 if (min < 0)
5431 return posix_error();
5432 return PyLong_FromLong(min);
5433}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005434#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5435
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005436
Larry Hastings2f936352014-08-05 14:04:04 +10005437#ifdef HAVE_SCHED_SETSCHEDULER
5438/*[clinic input]
5439os.sched_getscheduler
5440 pid: pid_t
5441 /
5442
5443Get the scheduling policy for the process identifiedy by pid.
5444
5445Passing 0 for pid returns the scheduling policy for the calling process.
5446[clinic start generated code]*/
5447
Larry Hastings2f936352014-08-05 14:04:04 +10005448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005449os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5450/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005451{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005452 int policy;
5453
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005454 policy = sched_getscheduler(pid);
5455 if (policy < 0)
5456 return posix_error();
5457 return PyLong_FromLong(policy);
5458}
Larry Hastings2f936352014-08-05 14:04:04 +10005459#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005460
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005461
5462#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005463/*[clinic input]
5464class os.sched_param "PyObject *" "&SchedParamType"
5465
5466@classmethod
5467os.sched_param.__new__
5468
5469 sched_priority: object
5470 A scheduling parameter.
5471
5472Current has only one field: sched_priority");
5473[clinic start generated code]*/
5474
Larry Hastings2f936352014-08-05 14:04:04 +10005475static PyObject *
5476os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005477/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005478{
5479 PyObject *res;
5480
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005481 res = PyStructSequence_New(type);
5482 if (!res)
5483 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005484 Py_INCREF(sched_priority);
5485 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005486 return res;
5487}
5488
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005489
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005490PyDoc_VAR(os_sched_param__doc__);
5491
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492static PyStructSequence_Field sched_param_fields[] = {
5493 {"sched_priority", "the scheduling priority"},
5494 {0}
5495};
5496
5497static PyStructSequence_Desc sched_param_desc = {
5498 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005499 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005500 sched_param_fields,
5501 1
5502};
5503
5504static int
5505convert_sched_param(PyObject *param, struct sched_param *res)
5506{
5507 long priority;
5508
5509 if (Py_TYPE(param) != &SchedParamType) {
5510 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5511 return 0;
5512 }
5513 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5514 if (priority == -1 && PyErr_Occurred())
5515 return 0;
5516 if (priority > INT_MAX || priority < INT_MIN) {
5517 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5518 return 0;
5519 }
5520 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5521 return 1;
5522}
Larry Hastings2f936352014-08-05 14:04:04 +10005523#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005524
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005525
5526#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005527/*[clinic input]
5528os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005529
Larry Hastings2f936352014-08-05 14:04:04 +10005530 pid: pid_t
5531 policy: int
5532 param: sched_param
5533 /
5534
5535Set the scheduling policy for the process identified by pid.
5536
5537If pid is 0, the calling process is changed.
5538param is an instance of sched_param.
5539[clinic start generated code]*/
5540
Larry Hastings2f936352014-08-05 14:04:04 +10005541static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005542os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005543 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005544/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005545{
Jesus Cea9c822272011-09-10 01:40:52 +02005546 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005547 ** sched_setscheduler() returns 0 in Linux, but the previous
5548 ** scheduling policy under Solaris/Illumos, and others.
5549 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005550 */
Larry Hastings2f936352014-08-05 14:04:04 +10005551 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005552 return posix_error();
5553 Py_RETURN_NONE;
5554}
Larry Hastings2f936352014-08-05 14:04:04 +10005555#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005556
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005557
5558#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005559/*[clinic input]
5560os.sched_getparam
5561 pid: pid_t
5562 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005563
Larry Hastings2f936352014-08-05 14:04:04 +10005564Returns scheduling parameters for the process identified by pid.
5565
5566If pid is 0, returns parameters for the calling process.
5567Return value is an instance of sched_param.
5568[clinic start generated code]*/
5569
Larry Hastings2f936352014-08-05 14:04:04 +10005570static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005571os_sched_getparam_impl(PyObject *module, pid_t pid)
5572/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005573{
5574 struct sched_param param;
5575 PyObject *result;
5576 PyObject *priority;
5577
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005578 if (sched_getparam(pid, &param))
5579 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005580 result = PyStructSequence_New(&SchedParamType);
5581 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005582 return NULL;
5583 priority = PyLong_FromLong(param.sched_priority);
5584 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005585 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586 return NULL;
5587 }
Larry Hastings2f936352014-08-05 14:04:04 +10005588 PyStructSequence_SET_ITEM(result, 0, priority);
5589 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005590}
5591
Larry Hastings2f936352014-08-05 14:04:04 +10005592
5593/*[clinic input]
5594os.sched_setparam
5595 pid: pid_t
5596 param: sched_param
5597 /
5598
5599Set scheduling parameters for the process identified by pid.
5600
5601If pid is 0, sets parameters for the calling process.
5602param should be an instance of sched_param.
5603[clinic start generated code]*/
5604
Larry Hastings2f936352014-08-05 14:04:04 +10005605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005606os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005607 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005608/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005609{
5610 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611 return posix_error();
5612 Py_RETURN_NONE;
5613}
Larry Hastings2f936352014-08-05 14:04:04 +10005614#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005615
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616
5617#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005618/*[clinic input]
5619os.sched_rr_get_interval -> double
5620 pid: pid_t
5621 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005622
Larry Hastings2f936352014-08-05 14:04:04 +10005623Return the round-robin quantum for the process identified by pid, in seconds.
5624
5625Value returned is a float.
5626[clinic start generated code]*/
5627
Larry Hastings2f936352014-08-05 14:04:04 +10005628static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005629os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5630/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005631{
5632 struct timespec interval;
5633 if (sched_rr_get_interval(pid, &interval)) {
5634 posix_error();
5635 return -1.0;
5636 }
5637 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5638}
5639#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005640
Larry Hastings2f936352014-08-05 14:04:04 +10005641
5642/*[clinic input]
5643os.sched_yield
5644
5645Voluntarily relinquish the CPU.
5646[clinic start generated code]*/
5647
Larry Hastings2f936352014-08-05 14:04:04 +10005648static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005649os_sched_yield_impl(PyObject *module)
5650/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005651{
5652 if (sched_yield())
5653 return posix_error();
5654 Py_RETURN_NONE;
5655}
5656
Benjamin Peterson2740af82011-08-02 17:41:34 -05005657#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005658/* The minimum number of CPUs allocated in a cpu_set_t */
5659static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005660
Larry Hastings2f936352014-08-05 14:04:04 +10005661/*[clinic input]
5662os.sched_setaffinity
5663 pid: pid_t
5664 mask : object
5665 /
5666
5667Set the CPU affinity of the process identified by pid to mask.
5668
5669mask should be an iterable of integers identifying CPUs.
5670[clinic start generated code]*/
5671
Larry Hastings2f936352014-08-05 14:04:04 +10005672static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005673os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5674/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005675{
Antoine Pitrou84869872012-08-04 16:16:35 +02005676 int ncpus;
5677 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005678 cpu_set_t *cpu_set = NULL;
5679 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005680
Larry Hastings2f936352014-08-05 14:04:04 +10005681 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005682 if (iterator == NULL)
5683 return NULL;
5684
5685 ncpus = NCPUS_START;
5686 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005687 cpu_set = CPU_ALLOC(ncpus);
5688 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005689 PyErr_NoMemory();
5690 goto error;
5691 }
Larry Hastings2f936352014-08-05 14:04:04 +10005692 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005693
5694 while ((item = PyIter_Next(iterator))) {
5695 long cpu;
5696 if (!PyLong_Check(item)) {
5697 PyErr_Format(PyExc_TypeError,
5698 "expected an iterator of ints, "
5699 "but iterator yielded %R",
5700 Py_TYPE(item));
5701 Py_DECREF(item);
5702 goto error;
5703 }
5704 cpu = PyLong_AsLong(item);
5705 Py_DECREF(item);
5706 if (cpu < 0) {
5707 if (!PyErr_Occurred())
5708 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5709 goto error;
5710 }
5711 if (cpu > INT_MAX - 1) {
5712 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5713 goto error;
5714 }
5715 if (cpu >= ncpus) {
5716 /* Grow CPU mask to fit the CPU number */
5717 int newncpus = ncpus;
5718 cpu_set_t *newmask;
5719 size_t newsetsize;
5720 while (newncpus <= cpu) {
5721 if (newncpus > INT_MAX / 2)
5722 newncpus = cpu + 1;
5723 else
5724 newncpus = newncpus * 2;
5725 }
5726 newmask = CPU_ALLOC(newncpus);
5727 if (newmask == NULL) {
5728 PyErr_NoMemory();
5729 goto error;
5730 }
5731 newsetsize = CPU_ALLOC_SIZE(newncpus);
5732 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005733 memcpy(newmask, cpu_set, setsize);
5734 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005735 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005736 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005737 ncpus = newncpus;
5738 }
Larry Hastings2f936352014-08-05 14:04:04 +10005739 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005740 }
5741 Py_CLEAR(iterator);
5742
Larry Hastings2f936352014-08-05 14:04:04 +10005743 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005744 posix_error();
5745 goto error;
5746 }
Larry Hastings2f936352014-08-05 14:04:04 +10005747 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005748 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005749
5750error:
Larry Hastings2f936352014-08-05 14:04:04 +10005751 if (cpu_set)
5752 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005753 Py_XDECREF(iterator);
5754 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005755}
5756
Larry Hastings2f936352014-08-05 14:04:04 +10005757
5758/*[clinic input]
5759os.sched_getaffinity
5760 pid: pid_t
5761 /
5762
5763Return the affinity of the process identified by pid.
5764
5765The affinity is returned as a set of CPU identifiers.
5766[clinic start generated code]*/
5767
Larry Hastings2f936352014-08-05 14:04:04 +10005768static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005769os_sched_getaffinity_impl(PyObject *module, pid_t pid)
5770/*[clinic end generated code: output=f726f2c193c17a4f input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005771{
Antoine Pitrou84869872012-08-04 16:16:35 +02005772 int cpu, ncpus, count;
5773 size_t setsize;
5774 cpu_set_t *mask = NULL;
5775 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005776
Antoine Pitrou84869872012-08-04 16:16:35 +02005777 ncpus = NCPUS_START;
5778 while (1) {
5779 setsize = CPU_ALLOC_SIZE(ncpus);
5780 mask = CPU_ALLOC(ncpus);
5781 if (mask == NULL)
5782 return PyErr_NoMemory();
5783 if (sched_getaffinity(pid, setsize, mask) == 0)
5784 break;
5785 CPU_FREE(mask);
5786 if (errno != EINVAL)
5787 return posix_error();
5788 if (ncpus > INT_MAX / 2) {
5789 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5790 "a large enough CPU set");
5791 return NULL;
5792 }
5793 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005794 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005795
5796 res = PySet_New(NULL);
5797 if (res == NULL)
5798 goto error;
5799 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5800 if (CPU_ISSET_S(cpu, setsize, mask)) {
5801 PyObject *cpu_num = PyLong_FromLong(cpu);
5802 --count;
5803 if (cpu_num == NULL)
5804 goto error;
5805 if (PySet_Add(res, cpu_num)) {
5806 Py_DECREF(cpu_num);
5807 goto error;
5808 }
5809 Py_DECREF(cpu_num);
5810 }
5811 }
5812 CPU_FREE(mask);
5813 return res;
5814
5815error:
5816 if (mask)
5817 CPU_FREE(mask);
5818 Py_XDECREF(res);
5819 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005820}
5821
Benjamin Peterson2740af82011-08-02 17:41:34 -05005822#endif /* HAVE_SCHED_SETAFFINITY */
5823
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005824#endif /* HAVE_SCHED_H */
5825
Larry Hastings2f936352014-08-05 14:04:04 +10005826
Neal Norwitzb59798b2003-03-21 01:43:31 +00005827/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005828/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5829#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005830#define DEV_PTY_FILE "/dev/ptc"
5831#define HAVE_DEV_PTMX
5832#else
5833#define DEV_PTY_FILE "/dev/ptmx"
5834#endif
5835
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005836#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005837#ifdef HAVE_PTY_H
5838#include <pty.h>
5839#else
5840#ifdef HAVE_LIBUTIL_H
5841#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005842#else
5843#ifdef HAVE_UTIL_H
5844#include <util.h>
5845#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005846#endif /* HAVE_LIBUTIL_H */
5847#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005848#ifdef HAVE_STROPTS_H
5849#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005850#endif
5851#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005852
Larry Hastings2f936352014-08-05 14:04:04 +10005853
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005854#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005855/*[clinic input]
5856os.openpty
5857
5858Open a pseudo-terminal.
5859
5860Return a tuple of (master_fd, slave_fd) containing open file descriptors
5861for both the master and slave ends.
5862[clinic start generated code]*/
5863
Larry Hastings2f936352014-08-05 14:04:04 +10005864static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005865os_openpty_impl(PyObject *module)
5866/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005867{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005868 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005869#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005870 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005871#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005872#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005873 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005874#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005875 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005876#endif
5877#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005878
Thomas Wouters70c21a12000-07-14 14:28:33 +00005879#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005880 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005881 goto posix_error;
5882
5883 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5884 goto error;
5885 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5886 goto error;
5887
Neal Norwitzb59798b2003-03-21 01:43:31 +00005888#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005889 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5890 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005891 goto posix_error;
5892 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5893 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005894
Victor Stinnerdaf45552013-08-28 00:53:59 +02005895 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005896 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005897 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005898
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005899#else
Victor Stinner000de532013-11-25 23:19:58 +01005900 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005901 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005902 goto posix_error;
5903
Victor Stinner8c62be82010-05-06 00:08:46 +00005904 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005905
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 /* change permission of slave */
5907 if (grantpt(master_fd) < 0) {
5908 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005909 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 /* unlock slave */
5913 if (unlockpt(master_fd) < 0) {
5914 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005917
Victor Stinner8c62be82010-05-06 00:08:46 +00005918 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005919
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 slave_name = ptsname(master_fd); /* get name of slave */
5921 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005922 goto posix_error;
5923
5924 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005925 if (slave_fd == -1)
5926 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005927
5928 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5929 goto posix_error;
5930
Neal Norwitzb59798b2003-03-21 01:43:31 +00005931#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005932 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5933 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005934#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005936#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005937#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005938#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005939
Victor Stinner8c62be82010-05-06 00:08:46 +00005940 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005941
Victor Stinnerdaf45552013-08-28 00:53:59 +02005942posix_error:
5943 posix_error();
5944error:
5945 if (master_fd != -1)
5946 close(master_fd);
5947 if (slave_fd != -1)
5948 close(slave_fd);
5949 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005950}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005951#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005952
Larry Hastings2f936352014-08-05 14:04:04 +10005953
Fred Drake8cef4cf2000-06-28 16:40:38 +00005954#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005955/*[clinic input]
5956os.forkpty
5957
5958Fork a new process with a new pseudo-terminal as controlling tty.
5959
5960Returns a tuple of (pid, master_fd).
5961Like fork(), return pid of 0 to the child process,
5962and pid of child to the parent process.
5963To both, return fd of newly opened pseudo-terminal.
5964[clinic start generated code]*/
5965
Larry Hastings2f936352014-08-05 14:04:04 +10005966static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005967os_forkpty_impl(PyObject *module)
5968/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005969{
Victor Stinner8c62be82010-05-06 00:08:46 +00005970 int master_fd = -1, result = 0;
5971 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005972
Victor Stinner8c62be82010-05-06 00:08:46 +00005973 _PyImport_AcquireLock();
5974 pid = forkpty(&master_fd, NULL, NULL, NULL);
5975 if (pid == 0) {
5976 /* child: this clobbers and resets the import lock. */
5977 PyOS_AfterFork();
5978 } else {
5979 /* parent: release the import lock. */
5980 result = _PyImport_ReleaseLock();
5981 }
5982 if (pid == -1)
5983 return posix_error();
5984 if (result < 0) {
5985 /* Don't clobber the OSError if the fork failed. */
5986 PyErr_SetString(PyExc_RuntimeError,
5987 "not holding the import lock");
5988 return NULL;
5989 }
5990 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005991}
Larry Hastings2f936352014-08-05 14:04:04 +10005992#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005993
Ross Lagerwall7807c352011-03-17 20:20:30 +02005994
Guido van Rossumad0ee831995-03-01 10:34:45 +00005995#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005996/*[clinic input]
5997os.getegid
5998
5999Return the current process's effective group id.
6000[clinic start generated code]*/
6001
Larry Hastings2f936352014-08-05 14:04:04 +10006002static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006003os_getegid_impl(PyObject *module)
6004/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006005{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006006 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006007}
Larry Hastings2f936352014-08-05 14:04:04 +10006008#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006009
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006010
Guido van Rossumad0ee831995-03-01 10:34:45 +00006011#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006012/*[clinic input]
6013os.geteuid
6014
6015Return the current process's effective user id.
6016[clinic start generated code]*/
6017
Larry Hastings2f936352014-08-05 14:04:04 +10006018static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006019os_geteuid_impl(PyObject *module)
6020/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006021{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006022 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006023}
Larry Hastings2f936352014-08-05 14:04:04 +10006024#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006025
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006026
Guido van Rossumad0ee831995-03-01 10:34:45 +00006027#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006028/*[clinic input]
6029os.getgid
6030
6031Return the current process's group id.
6032[clinic start generated code]*/
6033
Larry Hastings2f936352014-08-05 14:04:04 +10006034static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006035os_getgid_impl(PyObject *module)
6036/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006037{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006038 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006039}
Larry Hastings2f936352014-08-05 14:04:04 +10006040#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006041
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006042
Larry Hastings2f936352014-08-05 14:04:04 +10006043/*[clinic input]
6044os.getpid
6045
6046Return the current process id.
6047[clinic start generated code]*/
6048
Larry Hastings2f936352014-08-05 14:04:04 +10006049static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006050os_getpid_impl(PyObject *module)
6051/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006052{
Victor Stinner8c62be82010-05-06 00:08:46 +00006053 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006054}
6055
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006056#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006057
6058/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006059PyDoc_STRVAR(posix_getgrouplist__doc__,
6060"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6061Returns a list of groups to which a user belongs.\n\n\
6062 user: username to lookup\n\
6063 group: base group id of the user");
6064
6065static PyObject *
6066posix_getgrouplist(PyObject *self, PyObject *args)
6067{
6068#ifdef NGROUPS_MAX
6069#define MAX_GROUPS NGROUPS_MAX
6070#else
6071 /* defined to be 16 on Solaris7, so this should be a small number */
6072#define MAX_GROUPS 64
6073#endif
6074
6075 const char *user;
6076 int i, ngroups;
6077 PyObject *list;
6078#ifdef __APPLE__
6079 int *groups, basegid;
6080#else
6081 gid_t *groups, basegid;
6082#endif
6083 ngroups = MAX_GROUPS;
6084
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006085#ifdef __APPLE__
6086 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006087 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006088#else
6089 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6090 _Py_Gid_Converter, &basegid))
6091 return NULL;
6092#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006093
6094#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006095 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006096#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006097 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006098#endif
6099 if (groups == NULL)
6100 return PyErr_NoMemory();
6101
6102 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6103 PyMem_Del(groups);
6104 return posix_error();
6105 }
6106
6107 list = PyList_New(ngroups);
6108 if (list == NULL) {
6109 PyMem_Del(groups);
6110 return NULL;
6111 }
6112
6113 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006114#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006115 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006116#else
6117 PyObject *o = _PyLong_FromGid(groups[i]);
6118#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006119 if (o == NULL) {
6120 Py_DECREF(list);
6121 PyMem_Del(groups);
6122 return NULL;
6123 }
6124 PyList_SET_ITEM(list, i, o);
6125 }
6126
6127 PyMem_Del(groups);
6128
6129 return list;
6130}
Larry Hastings2f936352014-08-05 14:04:04 +10006131#endif /* HAVE_GETGROUPLIST */
6132
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006133
Fred Drakec9680921999-12-13 16:37:25 +00006134#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006135/*[clinic input]
6136os.getgroups
6137
6138Return list of supplemental group IDs for the process.
6139[clinic start generated code]*/
6140
Larry Hastings2f936352014-08-05 14:04:04 +10006141static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006142os_getgroups_impl(PyObject *module)
6143/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006144{
6145 PyObject *result = NULL;
6146
Fred Drakec9680921999-12-13 16:37:25 +00006147#ifdef NGROUPS_MAX
6148#define MAX_GROUPS NGROUPS_MAX
6149#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006150 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006151#define MAX_GROUPS 64
6152#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006153 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006154
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006155 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006156 * This is a helper variable to store the intermediate result when
6157 * that happens.
6158 *
6159 * To keep the code readable the OSX behaviour is unconditional,
6160 * according to the POSIX spec this should be safe on all unix-y
6161 * systems.
6162 */
6163 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006165
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006166#ifdef __APPLE__
6167 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6168 * there are more groups than can fit in grouplist. Therefore, on OS X
6169 * always first call getgroups with length 0 to get the actual number
6170 * of groups.
6171 */
6172 n = getgroups(0, NULL);
6173 if (n < 0) {
6174 return posix_error();
6175 } else if (n <= MAX_GROUPS) {
6176 /* groups will fit in existing array */
6177 alt_grouplist = grouplist;
6178 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006179 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006180 if (alt_grouplist == NULL) {
6181 errno = EINVAL;
6182 return posix_error();
6183 }
6184 }
6185
6186 n = getgroups(n, alt_grouplist);
6187 if (n == -1) {
6188 if (alt_grouplist != grouplist) {
6189 PyMem_Free(alt_grouplist);
6190 }
6191 return posix_error();
6192 }
6193#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006194 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006195 if (n < 0) {
6196 if (errno == EINVAL) {
6197 n = getgroups(0, NULL);
6198 if (n == -1) {
6199 return posix_error();
6200 }
6201 if (n == 0) {
6202 /* Avoid malloc(0) */
6203 alt_grouplist = grouplist;
6204 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006205 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006206 if (alt_grouplist == NULL) {
6207 errno = EINVAL;
6208 return posix_error();
6209 }
6210 n = getgroups(n, alt_grouplist);
6211 if (n == -1) {
6212 PyMem_Free(alt_grouplist);
6213 return posix_error();
6214 }
6215 }
6216 } else {
6217 return posix_error();
6218 }
6219 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006220#endif
6221
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006222 result = PyList_New(n);
6223 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006224 int i;
6225 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006226 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006227 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006228 Py_DECREF(result);
6229 result = NULL;
6230 break;
Fred Drakec9680921999-12-13 16:37:25 +00006231 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006233 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006234 }
6235
6236 if (alt_grouplist != grouplist) {
6237 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006239
Fred Drakec9680921999-12-13 16:37:25 +00006240 return result;
6241}
Larry Hastings2f936352014-08-05 14:04:04 +10006242#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006243
Antoine Pitroub7572f02009-12-02 20:46:48 +00006244#ifdef HAVE_INITGROUPS
6245PyDoc_STRVAR(posix_initgroups__doc__,
6246"initgroups(username, gid) -> None\n\n\
6247Call the system initgroups() to initialize the group access list with all of\n\
6248the groups of which the specified username is a member, plus the specified\n\
6249group id.");
6250
Larry Hastings2f936352014-08-05 14:04:04 +10006251/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006252static PyObject *
6253posix_initgroups(PyObject *self, PyObject *args)
6254{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006255 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006256 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006257 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258#ifdef __APPLE__
6259 int gid;
6260#else
6261 gid_t gid;
6262#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006263
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006264#ifdef __APPLE__
6265 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6266 PyUnicode_FSConverter, &oname,
6267 &gid))
6268#else
6269 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6270 PyUnicode_FSConverter, &oname,
6271 _Py_Gid_Converter, &gid))
6272#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006274 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006275
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006276 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006277 Py_DECREF(oname);
6278 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006280
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 Py_INCREF(Py_None);
6282 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006283}
Larry Hastings2f936352014-08-05 14:04:04 +10006284#endif /* HAVE_INITGROUPS */
6285
Antoine Pitroub7572f02009-12-02 20:46:48 +00006286
Martin v. Löwis606edc12002-06-13 21:09:11 +00006287#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006288/*[clinic input]
6289os.getpgid
6290
6291 pid: pid_t
6292
6293Call the system call getpgid(), and return the result.
6294[clinic start generated code]*/
6295
Larry Hastings2f936352014-08-05 14:04:04 +10006296static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006297os_getpgid_impl(PyObject *module, pid_t pid)
6298/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006299{
6300 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006301 if (pgid < 0)
6302 return posix_error();
6303 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006304}
6305#endif /* HAVE_GETPGID */
6306
6307
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006309/*[clinic input]
6310os.getpgrp
6311
6312Return the current process group id.
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006316os_getpgrp_impl(PyObject *module)
6317/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006318{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006319#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006321#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006323#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006324}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006325#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006326
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006327
Guido van Rossumb6775db1994-08-01 11:34:53 +00006328#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006329/*[clinic input]
6330os.setpgrp
6331
6332Make the current process the leader of its process group.
6333[clinic start generated code]*/
6334
Larry Hastings2f936352014-08-05 14:04:04 +10006335static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006336os_setpgrp_impl(PyObject *module)
6337/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006338{
Guido van Rossum64933891994-10-20 21:56:42 +00006339#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006341#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006342 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006343#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006344 return posix_error();
6345 Py_INCREF(Py_None);
6346 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006347}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006348#endif /* HAVE_SETPGRP */
6349
Guido van Rossumad0ee831995-03-01 10:34:45 +00006350#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006351
6352#ifdef MS_WINDOWS
6353#include <tlhelp32.h>
6354
6355static PyObject*
6356win32_getppid()
6357{
6358 HANDLE snapshot;
6359 pid_t mypid;
6360 PyObject* result = NULL;
6361 BOOL have_record;
6362 PROCESSENTRY32 pe;
6363
6364 mypid = getpid(); /* This function never fails */
6365
6366 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6367 if (snapshot == INVALID_HANDLE_VALUE)
6368 return PyErr_SetFromWindowsErr(GetLastError());
6369
6370 pe.dwSize = sizeof(pe);
6371 have_record = Process32First(snapshot, &pe);
6372 while (have_record) {
6373 if (mypid == (pid_t)pe.th32ProcessID) {
6374 /* We could cache the ulong value in a static variable. */
6375 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6376 break;
6377 }
6378
6379 have_record = Process32Next(snapshot, &pe);
6380 }
6381
6382 /* If our loop exits and our pid was not found (result will be NULL)
6383 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6384 * error anyway, so let's raise it. */
6385 if (!result)
6386 result = PyErr_SetFromWindowsErr(GetLastError());
6387
6388 CloseHandle(snapshot);
6389
6390 return result;
6391}
6392#endif /*MS_WINDOWS*/
6393
Larry Hastings2f936352014-08-05 14:04:04 +10006394
6395/*[clinic input]
6396os.getppid
6397
6398Return the parent's process id.
6399
6400If the parent process has already exited, Windows machines will still
6401return its id; others systems will return the id of the 'init' process (1).
6402[clinic start generated code]*/
6403
Larry Hastings2f936352014-08-05 14:04:04 +10006404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006405os_getppid_impl(PyObject *module)
6406/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006407{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006408#ifdef MS_WINDOWS
6409 return win32_getppid();
6410#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006411 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006412#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006413}
6414#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006415
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006416
Fred Drake12c6e2d1999-12-14 21:25:03 +00006417#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006418/*[clinic input]
6419os.getlogin
6420
6421Return the actual login name.
6422[clinic start generated code]*/
6423
Larry Hastings2f936352014-08-05 14:04:04 +10006424static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006425os_getlogin_impl(PyObject *module)
6426/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006427{
Victor Stinner8c62be82010-05-06 00:08:46 +00006428 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006429#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006430 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006431 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006432
6433 if (GetUserNameW(user_name, &num_chars)) {
6434 /* num_chars is the number of unicode chars plus null terminator */
6435 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006436 }
6437 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006438 result = PyErr_SetFromWindowsErr(GetLastError());
6439#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006440 char *name;
6441 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006442
Victor Stinner8c62be82010-05-06 00:08:46 +00006443 errno = 0;
6444 name = getlogin();
6445 if (name == NULL) {
6446 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006447 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006448 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006449 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006450 }
6451 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006452 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006453 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006454#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006455 return result;
6456}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006457#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006458
Larry Hastings2f936352014-08-05 14:04:04 +10006459
Guido van Rossumad0ee831995-03-01 10:34:45 +00006460#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006461/*[clinic input]
6462os.getuid
6463
6464Return the current process's user id.
6465[clinic start generated code]*/
6466
Larry Hastings2f936352014-08-05 14:04:04 +10006467static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006468os_getuid_impl(PyObject *module)
6469/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006470{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006471 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006472}
Larry Hastings2f936352014-08-05 14:04:04 +10006473#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006474
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006475
Brian Curtineb24d742010-04-12 17:16:38 +00006476#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006477#define HAVE_KILL
6478#endif /* MS_WINDOWS */
6479
6480#ifdef HAVE_KILL
6481/*[clinic input]
6482os.kill
6483
6484 pid: pid_t
6485 signal: Py_ssize_t
6486 /
6487
6488Kill a process with a signal.
6489[clinic start generated code]*/
6490
Larry Hastings2f936352014-08-05 14:04:04 +10006491static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006492os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6493/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006494#ifndef MS_WINDOWS
6495{
6496 if (kill(pid, (int)signal) == -1)
6497 return posix_error();
6498 Py_RETURN_NONE;
6499}
6500#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006501{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006502 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006503 DWORD sig = (DWORD)signal;
6504 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006506
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 /* Console processes which share a common console can be sent CTRL+C or
6508 CTRL+BREAK events, provided they handle said events. */
6509 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006510 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006511 err = GetLastError();
6512 PyErr_SetFromWindowsErr(err);
6513 }
6514 else
6515 Py_RETURN_NONE;
6516 }
Brian Curtineb24d742010-04-12 17:16:38 +00006517
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6519 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006520 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006521 if (handle == NULL) {
6522 err = GetLastError();
6523 return PyErr_SetFromWindowsErr(err);
6524 }
Brian Curtineb24d742010-04-12 17:16:38 +00006525
Victor Stinner8c62be82010-05-06 00:08:46 +00006526 if (TerminateProcess(handle, sig) == 0) {
6527 err = GetLastError();
6528 result = PyErr_SetFromWindowsErr(err);
6529 } else {
6530 Py_INCREF(Py_None);
6531 result = Py_None;
6532 }
Brian Curtineb24d742010-04-12 17:16:38 +00006533
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 CloseHandle(handle);
6535 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006536}
Larry Hastings2f936352014-08-05 14:04:04 +10006537#endif /* !MS_WINDOWS */
6538#endif /* HAVE_KILL */
6539
6540
6541#ifdef HAVE_KILLPG
6542/*[clinic input]
6543os.killpg
6544
6545 pgid: pid_t
6546 signal: int
6547 /
6548
6549Kill a process group with a signal.
6550[clinic start generated code]*/
6551
Larry Hastings2f936352014-08-05 14:04:04 +10006552static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006553os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6554/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006555{
6556 /* XXX some man pages make the `pgid` parameter an int, others
6557 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6558 take the same type. Moreover, pid_t is always at least as wide as
6559 int (else compilation of this module fails), which is safe. */
6560 if (killpg(pgid, signal) == -1)
6561 return posix_error();
6562 Py_RETURN_NONE;
6563}
6564#endif /* HAVE_KILLPG */
6565
Brian Curtineb24d742010-04-12 17:16:38 +00006566
Guido van Rossumc0125471996-06-28 18:55:32 +00006567#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006568#ifdef HAVE_SYS_LOCK_H
6569#include <sys/lock.h>
6570#endif
6571
Larry Hastings2f936352014-08-05 14:04:04 +10006572/*[clinic input]
6573os.plock
6574 op: int
6575 /
6576
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006577Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006578[clinic start generated code]*/
6579
Larry Hastings2f936352014-08-05 14:04:04 +10006580static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006581os_plock_impl(PyObject *module, int op)
6582/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006583{
Victor Stinner8c62be82010-05-06 00:08:46 +00006584 if (plock(op) == -1)
6585 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006586 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006587}
Larry Hastings2f936352014-08-05 14:04:04 +10006588#endif /* HAVE_PLOCK */
6589
Guido van Rossumc0125471996-06-28 18:55:32 +00006590
Guido van Rossumb6775db1994-08-01 11:34:53 +00006591#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006592/*[clinic input]
6593os.setuid
6594
6595 uid: uid_t
6596 /
6597
6598Set the current process's user id.
6599[clinic start generated code]*/
6600
Larry Hastings2f936352014-08-05 14:04:04 +10006601static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006602os_setuid_impl(PyObject *module, uid_t uid)
6603/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006604{
Victor Stinner8c62be82010-05-06 00:08:46 +00006605 if (setuid(uid) < 0)
6606 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006607 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006608}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006609#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006610
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006611
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006612#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006613/*[clinic input]
6614os.seteuid
6615
6616 euid: uid_t
6617 /
6618
6619Set the current process's effective user id.
6620[clinic start generated code]*/
6621
Larry Hastings2f936352014-08-05 14:04:04 +10006622static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006623os_seteuid_impl(PyObject *module, uid_t euid)
6624/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006625{
6626 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006628 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006629}
6630#endif /* HAVE_SETEUID */
6631
Larry Hastings2f936352014-08-05 14:04:04 +10006632
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006633#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006634/*[clinic input]
6635os.setegid
6636
6637 egid: gid_t
6638 /
6639
6640Set the current process's effective group id.
6641[clinic start generated code]*/
6642
Larry Hastings2f936352014-08-05 14:04:04 +10006643static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006644os_setegid_impl(PyObject *module, gid_t egid)
6645/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006646{
6647 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006648 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006649 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006650}
6651#endif /* HAVE_SETEGID */
6652
Larry Hastings2f936352014-08-05 14:04:04 +10006653
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006654#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006655/*[clinic input]
6656os.setreuid
6657
6658 ruid: uid_t
6659 euid: uid_t
6660 /
6661
6662Set the current process's real and effective user ids.
6663[clinic start generated code]*/
6664
Larry Hastings2f936352014-08-05 14:04:04 +10006665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006666os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6667/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006668{
Victor Stinner8c62be82010-05-06 00:08:46 +00006669 if (setreuid(ruid, euid) < 0) {
6670 return posix_error();
6671 } else {
6672 Py_INCREF(Py_None);
6673 return Py_None;
6674 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006675}
6676#endif /* HAVE_SETREUID */
6677
Larry Hastings2f936352014-08-05 14:04:04 +10006678
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006679#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006680/*[clinic input]
6681os.setregid
6682
6683 rgid: gid_t
6684 egid: gid_t
6685 /
6686
6687Set the current process's real and effective group ids.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006691os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6692/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006693{
6694 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006695 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006696 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006697}
6698#endif /* HAVE_SETREGID */
6699
Larry Hastings2f936352014-08-05 14:04:04 +10006700
Guido van Rossumb6775db1994-08-01 11:34:53 +00006701#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006702/*[clinic input]
6703os.setgid
6704 gid: gid_t
6705 /
6706
6707Set the current process's group id.
6708[clinic start generated code]*/
6709
Larry Hastings2f936352014-08-05 14:04:04 +10006710static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006711os_setgid_impl(PyObject *module, gid_t gid)
6712/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006713{
Victor Stinner8c62be82010-05-06 00:08:46 +00006714 if (setgid(gid) < 0)
6715 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006716 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006717}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006718#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006719
Larry Hastings2f936352014-08-05 14:04:04 +10006720
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006721#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006722/*[clinic input]
6723os.setgroups
6724
6725 groups: object
6726 /
6727
6728Set the groups of the current process to list.
6729[clinic start generated code]*/
6730
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006731static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006732os_setgroups(PyObject *module, PyObject *groups)
6733/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006734{
Victor Stinner8c62be82010-05-06 00:08:46 +00006735 int i, len;
6736 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006737
Victor Stinner8c62be82010-05-06 00:08:46 +00006738 if (!PySequence_Check(groups)) {
6739 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6740 return NULL;
6741 }
6742 len = PySequence_Size(groups);
6743 if (len > MAX_GROUPS) {
6744 PyErr_SetString(PyExc_ValueError, "too many groups");
6745 return NULL;
6746 }
6747 for(i = 0; i < len; i++) {
6748 PyObject *elem;
6749 elem = PySequence_GetItem(groups, i);
6750 if (!elem)
6751 return NULL;
6752 if (!PyLong_Check(elem)) {
6753 PyErr_SetString(PyExc_TypeError,
6754 "groups must be integers");
6755 Py_DECREF(elem);
6756 return NULL;
6757 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006758 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006759 Py_DECREF(elem);
6760 return NULL;
6761 }
6762 }
6763 Py_DECREF(elem);
6764 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006765
Victor Stinner8c62be82010-05-06 00:08:46 +00006766 if (setgroups(len, grouplist) < 0)
6767 return posix_error();
6768 Py_INCREF(Py_None);
6769 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006770}
6771#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006772
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006773#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6774static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006775wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776{
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 PyObject *result;
6778 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006779 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006780
Victor Stinner8c62be82010-05-06 00:08:46 +00006781 if (pid == -1)
6782 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006783
Victor Stinner8c62be82010-05-06 00:08:46 +00006784 if (struct_rusage == NULL) {
6785 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6786 if (m == NULL)
6787 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006788 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 Py_DECREF(m);
6790 if (struct_rusage == NULL)
6791 return NULL;
6792 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006793
Victor Stinner8c62be82010-05-06 00:08:46 +00006794 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6795 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6796 if (!result)
6797 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006798
6799#ifndef doubletime
6800#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6801#endif
6802
Victor Stinner8c62be82010-05-06 00:08:46 +00006803 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006804 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006806 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006807#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006808 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6809 SET_INT(result, 2, ru->ru_maxrss);
6810 SET_INT(result, 3, ru->ru_ixrss);
6811 SET_INT(result, 4, ru->ru_idrss);
6812 SET_INT(result, 5, ru->ru_isrss);
6813 SET_INT(result, 6, ru->ru_minflt);
6814 SET_INT(result, 7, ru->ru_majflt);
6815 SET_INT(result, 8, ru->ru_nswap);
6816 SET_INT(result, 9, ru->ru_inblock);
6817 SET_INT(result, 10, ru->ru_oublock);
6818 SET_INT(result, 11, ru->ru_msgsnd);
6819 SET_INT(result, 12, ru->ru_msgrcv);
6820 SET_INT(result, 13, ru->ru_nsignals);
6821 SET_INT(result, 14, ru->ru_nvcsw);
6822 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823#undef SET_INT
6824
Victor Stinner8c62be82010-05-06 00:08:46 +00006825 if (PyErr_Occurred()) {
6826 Py_DECREF(result);
6827 return NULL;
6828 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006831}
6832#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6833
Larry Hastings2f936352014-08-05 14:04:04 +10006834
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006836/*[clinic input]
6837os.wait3
6838
6839 options: int
6840Wait for completion of a child process.
6841
6842Returns a tuple of information about the child process:
6843 (pid, status, rusage)
6844[clinic start generated code]*/
6845
Larry Hastings2f936352014-08-05 14:04:04 +10006846static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006847os_wait3_impl(PyObject *module, int options)
6848/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849{
Victor Stinner8c62be82010-05-06 00:08:46 +00006850 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006852 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 WAIT_TYPE status;
6854 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006855
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006856 do {
6857 Py_BEGIN_ALLOW_THREADS
6858 pid = wait3(&status, options, &ru);
6859 Py_END_ALLOW_THREADS
6860 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6861 if (pid < 0)
6862 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863
Victor Stinner4195b5c2012-02-08 23:03:19 +01006864 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865}
6866#endif /* HAVE_WAIT3 */
6867
Larry Hastings2f936352014-08-05 14:04:04 +10006868
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006869#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006870/*[clinic input]
6871
6872os.wait4
6873
6874 pid: pid_t
6875 options: int
6876
6877Wait for completion of a specific child process.
6878
6879Returns a tuple of information about the child process:
6880 (pid, status, rusage)
6881[clinic start generated code]*/
6882
Larry Hastings2f936352014-08-05 14:04:04 +10006883static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006884os_wait4_impl(PyObject *module, pid_t pid, int options)
6885/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006886{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006887 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006888 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006889 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006890 WAIT_TYPE status;
6891 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006893 do {
6894 Py_BEGIN_ALLOW_THREADS
6895 res = wait4(pid, &status, options, &ru);
6896 Py_END_ALLOW_THREADS
6897 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6898 if (res < 0)
6899 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006900
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006901 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006902}
6903#endif /* HAVE_WAIT4 */
6904
Larry Hastings2f936352014-08-05 14:04:04 +10006905
Ross Lagerwall7807c352011-03-17 20:20:30 +02006906#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006907/*[clinic input]
6908os.waitid
6909
6910 idtype: idtype_t
6911 Must be one of be P_PID, P_PGID or P_ALL.
6912 id: id_t
6913 The id to wait on.
6914 options: int
6915 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6916 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6917 /
6918
6919Returns the result of waiting for a process or processes.
6920
6921Returns either waitid_result or None if WNOHANG is specified and there are
6922no children in a waitable state.
6923[clinic start generated code]*/
6924
Larry Hastings2f936352014-08-05 14:04:04 +10006925static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006926os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6927/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006928{
6929 PyObject *result;
6930 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006931 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006932 siginfo_t si;
6933 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006934
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006935 do {
6936 Py_BEGIN_ALLOW_THREADS
6937 res = waitid(idtype, id, &si, options);
6938 Py_END_ALLOW_THREADS
6939 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6940 if (res < 0)
6941 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006942
6943 if (si.si_pid == 0)
6944 Py_RETURN_NONE;
6945
6946 result = PyStructSequence_New(&WaitidResultType);
6947 if (!result)
6948 return NULL;
6949
6950 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006951 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006952 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6953 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6954 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6955 if (PyErr_Occurred()) {
6956 Py_DECREF(result);
6957 return NULL;
6958 }
6959
6960 return result;
6961}
Larry Hastings2f936352014-08-05 14:04:04 +10006962#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006963
Larry Hastings2f936352014-08-05 14:04:04 +10006964
6965#if defined(HAVE_WAITPID)
6966/*[clinic input]
6967os.waitpid
6968 pid: pid_t
6969 options: int
6970 /
6971
6972Wait for completion of a given child process.
6973
6974Returns a tuple of information regarding the child process:
6975 (pid, status)
6976
6977The options argument is ignored on Windows.
6978[clinic start generated code]*/
6979
Larry Hastings2f936352014-08-05 14:04:04 +10006980static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006981os_waitpid_impl(PyObject *module, pid_t pid, int options)
6982/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006983{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006984 pid_t res;
6985 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006986 WAIT_TYPE status;
6987 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006988
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006989 do {
6990 Py_BEGIN_ALLOW_THREADS
6991 res = waitpid(pid, &status, options);
6992 Py_END_ALLOW_THREADS
6993 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6994 if (res < 0)
6995 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006996
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006997 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006998}
Tim Petersab034fa2002-02-01 11:27:43 +00006999#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007000/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007001/*[clinic input]
7002os.waitpid
7003 pid: Py_intptr_t
7004 options: int
7005 /
7006
7007Wait for completion of a given process.
7008
7009Returns a tuple of information regarding the process:
7010 (pid, status << 8)
7011
7012The options argument is ignored on Windows.
7013[clinic start generated code]*/
7014
Larry Hastings2f936352014-08-05 14:04:04 +10007015static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007016os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7017/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007018{
7019 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007020 Py_intptr_t res;
7021 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007022
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007023 do {
7024 Py_BEGIN_ALLOW_THREADS
7025 res = _cwait(&status, pid, options);
7026 Py_END_ALLOW_THREADS
7027 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007028 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007029 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007030
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007032 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007033}
Larry Hastings2f936352014-08-05 14:04:04 +10007034#endif
7035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007036
Guido van Rossumad0ee831995-03-01 10:34:45 +00007037#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007038/*[clinic input]
7039os.wait
7040
7041Wait for completion of a child process.
7042
7043Returns a tuple of information about the child process:
7044 (pid, status)
7045[clinic start generated code]*/
7046
Larry Hastings2f936352014-08-05 14:04:04 +10007047static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007048os_wait_impl(PyObject *module)
7049/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007050{
Victor Stinner8c62be82010-05-06 00:08:46 +00007051 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007052 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007053 WAIT_TYPE status;
7054 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007055
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007056 do {
7057 Py_BEGIN_ALLOW_THREADS
7058 pid = wait(&status);
7059 Py_END_ALLOW_THREADS
7060 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7061 if (pid < 0)
7062 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007063
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007065}
Larry Hastings2f936352014-08-05 14:04:04 +10007066#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007067
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007068
Larry Hastings9cf065c2012-06-22 16:30:09 -07007069#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7070PyDoc_STRVAR(readlink__doc__,
7071"readlink(path, *, dir_fd=None) -> path\n\n\
7072Return a string representing the path to which the symbolic link points.\n\
7073\n\
7074If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7075 and path should be relative; path will then be relative to that directory.\n\
7076dir_fd may not be implemented on your platform.\n\
7077 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007078#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007079
Guido van Rossumb6775db1994-08-01 11:34:53 +00007080#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007081
Larry Hastings2f936352014-08-05 14:04:04 +10007082/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007083static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007084posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007085{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007086 path_t path;
7087 int dir_fd = DEFAULT_DIR_FD;
7088 char buffer[MAXPATHLEN];
7089 ssize_t length;
7090 PyObject *return_value = NULL;
7091 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007092
Larry Hastings9cf065c2012-06-22 16:30:09 -07007093 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007094 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7096 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007097 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007098 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007099
Victor Stinner8c62be82010-05-06 00:08:46 +00007100 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101#ifdef HAVE_READLINKAT
7102 if (dir_fd != DEFAULT_DIR_FD)
7103 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007104 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105#endif
7106 length = readlink(path.narrow, buffer, sizeof(buffer));
7107 Py_END_ALLOW_THREADS
7108
7109 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007110 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111 goto exit;
7112 }
7113
7114 if (PyUnicode_Check(path.object))
7115 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7116 else
7117 return_value = PyBytes_FromStringAndSize(buffer, length);
7118exit:
7119 path_cleanup(&path);
7120 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007121}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122
Guido van Rossumb6775db1994-08-01 11:34:53 +00007123#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007124
Larry Hastings2f936352014-08-05 14:04:04 +10007125#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7126
7127static PyObject *
7128win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7129{
7130 wchar_t *path;
7131 DWORD n_bytes_returned;
7132 DWORD io_result;
7133 PyObject *po, *result;
7134 int dir_fd;
7135 HANDLE reparse_point_handle;
7136
7137 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7138 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7139 wchar_t *print_name;
7140
7141 static char *keywords[] = {"path", "dir_fd", NULL};
7142
7143 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7144 &po,
7145 dir_fd_unavailable, &dir_fd
7146 ))
7147 return NULL;
7148
7149 path = PyUnicode_AsUnicode(po);
7150 if (path == NULL)
7151 return NULL;
7152
7153 /* First get a handle to the reparse point */
7154 Py_BEGIN_ALLOW_THREADS
7155 reparse_point_handle = CreateFileW(
7156 path,
7157 0,
7158 0,
7159 0,
7160 OPEN_EXISTING,
7161 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7162 0);
7163 Py_END_ALLOW_THREADS
7164
7165 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7166 return win32_error_object("readlink", po);
7167
7168 Py_BEGIN_ALLOW_THREADS
7169 /* New call DeviceIoControl to read the reparse point */
7170 io_result = DeviceIoControl(
7171 reparse_point_handle,
7172 FSCTL_GET_REPARSE_POINT,
7173 0, 0, /* in buffer */
7174 target_buffer, sizeof(target_buffer),
7175 &n_bytes_returned,
7176 0 /* we're not using OVERLAPPED_IO */
7177 );
7178 CloseHandle(reparse_point_handle);
7179 Py_END_ALLOW_THREADS
7180
7181 if (io_result==0)
7182 return win32_error_object("readlink", po);
7183
7184 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7185 {
7186 PyErr_SetString(PyExc_ValueError,
7187 "not a symbolic link");
7188 return NULL;
7189 }
7190 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7191 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7192
7193 result = PyUnicode_FromWideChar(print_name,
7194 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7195 return result;
7196}
7197
7198#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7199
7200
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007201
Larry Hastings9cf065c2012-06-22 16:30:09 -07007202#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007203
7204#if defined(MS_WINDOWS)
7205
7206/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7207static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7208static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007209
Larry Hastings9cf065c2012-06-22 16:30:09 -07007210static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007211check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007212{
7213 HINSTANCE hKernel32;
7214 /* only recheck */
7215 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7216 return 1;
7217 hKernel32 = GetModuleHandleW(L"KERNEL32");
7218 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7219 "CreateSymbolicLinkW");
7220 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7221 "CreateSymbolicLinkA");
7222 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7223}
7224
Victor Stinner31b3b922013-06-05 01:49:17 +02007225/* Remove the last portion of the path */
7226static void
7227_dirnameW(WCHAR *path)
7228{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007229 WCHAR *ptr;
7230
7231 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007232 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007233 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007234 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007235 }
7236 *ptr = 0;
7237}
7238
Victor Stinner31b3b922013-06-05 01:49:17 +02007239/* Remove the last portion of the path */
7240static void
7241_dirnameA(char *path)
7242{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243 char *ptr;
7244
7245 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007246 for(ptr = path + strlen(path); ptr != path; ptr--) {
7247 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007248 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007249 }
7250 *ptr = 0;
7251}
7252
Victor Stinner31b3b922013-06-05 01:49:17 +02007253/* Is this path absolute? */
7254static int
7255_is_absW(const WCHAR *path)
7256{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007257 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7258
7259}
7260
Victor Stinner31b3b922013-06-05 01:49:17 +02007261/* Is this path absolute? */
7262static int
7263_is_absA(const char *path)
7264{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007265 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7266
7267}
7268
Victor Stinner31b3b922013-06-05 01:49:17 +02007269/* join root and rest with a backslash */
7270static void
7271_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7272{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007273 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007274
Victor Stinner31b3b922013-06-05 01:49:17 +02007275 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276 wcscpy(dest_path, rest);
7277 return;
7278 }
7279
7280 root_len = wcslen(root);
7281
7282 wcscpy(dest_path, root);
7283 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007284 dest_path[root_len] = L'\\';
7285 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007286 }
7287 wcscpy(dest_path+root_len, rest);
7288}
7289
Victor Stinner31b3b922013-06-05 01:49:17 +02007290/* join root and rest with a backslash */
7291static void
7292_joinA(char *dest_path, const char *root, const char *rest)
7293{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007294 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295
Victor Stinner31b3b922013-06-05 01:49:17 +02007296 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 strcpy(dest_path, rest);
7298 return;
7299 }
7300
7301 root_len = strlen(root);
7302
7303 strcpy(dest_path, root);
7304 if(root_len) {
7305 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007306 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007307 }
7308 strcpy(dest_path+root_len, rest);
7309}
7310
Victor Stinner31b3b922013-06-05 01:49:17 +02007311/* Return True if the path at src relative to dest is a directory */
7312static int
7313_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315 WIN32_FILE_ATTRIBUTE_DATA src_info;
7316 WCHAR dest_parent[MAX_PATH];
7317 WCHAR src_resolved[MAX_PATH] = L"";
7318
7319 /* dest_parent = os.path.dirname(dest) */
7320 wcscpy(dest_parent, dest);
7321 _dirnameW(dest_parent);
7322 /* src_resolved = os.path.join(dest_parent, src) */
7323 _joinW(src_resolved, dest_parent, src);
7324 return (
7325 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7326 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7327 );
7328}
7329
Victor Stinner31b3b922013-06-05 01:49:17 +02007330/* Return True if the path at src relative to dest is a directory */
7331static int
7332_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007334 WIN32_FILE_ATTRIBUTE_DATA src_info;
7335 char dest_parent[MAX_PATH];
7336 char src_resolved[MAX_PATH] = "";
7337
7338 /* dest_parent = os.path.dirname(dest) */
7339 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007340 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007341 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007342 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007343 return (
7344 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7345 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7346 );
7347}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007348#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007349
Larry Hastings2f936352014-08-05 14:04:04 +10007350
7351/*[clinic input]
7352os.symlink
7353 src: path_t
7354 dst: path_t
7355 target_is_directory: bool = False
7356 *
7357 dir_fd: dir_fd(requires='symlinkat')=None
7358
7359# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7360
7361Create a symbolic link pointing to src named dst.
7362
7363target_is_directory is required on Windows if the target is to be
7364 interpreted as a directory. (On Windows, symlink requires
7365 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7366 target_is_directory is ignored on non-Windows platforms.
7367
7368If dir_fd is not None, it should be a file descriptor open to a directory,
7369 and path should be relative; path will then be relative to that directory.
7370dir_fd may not be implemented on your platform.
7371 If it is unavailable, using it will raise a NotImplementedError.
7372
7373[clinic start generated code]*/
7374
Larry Hastings2f936352014-08-05 14:04:04 +10007375static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007376os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007377 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007378/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007379{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380#ifdef MS_WINDOWS
7381 DWORD result;
7382#else
7383 int result;
7384#endif
7385
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386#ifdef MS_WINDOWS
7387 if (!check_CreateSymbolicLink()) {
7388 PyErr_SetString(PyExc_NotImplementedError,
7389 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007390 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007391 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392 if (!win32_can_symlink) {
7393 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007394 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007395 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396#endif
7397
Larry Hastings2f936352014-08-05 14:04:04 +10007398 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007399 PyErr_SetString(PyExc_ValueError,
7400 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007401 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 }
7403
7404#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007405
Larry Hastings9cf065c2012-06-22 16:30:09 -07007406 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007407 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007408 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007409 target_is_directory |= _check_dirW(src->wide, dst->wide);
7410 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007411 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007412 }
7413 else {
7414 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007415 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7416 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007418 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419 Py_END_ALLOW_THREADS
7420
Larry Hastings2f936352014-08-05 14:04:04 +10007421 if (!result)
7422 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007423
7424#else
7425
7426 Py_BEGIN_ALLOW_THREADS
7427#if HAVE_SYMLINKAT
7428 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007429 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 else
7431#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007432 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433 Py_END_ALLOW_THREADS
7434
Larry Hastings2f936352014-08-05 14:04:04 +10007435 if (result)
7436 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007437#endif
7438
Larry Hastings2f936352014-08-05 14:04:04 +10007439 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007440}
7441#endif /* HAVE_SYMLINK */
7442
Larry Hastings9cf065c2012-06-22 16:30:09 -07007443
Brian Curtind40e6f72010-07-08 21:39:08 +00007444
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007445
Larry Hastings605a62d2012-06-24 04:33:36 -07007446static PyStructSequence_Field times_result_fields[] = {
7447 {"user", "user time"},
7448 {"system", "system time"},
7449 {"children_user", "user time of children"},
7450 {"children_system", "system time of children"},
7451 {"elapsed", "elapsed time since an arbitrary point in the past"},
7452 {NULL}
7453};
7454
7455PyDoc_STRVAR(times_result__doc__,
7456"times_result: Result from os.times().\n\n\
7457This object may be accessed either as a tuple of\n\
7458 (user, system, children_user, children_system, elapsed),\n\
7459or via the attributes user, system, children_user, children_system,\n\
7460and elapsed.\n\
7461\n\
7462See os.times for more information.");
7463
7464static PyStructSequence_Desc times_result_desc = {
7465 "times_result", /* name */
7466 times_result__doc__, /* doc */
7467 times_result_fields,
7468 5
7469};
7470
7471static PyTypeObject TimesResultType;
7472
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007473#ifdef MS_WINDOWS
7474#define HAVE_TIMES /* mandatory, for the method table */
7475#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007476
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007477#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007478
7479static PyObject *
7480build_times_result(double user, double system,
7481 double children_user, double children_system,
7482 double elapsed)
7483{
7484 PyObject *value = PyStructSequence_New(&TimesResultType);
7485 if (value == NULL)
7486 return NULL;
7487
7488#define SET(i, field) \
7489 { \
7490 PyObject *o = PyFloat_FromDouble(field); \
7491 if (!o) { \
7492 Py_DECREF(value); \
7493 return NULL; \
7494 } \
7495 PyStructSequence_SET_ITEM(value, i, o); \
7496 } \
7497
7498 SET(0, user);
7499 SET(1, system);
7500 SET(2, children_user);
7501 SET(3, children_system);
7502 SET(4, elapsed);
7503
7504#undef SET
7505
7506 return value;
7507}
7508
Larry Hastings605a62d2012-06-24 04:33:36 -07007509
Larry Hastings2f936352014-08-05 14:04:04 +10007510#ifndef MS_WINDOWS
7511#define NEED_TICKS_PER_SECOND
7512static long ticks_per_second = -1;
7513#endif /* MS_WINDOWS */
7514
7515/*[clinic input]
7516os.times
7517
7518Return a collection containing process timing information.
7519
7520The object returned behaves like a named tuple with these fields:
7521 (utime, stime, cutime, cstime, elapsed_time)
7522All fields are floating point numbers.
7523[clinic start generated code]*/
7524
Larry Hastings2f936352014-08-05 14:04:04 +10007525static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007526os_times_impl(PyObject *module)
7527/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007528#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007529{
Victor Stinner8c62be82010-05-06 00:08:46 +00007530 FILETIME create, exit, kernel, user;
7531 HANDLE hProc;
7532 hProc = GetCurrentProcess();
7533 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7534 /* The fields of a FILETIME structure are the hi and lo part
7535 of a 64-bit value expressed in 100 nanosecond units.
7536 1e7 is one second in such units; 1e-7 the inverse.
7537 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7538 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007539 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007540 (double)(user.dwHighDateTime*429.4967296 +
7541 user.dwLowDateTime*1e-7),
7542 (double)(kernel.dwHighDateTime*429.4967296 +
7543 kernel.dwLowDateTime*1e-7),
7544 (double)0,
7545 (double)0,
7546 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007547}
Larry Hastings2f936352014-08-05 14:04:04 +10007548#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007549{
Larry Hastings2f936352014-08-05 14:04:04 +10007550
7551
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007552 struct tms t;
7553 clock_t c;
7554 errno = 0;
7555 c = times(&t);
7556 if (c == (clock_t) -1)
7557 return posix_error();
7558 return build_times_result(
7559 (double)t.tms_utime / ticks_per_second,
7560 (double)t.tms_stime / ticks_per_second,
7561 (double)t.tms_cutime / ticks_per_second,
7562 (double)t.tms_cstime / ticks_per_second,
7563 (double)c / ticks_per_second);
7564}
Larry Hastings2f936352014-08-05 14:04:04 +10007565#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007566#endif /* HAVE_TIMES */
7567
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007568
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007569#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007570/*[clinic input]
7571os.getsid
7572
7573 pid: pid_t
7574 /
7575
7576Call the system call getsid(pid) and return the result.
7577[clinic start generated code]*/
7578
Larry Hastings2f936352014-08-05 14:04:04 +10007579static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007580os_getsid_impl(PyObject *module, pid_t pid)
7581/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007582{
Victor Stinner8c62be82010-05-06 00:08:46 +00007583 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 sid = getsid(pid);
7585 if (sid < 0)
7586 return posix_error();
7587 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007588}
7589#endif /* HAVE_GETSID */
7590
7591
Guido van Rossumb6775db1994-08-01 11:34:53 +00007592#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007593/*[clinic input]
7594os.setsid
7595
7596Call the system call setsid().
7597[clinic start generated code]*/
7598
Larry Hastings2f936352014-08-05 14:04:04 +10007599static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007600os_setsid_impl(PyObject *module)
7601/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007602{
Victor Stinner8c62be82010-05-06 00:08:46 +00007603 if (setsid() < 0)
7604 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007605 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007606}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007607#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007608
Larry Hastings2f936352014-08-05 14:04:04 +10007609
Guido van Rossumb6775db1994-08-01 11:34:53 +00007610#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007611/*[clinic input]
7612os.setpgid
7613
7614 pid: pid_t
7615 pgrp: pid_t
7616 /
7617
7618Call the system call setpgid(pid, pgrp).
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007622os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7623/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007624{
Victor Stinner8c62be82010-05-06 00:08:46 +00007625 if (setpgid(pid, pgrp) < 0)
7626 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007627 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007628}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007629#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007630
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007631
Guido van Rossumb6775db1994-08-01 11:34:53 +00007632#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007633/*[clinic input]
7634os.tcgetpgrp
7635
7636 fd: int
7637 /
7638
7639Return the process group associated with the terminal specified by fd.
7640[clinic start generated code]*/
7641
Larry Hastings2f936352014-08-05 14:04:04 +10007642static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007643os_tcgetpgrp_impl(PyObject *module, int fd)
7644/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007645{
7646 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007647 if (pgid < 0)
7648 return posix_error();
7649 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007650}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007651#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007652
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007653
Guido van Rossumb6775db1994-08-01 11:34:53 +00007654#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007655/*[clinic input]
7656os.tcsetpgrp
7657
7658 fd: int
7659 pgid: pid_t
7660 /
7661
7662Set the process group associated with the terminal specified by fd.
7663[clinic start generated code]*/
7664
Larry Hastings2f936352014-08-05 14:04:04 +10007665static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007666os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7667/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007668{
Victor Stinner8c62be82010-05-06 00:08:46 +00007669 if (tcsetpgrp(fd, pgid) < 0)
7670 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007671 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007672}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007673#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007674
Guido van Rossum687dd131993-05-17 08:34:16 +00007675/* Functions acting on file descriptors */
7676
Victor Stinnerdaf45552013-08-28 00:53:59 +02007677#ifdef O_CLOEXEC
7678extern int _Py_open_cloexec_works;
7679#endif
7680
Larry Hastings2f936352014-08-05 14:04:04 +10007681
7682/*[clinic input]
7683os.open -> int
7684 path: path_t
7685 flags: int
7686 mode: int = 0o777
7687 *
7688 dir_fd: dir_fd(requires='openat') = None
7689
7690# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7691
7692Open a file for low level IO. Returns a file descriptor (integer).
7693
7694If dir_fd is not None, it should be a file descriptor open to a directory,
7695 and path should be relative; path will then be relative to that directory.
7696dir_fd may not be implemented on your platform.
7697 If it is unavailable, using it will raise a NotImplementedError.
7698[clinic start generated code]*/
7699
Larry Hastings2f936352014-08-05 14:04:04 +10007700static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007701os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7702/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007703{
7704 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007705 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007706
Victor Stinnerdaf45552013-08-28 00:53:59 +02007707#ifdef O_CLOEXEC
7708 int *atomic_flag_works = &_Py_open_cloexec_works;
7709#elif !defined(MS_WINDOWS)
7710 int *atomic_flag_works = NULL;
7711#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007712
Victor Stinnerdaf45552013-08-28 00:53:59 +02007713#ifdef MS_WINDOWS
7714 flags |= O_NOINHERIT;
7715#elif defined(O_CLOEXEC)
7716 flags |= O_CLOEXEC;
7717#endif
7718
Steve Dower8fc89802015-04-12 00:26:27 -04007719 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007720 do {
7721 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007722#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007723 if (path->wide)
7724 fd = _wopen(path->wide, flags, mode);
7725 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007726#endif
7727#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007728 if (dir_fd != DEFAULT_DIR_FD)
7729 fd = openat(dir_fd, path->narrow, flags, mode);
7730 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007731#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007732 fd = open(path->narrow, flags, mode);
7733 Py_END_ALLOW_THREADS
7734 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007735 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007736
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007737 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007738 if (!async_err)
7739 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007740 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007741 }
7742
Victor Stinnerdaf45552013-08-28 00:53:59 +02007743#ifndef MS_WINDOWS
7744 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7745 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007746 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007747 }
7748#endif
7749
Larry Hastings2f936352014-08-05 14:04:04 +10007750 return fd;
7751}
7752
7753
7754/*[clinic input]
7755os.close
7756
7757 fd: int
7758
7759Close a file descriptor.
7760[clinic start generated code]*/
7761
Barry Warsaw53699e91996-12-10 23:23:01 +00007762static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007763os_close_impl(PyObject *module, int fd)
7764/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007765{
Larry Hastings2f936352014-08-05 14:04:04 +10007766 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007767 if (!_PyVerify_fd(fd))
7768 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007769 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7770 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7771 * for more details.
7772 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007773 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007774 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007776 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 Py_END_ALLOW_THREADS
7778 if (res < 0)
7779 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007780 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007781}
7782
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007783
Larry Hastings2f936352014-08-05 14:04:04 +10007784/*[clinic input]
7785os.closerange
7786
7787 fd_low: int
7788 fd_high: int
7789 /
7790
7791Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7792[clinic start generated code]*/
7793
Larry Hastings2f936352014-08-05 14:04:04 +10007794static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007795os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7796/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007797{
7798 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007800 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007801 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 if (_PyVerify_fd(i))
7803 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007804 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007805 Py_END_ALLOW_THREADS
7806 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007807}
7808
7809
Larry Hastings2f936352014-08-05 14:04:04 +10007810/*[clinic input]
7811os.dup -> int
7812
7813 fd: int
7814 /
7815
7816Return a duplicate of a file descriptor.
7817[clinic start generated code]*/
7818
Larry Hastings2f936352014-08-05 14:04:04 +10007819static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007820os_dup_impl(PyObject *module, int fd)
7821/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007822{
7823 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007824}
7825
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007826
Larry Hastings2f936352014-08-05 14:04:04 +10007827/*[clinic input]
7828os.dup2
7829 fd: int
7830 fd2: int
7831 inheritable: bool=True
7832
7833Duplicate file descriptor.
7834[clinic start generated code]*/
7835
Larry Hastings2f936352014-08-05 14:04:04 +10007836static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007837os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7838/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007839{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007840 int res;
7841#if defined(HAVE_DUP3) && \
7842 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7843 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7844 int dup3_works = -1;
7845#endif
7846
Victor Stinner8c62be82010-05-06 00:08:46 +00007847 if (!_PyVerify_fd_dup2(fd, fd2))
7848 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007849
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007850 /* dup2() can fail with EINTR if the target FD is already open, because it
7851 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7852 * upon close(), and therefore below.
7853 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007854#ifdef MS_WINDOWS
7855 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007856 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007858 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007859 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007860 if (res < 0)
7861 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007862
7863 /* Character files like console cannot be make non-inheritable */
7864 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7865 close(fd2);
7866 return NULL;
7867 }
7868
7869#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7870 Py_BEGIN_ALLOW_THREADS
7871 if (!inheritable)
7872 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7873 else
7874 res = dup2(fd, fd2);
7875 Py_END_ALLOW_THREADS
7876 if (res < 0)
7877 return posix_error();
7878
7879#else
7880
7881#ifdef HAVE_DUP3
7882 if (!inheritable && dup3_works != 0) {
7883 Py_BEGIN_ALLOW_THREADS
7884 res = dup3(fd, fd2, O_CLOEXEC);
7885 Py_END_ALLOW_THREADS
7886 if (res < 0) {
7887 if (dup3_works == -1)
7888 dup3_works = (errno != ENOSYS);
7889 if (dup3_works)
7890 return posix_error();
7891 }
7892 }
7893
7894 if (inheritable || dup3_works == 0)
7895 {
7896#endif
7897 Py_BEGIN_ALLOW_THREADS
7898 res = dup2(fd, fd2);
7899 Py_END_ALLOW_THREADS
7900 if (res < 0)
7901 return posix_error();
7902
7903 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7904 close(fd2);
7905 return NULL;
7906 }
7907#ifdef HAVE_DUP3
7908 }
7909#endif
7910
7911#endif
7912
Larry Hastings2f936352014-08-05 14:04:04 +10007913 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007914}
7915
Larry Hastings2f936352014-08-05 14:04:04 +10007916
Ross Lagerwall7807c352011-03-17 20:20:30 +02007917#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007918/*[clinic input]
7919os.lockf
7920
7921 fd: int
7922 An open file descriptor.
7923 command: int
7924 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7925 length: Py_off_t
7926 The number of bytes to lock, starting at the current position.
7927 /
7928
7929Apply, test or remove a POSIX lock on an open file descriptor.
7930
7931[clinic start generated code]*/
7932
Larry Hastings2f936352014-08-05 14:04:04 +10007933static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007934os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7935/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007936{
7937 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938
7939 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007940 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007941 Py_END_ALLOW_THREADS
7942
7943 if (res < 0)
7944 return posix_error();
7945
7946 Py_RETURN_NONE;
7947}
Larry Hastings2f936352014-08-05 14:04:04 +10007948#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007949
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007950
Larry Hastings2f936352014-08-05 14:04:04 +10007951/*[clinic input]
7952os.lseek -> Py_off_t
7953
7954 fd: int
7955 position: Py_off_t
7956 how: int
7957 /
7958
7959Set the position of a file descriptor. Return the new position.
7960
7961Return the new cursor position in number of bytes
7962relative to the beginning of the file.
7963[clinic start generated code]*/
7964
Larry Hastings2f936352014-08-05 14:04:04 +10007965static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007966os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7967/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007968{
7969 Py_off_t result;
7970
7971 if (!_PyVerify_fd(fd)) {
7972 posix_error();
7973 return -1;
7974 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007975#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7977 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007978 case 0: how = SEEK_SET; break;
7979 case 1: how = SEEK_CUR; break;
7980 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007982#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007983
Victor Stinner8c62be82010-05-06 00:08:46 +00007984 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007985 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007986
Larry Hastings2f936352014-08-05 14:04:04 +10007987 if (!_PyVerify_fd(fd)) {
7988 posix_error();
7989 return -1;
7990 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007991 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007992 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007993#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007994 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007995#else
Larry Hastings2f936352014-08-05 14:04:04 +10007996 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007997#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007998 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008000 if (result < 0)
8001 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008002
Larry Hastings2f936352014-08-05 14:04:04 +10008003 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008004}
8005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008006
Larry Hastings2f936352014-08-05 14:04:04 +10008007/*[clinic input]
8008os.read
8009 fd: int
8010 length: Py_ssize_t
8011 /
8012
8013Read from a file descriptor. Returns a bytes object.
8014[clinic start generated code]*/
8015
Larry Hastings2f936352014-08-05 14:04:04 +10008016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008017os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8018/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008019{
Victor Stinner8c62be82010-05-06 00:08:46 +00008020 Py_ssize_t n;
8021 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008022
8023 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 errno = EINVAL;
8025 return posix_error();
8026 }
Larry Hastings2f936352014-08-05 14:04:04 +10008027
8028#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008029 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008030 if (length > INT_MAX)
8031 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008032#endif
8033
8034 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 if (buffer == NULL)
8036 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008037
Victor Stinner66aab0c2015-03-19 22:53:20 +01008038 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8039 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008041 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 }
Larry Hastings2f936352014-08-05 14:04:04 +10008043
8044 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008045 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008046
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008048}
8049
Ross Lagerwall7807c352011-03-17 20:20:30 +02008050#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8051 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008052static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8054{
8055 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008056 Py_ssize_t blen, total = 0;
8057
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008058 *iov = PyMem_New(struct iovec, cnt);
8059 if (*iov == NULL) {
8060 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008061 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008062 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008063
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 *buf = PyMem_New(Py_buffer, cnt);
8065 if (*buf == NULL) {
8066 PyMem_Del(*iov);
8067 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008068 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008069 }
8070
8071 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008072 PyObject *item = PySequence_GetItem(seq, i);
8073 if (item == NULL)
8074 goto fail;
8075 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8076 Py_DECREF(item);
8077 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008078 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008079 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008081 blen = (*buf)[i].len;
8082 (*iov)[i].iov_len = blen;
8083 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008085 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008086
8087fail:
8088 PyMem_Del(*iov);
8089 for (j = 0; j < i; j++) {
8090 PyBuffer_Release(&(*buf)[j]);
8091 }
8092 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008093 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008094}
8095
8096static void
8097iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8098{
8099 int i;
8100 PyMem_Del(iov);
8101 for (i = 0; i < cnt; i++) {
8102 PyBuffer_Release(&buf[i]);
8103 }
8104 PyMem_Del(buf);
8105}
8106#endif
8107
Larry Hastings2f936352014-08-05 14:04:04 +10008108
Ross Lagerwall7807c352011-03-17 20:20:30 +02008109#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008110/*[clinic input]
8111os.readv -> Py_ssize_t
8112
8113 fd: int
8114 buffers: object
8115 /
8116
8117Read from a file descriptor fd into an iterable of buffers.
8118
8119The buffers should be mutable buffers accepting bytes.
8120readv will transfer data into each buffer until it is full
8121and then move on to the next buffer in the sequence to hold
8122the rest of the data.
8123
8124readv returns the total number of bytes read,
8125which may be less than the total capacity of all the buffers.
8126[clinic start generated code]*/
8127
Larry Hastings2f936352014-08-05 14:04:04 +10008128static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008129os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8130/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008131{
8132 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008134 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008135 struct iovec *iov;
8136 Py_buffer *buf;
8137
Larry Hastings2f936352014-08-05 14:04:04 +10008138 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139 PyErr_SetString(PyExc_TypeError,
8140 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008141 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008142 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008143
Larry Hastings2f936352014-08-05 14:04:04 +10008144 cnt = PySequence_Size(buffers);
8145
8146 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8147 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008148
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008149 do {
8150 Py_BEGIN_ALLOW_THREADS
8151 n = readv(fd, iov, cnt);
8152 Py_END_ALLOW_THREADS
8153 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008154
8155 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008156 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008157 if (!async_err)
8158 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008159 return -1;
8160 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008161
Larry Hastings2f936352014-08-05 14:04:04 +10008162 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008163}
Larry Hastings2f936352014-08-05 14:04:04 +10008164#endif /* HAVE_READV */
8165
Ross Lagerwall7807c352011-03-17 20:20:30 +02008166
8167#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008168/*[clinic input]
8169# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8170os.pread
8171
8172 fd: int
8173 length: int
8174 offset: Py_off_t
8175 /
8176
8177Read a number of bytes from a file descriptor starting at a particular offset.
8178
8179Read length bytes from file descriptor fd, starting at offset bytes from
8180the beginning of the file. The file offset remains unchanged.
8181[clinic start generated code]*/
8182
Larry Hastings2f936352014-08-05 14:04:04 +10008183static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008184os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8185/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008186{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008187 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008188 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190
Larry Hastings2f936352014-08-05 14:04:04 +10008191 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192 errno = EINVAL;
8193 return posix_error();
8194 }
Larry Hastings2f936352014-08-05 14:04:04 +10008195 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008196 if (buffer == NULL)
8197 return NULL;
8198 if (!_PyVerify_fd(fd)) {
8199 Py_DECREF(buffer);
8200 return posix_error();
8201 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008202
8203 do {
8204 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008205 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008206 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008207 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008208 Py_END_ALLOW_THREADS
8209 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8210
Ross Lagerwall7807c352011-03-17 20:20:30 +02008211 if (n < 0) {
8212 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008213 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008214 }
Larry Hastings2f936352014-08-05 14:04:04 +10008215 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216 _PyBytes_Resize(&buffer, n);
8217 return buffer;
8218}
Larry Hastings2f936352014-08-05 14:04:04 +10008219#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008220
Larry Hastings2f936352014-08-05 14:04:04 +10008221
8222/*[clinic input]
8223os.write -> Py_ssize_t
8224
8225 fd: int
8226 data: Py_buffer
8227 /
8228
8229Write a bytes object to a file descriptor.
8230[clinic start generated code]*/
8231
Larry Hastings2f936352014-08-05 14:04:04 +10008232static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008233os_write_impl(PyObject *module, int fd, Py_buffer *data)
8234/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008235{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008236 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008237}
8238
8239#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008240PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008241"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008242sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008243 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008244Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245
Larry Hastings2f936352014-08-05 14:04:04 +10008246/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247static PyObject *
8248posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8249{
8250 int in, out;
8251 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008252 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008253 off_t offset;
8254
8255#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8256#ifndef __APPLE__
8257 Py_ssize_t len;
8258#endif
8259 PyObject *headers = NULL, *trailers = NULL;
8260 Py_buffer *hbuf, *tbuf;
8261 off_t sbytes;
8262 struct sf_hdtr sf;
8263 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008264 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008265 static char *keywords[] = {"out", "in",
8266 "offset", "count",
8267 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008268
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008269 sf.headers = NULL;
8270 sf.trailers = NULL;
8271
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272#ifdef __APPLE__
8273 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008274 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008275#else
8276 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008277 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008278#endif
8279 &headers, &trailers, &flags))
8280 return NULL;
8281 if (headers != NULL) {
8282 if (!PySequence_Check(headers)) {
8283 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008284 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008285 return NULL;
8286 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008287 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008288 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008289 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008290 (i = iov_setup(&(sf.headers), &hbuf,
8291 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008292 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008293#ifdef __APPLE__
8294 sbytes += i;
8295#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008296 }
8297 }
8298 if (trailers != NULL) {
8299 if (!PySequence_Check(trailers)) {
8300 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008301 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008302 return NULL;
8303 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008304 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008306 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008307 (i = iov_setup(&(sf.trailers), &tbuf,
8308 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008309 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008310#ifdef __APPLE__
8311 sbytes += i;
8312#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008313 }
8314 }
8315
Steve Dower8fc89802015-04-12 00:26:27 -04008316 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008317 do {
8318 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008319#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008320 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 Py_END_ALLOW_THREADS
8325 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008326 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008327
8328 if (sf.headers != NULL)
8329 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8330 if (sf.trailers != NULL)
8331 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8332
8333 if (ret < 0) {
8334 if ((errno == EAGAIN) || (errno == EBUSY)) {
8335 if (sbytes != 0) {
8336 // some data has been sent
8337 goto done;
8338 }
8339 else {
8340 // no data has been sent; upper application is supposed
8341 // to retry on EAGAIN or EBUSY
8342 return posix_error();
8343 }
8344 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008345 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008346 }
8347 goto done;
8348
8349done:
8350 #if !defined(HAVE_LARGEFILE_SUPPORT)
8351 return Py_BuildValue("l", sbytes);
8352 #else
8353 return Py_BuildValue("L", sbytes);
8354 #endif
8355
8356#else
8357 Py_ssize_t count;
8358 PyObject *offobj;
8359 static char *keywords[] = {"out", "in",
8360 "offset", "count", NULL};
8361 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8362 keywords, &out, &in, &offobj, &count))
8363 return NULL;
8364#ifdef linux
8365 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008366 do {
8367 Py_BEGIN_ALLOW_THREADS
8368 ret = sendfile(out, in, NULL, count);
8369 Py_END_ALLOW_THREADS
8370 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008371 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008372 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008373 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008374 }
8375#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008376 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008377 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008378
8379 do {
8380 Py_BEGIN_ALLOW_THREADS
8381 ret = sendfile(out, in, &offset, count);
8382 Py_END_ALLOW_THREADS
8383 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008384 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008385 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 return Py_BuildValue("n", ret);
8387#endif
8388}
Larry Hastings2f936352014-08-05 14:04:04 +10008389#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008390
Larry Hastings2f936352014-08-05 14:04:04 +10008391
8392/*[clinic input]
8393os.fstat
8394
8395 fd : int
8396
8397Perform a stat system call on the given file descriptor.
8398
8399Like stat(), but for an open file descriptor.
8400Equivalent to os.stat(fd).
8401[clinic start generated code]*/
8402
Larry Hastings2f936352014-08-05 14:04:04 +10008403static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008404os_fstat_impl(PyObject *module, int fd)
8405/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008406{
Victor Stinner8c62be82010-05-06 00:08:46 +00008407 STRUCT_STAT st;
8408 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008409 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008410
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 do {
8412 Py_BEGIN_ALLOW_THREADS
8413 res = FSTAT(fd, &st);
8414 Py_END_ALLOW_THREADS
8415 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008416 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008417#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008418 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008419#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008420 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008421#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008422 }
Tim Peters5aa91602002-01-30 05:46:57 +00008423
Victor Stinner4195b5c2012-02-08 23:03:19 +01008424 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008425}
8426
Larry Hastings2f936352014-08-05 14:04:04 +10008427
8428/*[clinic input]
8429os.isatty -> bool
8430 fd: int
8431 /
8432
8433Return True if the fd is connected to a terminal.
8434
8435Return True if the file descriptor is an open file descriptor
8436connected to the slave end of a terminal.
8437[clinic start generated code]*/
8438
Larry Hastings2f936352014-08-05 14:04:04 +10008439static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008440os_isatty_impl(PyObject *module, int fd)
8441/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008442{
Steve Dower8fc89802015-04-12 00:26:27 -04008443 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008444 if (!_PyVerify_fd(fd))
8445 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008446 _Py_BEGIN_SUPPRESS_IPH
8447 return_value = isatty(fd);
8448 _Py_END_SUPPRESS_IPH
8449 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008450}
8451
8452
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008453#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008454/*[clinic input]
8455os.pipe
8456
8457Create a pipe.
8458
8459Returns a tuple of two file descriptors:
8460 (read_fd, write_fd)
8461[clinic start generated code]*/
8462
Larry Hastings2f936352014-08-05 14:04:04 +10008463static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008464os_pipe_impl(PyObject *module)
8465/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008466{
Victor Stinner8c62be82010-05-06 00:08:46 +00008467 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008468#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008470 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008471 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008472#else
8473 int res;
8474#endif
8475
8476#ifdef MS_WINDOWS
8477 attr.nLength = sizeof(attr);
8478 attr.lpSecurityDescriptor = NULL;
8479 attr.bInheritHandle = FALSE;
8480
8481 Py_BEGIN_ALLOW_THREADS
8482 ok = CreatePipe(&read, &write, &attr, 0);
8483 if (ok) {
8484 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8485 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8486 if (fds[0] == -1 || fds[1] == -1) {
8487 CloseHandle(read);
8488 CloseHandle(write);
8489 ok = 0;
8490 }
8491 }
8492 Py_END_ALLOW_THREADS
8493
Victor Stinner8c62be82010-05-06 00:08:46 +00008494 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008495 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008496#else
8497
8498#ifdef HAVE_PIPE2
8499 Py_BEGIN_ALLOW_THREADS
8500 res = pipe2(fds, O_CLOEXEC);
8501 Py_END_ALLOW_THREADS
8502
8503 if (res != 0 && errno == ENOSYS)
8504 {
8505#endif
8506 Py_BEGIN_ALLOW_THREADS
8507 res = pipe(fds);
8508 Py_END_ALLOW_THREADS
8509
8510 if (res == 0) {
8511 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8512 close(fds[0]);
8513 close(fds[1]);
8514 return NULL;
8515 }
8516 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8517 close(fds[0]);
8518 close(fds[1]);
8519 return NULL;
8520 }
8521 }
8522#ifdef HAVE_PIPE2
8523 }
8524#endif
8525
8526 if (res != 0)
8527 return PyErr_SetFromErrno(PyExc_OSError);
8528#endif /* !MS_WINDOWS */
8529 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008530}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008531#endif /* HAVE_PIPE */
8532
Larry Hastings2f936352014-08-05 14:04:04 +10008533
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008534#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008535/*[clinic input]
8536os.pipe2
8537
8538 flags: int
8539 /
8540
8541Create a pipe with flags set atomically.
8542
8543Returns a tuple of two file descriptors:
8544 (read_fd, write_fd)
8545
8546flags can be constructed by ORing together one or more of these values:
8547O_NONBLOCK, O_CLOEXEC.
8548[clinic start generated code]*/
8549
Larry Hastings2f936352014-08-05 14:04:04 +10008550static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008551os_pipe2_impl(PyObject *module, int flags)
8552/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008553{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008554 int fds[2];
8555 int res;
8556
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008557 res = pipe2(fds, flags);
8558 if (res != 0)
8559 return posix_error();
8560 return Py_BuildValue("(ii)", fds[0], fds[1]);
8561}
8562#endif /* HAVE_PIPE2 */
8563
Larry Hastings2f936352014-08-05 14:04:04 +10008564
Ross Lagerwall7807c352011-03-17 20:20:30 +02008565#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008566/*[clinic input]
8567os.writev -> Py_ssize_t
8568 fd: int
8569 buffers: object
8570 /
8571
8572Iterate over buffers, and write the contents of each to a file descriptor.
8573
8574Returns the total number of bytes written.
8575buffers must be a sequence of bytes-like objects.
8576[clinic start generated code]*/
8577
Larry Hastings2f936352014-08-05 14:04:04 +10008578static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008579os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8580/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008581{
8582 int cnt;
8583 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008584 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008585 struct iovec *iov;
8586 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008587
8588 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008589 PyErr_SetString(PyExc_TypeError,
8590 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008591 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008592 }
Larry Hastings2f936352014-08-05 14:04:04 +10008593 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594
Larry Hastings2f936352014-08-05 14:04:04 +10008595 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8596 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597 }
8598
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008599 do {
8600 Py_BEGIN_ALLOW_THREADS
8601 result = writev(fd, iov, cnt);
8602 Py_END_ALLOW_THREADS
8603 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008604
8605 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008606 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008607 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008608
Georg Brandl306336b2012-06-24 12:55:33 +02008609 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008610}
Larry Hastings2f936352014-08-05 14:04:04 +10008611#endif /* HAVE_WRITEV */
8612
8613
8614#ifdef HAVE_PWRITE
8615/*[clinic input]
8616os.pwrite -> Py_ssize_t
8617
8618 fd: int
8619 buffer: Py_buffer
8620 offset: Py_off_t
8621 /
8622
8623Write bytes to a file descriptor starting at a particular offset.
8624
8625Write buffer to fd, starting at offset bytes from the beginning of
8626the file. Returns the number of bytes writte. Does not change the
8627current file offset.
8628[clinic start generated code]*/
8629
Larry Hastings2f936352014-08-05 14:04:04 +10008630static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008631os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8632/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008633{
8634 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008635 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008636
8637 if (!_PyVerify_fd(fd)) {
8638 posix_error();
8639 return -1;
8640 }
8641
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008642 do {
8643 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008644 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008646 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008647 Py_END_ALLOW_THREADS
8648 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008649
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008650 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008651 posix_error();
8652 return size;
8653}
8654#endif /* HAVE_PWRITE */
8655
8656
8657#ifdef HAVE_MKFIFO
8658/*[clinic input]
8659os.mkfifo
8660
8661 path: path_t
8662 mode: int=0o666
8663 *
8664 dir_fd: dir_fd(requires='mkfifoat')=None
8665
8666Create a "fifo" (a POSIX named pipe).
8667
8668If dir_fd is not None, it should be a file descriptor open to a directory,
8669 and path should be relative; path will then be relative to that directory.
8670dir_fd may not be implemented on your platform.
8671 If it is unavailable, using it will raise a NotImplementedError.
8672[clinic start generated code]*/
8673
Larry Hastings2f936352014-08-05 14:04:04 +10008674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008675os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8676/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008677{
8678 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008679 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008680
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008681 do {
8682 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008683#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 if (dir_fd != DEFAULT_DIR_FD)
8685 result = mkfifoat(dir_fd, path->narrow, mode);
8686 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008687#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008688 result = mkfifo(path->narrow, mode);
8689 Py_END_ALLOW_THREADS
8690 } while (result != 0 && errno == EINTR &&
8691 !(async_err = PyErr_CheckSignals()));
8692 if (result != 0)
8693 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008694
8695 Py_RETURN_NONE;
8696}
8697#endif /* HAVE_MKFIFO */
8698
8699
8700#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8701/*[clinic input]
8702os.mknod
8703
8704 path: path_t
8705 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008706 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008707 *
8708 dir_fd: dir_fd(requires='mknodat')=None
8709
8710Create a node in the file system.
8711
8712Create a node in the file system (file, device special file or named pipe)
8713at path. mode specifies both the permissions to use and the
8714type of node to be created, being combined (bitwise OR) with one of
8715S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8716device defines the newly created device special file (probably using
8717os.makedev()). Otherwise device is ignored.
8718
8719If dir_fd is not None, it should be a file descriptor open to a directory,
8720 and path should be relative; path will then be relative to that directory.
8721dir_fd may not be implemented on your platform.
8722 If it is unavailable, using it will raise a NotImplementedError.
8723[clinic start generated code]*/
8724
Larry Hastings2f936352014-08-05 14:04:04 +10008725static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008726os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008727 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008728/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008729{
8730 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008731 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008732
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008733 do {
8734 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008735#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008736 if (dir_fd != DEFAULT_DIR_FD)
8737 result = mknodat(dir_fd, path->narrow, mode, device);
8738 else
Larry Hastings2f936352014-08-05 14:04:04 +10008739#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008740 result = mknod(path->narrow, mode, device);
8741 Py_END_ALLOW_THREADS
8742 } while (result != 0 && errno == EINTR &&
8743 !(async_err = PyErr_CheckSignals()));
8744 if (result != 0)
8745 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008746
8747 Py_RETURN_NONE;
8748}
8749#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8750
8751
8752#ifdef HAVE_DEVICE_MACROS
8753/*[clinic input]
8754os.major -> unsigned_int
8755
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008756 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008757 /
8758
8759Extracts a device major number from a raw device number.
8760[clinic start generated code]*/
8761
Larry Hastings2f936352014-08-05 14:04:04 +10008762static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008763os_major_impl(PyObject *module, dev_t device)
8764/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008765{
8766 return major(device);
8767}
8768
8769
8770/*[clinic input]
8771os.minor -> unsigned_int
8772
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008773 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008774 /
8775
8776Extracts a device minor number from a raw device number.
8777[clinic start generated code]*/
8778
Larry Hastings2f936352014-08-05 14:04:04 +10008779static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008780os_minor_impl(PyObject *module, dev_t device)
8781/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008782{
8783 return minor(device);
8784}
8785
8786
8787/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008788os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008789
8790 major: int
8791 minor: int
8792 /
8793
8794Composes a raw device number from the major and minor device numbers.
8795[clinic start generated code]*/
8796
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008797static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008798os_makedev_impl(PyObject *module, int major, int minor)
8799/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008800{
8801 return makedev(major, minor);
8802}
8803#endif /* HAVE_DEVICE_MACROS */
8804
8805
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008806#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008807/*[clinic input]
8808os.ftruncate
8809
8810 fd: int
8811 length: Py_off_t
8812 /
8813
8814Truncate a file, specified by file descriptor, to a specific length.
8815[clinic start generated code]*/
8816
Larry Hastings2f936352014-08-05 14:04:04 +10008817static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008818os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8819/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008820{
8821 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008822 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008823
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008824 if (!_PyVerify_fd(fd))
8825 return posix_error();
8826
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008827 do {
8828 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008829 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008830#ifdef MS_WINDOWS
8831 result = _chsize_s(fd, length);
8832#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008833 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008834#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008835 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008836 Py_END_ALLOW_THREADS
8837 } while (result != 0 && errno == EINTR &&
8838 !(async_err = PyErr_CheckSignals()));
8839 if (result != 0)
8840 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008841 Py_RETURN_NONE;
8842}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008843#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008844
8845
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008846#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008847/*[clinic input]
8848os.truncate
8849 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8850 length: Py_off_t
8851
8852Truncate a file, specified by path, to a specific length.
8853
8854On some platforms, path may also be specified as an open file descriptor.
8855 If this functionality is unavailable, using it raises an exception.
8856[clinic start generated code]*/
8857
Larry Hastings2f936352014-08-05 14:04:04 +10008858static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008859os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8860/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008861{
8862 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008863#ifdef MS_WINDOWS
8864 int fd;
8865#endif
8866
8867 if (path->fd != -1)
8868 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008869
8870 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008871 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008872#ifdef MS_WINDOWS
8873 if (path->wide)
8874 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008875 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008876 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008877 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008878 result = -1;
8879 else {
8880 result = _chsize_s(fd, length);
8881 close(fd);
8882 if (result < 0)
8883 errno = result;
8884 }
8885#else
8886 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008887#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008888 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008889 Py_END_ALLOW_THREADS
8890 if (result < 0)
8891 return path_error(path);
8892
8893 Py_RETURN_NONE;
8894}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008895#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008896
Ross Lagerwall7807c352011-03-17 20:20:30 +02008897
Victor Stinnerd6b17692014-09-30 12:20:05 +02008898/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8899 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8900 defined, which is the case in Python on AIX. AIX bug report:
8901 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8902#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8903# define POSIX_FADVISE_AIX_BUG
8904#endif
8905
Victor Stinnerec39e262014-09-30 12:35:58 +02008906
Victor Stinnerd6b17692014-09-30 12:20:05 +02008907#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008908/*[clinic input]
8909os.posix_fallocate
8910
8911 fd: int
8912 offset: Py_off_t
8913 length: Py_off_t
8914 /
8915
8916Ensure a file has allocated at least a particular number of bytes on disk.
8917
8918Ensure that the file specified by fd encompasses a range of bytes
8919starting at offset bytes from the beginning and continuing for length bytes.
8920[clinic start generated code]*/
8921
Larry Hastings2f936352014-08-05 14:04:04 +10008922static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008923os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008924 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008925/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008926{
8927 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008928 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008929
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008930 do {
8931 Py_BEGIN_ALLOW_THREADS
8932 result = posix_fallocate(fd, offset, length);
8933 Py_END_ALLOW_THREADS
8934 } while (result != 0 && errno == EINTR &&
8935 !(async_err = PyErr_CheckSignals()));
8936 if (result != 0)
8937 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008938 Py_RETURN_NONE;
8939}
Victor Stinnerec39e262014-09-30 12:35:58 +02008940#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008941
Ross Lagerwall7807c352011-03-17 20:20:30 +02008942
Victor Stinnerd6b17692014-09-30 12:20:05 +02008943#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008944/*[clinic input]
8945os.posix_fadvise
8946
8947 fd: int
8948 offset: Py_off_t
8949 length: Py_off_t
8950 advice: int
8951 /
8952
8953Announce an intention to access data in a specific pattern.
8954
8955Announce an intention to access data in a specific pattern, thus allowing
8956the kernel to make optimizations.
8957The advice applies to the region of the file specified by fd starting at
8958offset and continuing for length bytes.
8959advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8960POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8961POSIX_FADV_DONTNEED.
8962[clinic start generated code]*/
8963
Larry Hastings2f936352014-08-05 14:04:04 +10008964static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008965os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008966 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008967/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008968{
8969 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008970 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008971
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008972 do {
8973 Py_BEGIN_ALLOW_THREADS
8974 result = posix_fadvise(fd, offset, length, advice);
8975 Py_END_ALLOW_THREADS
8976 } while (result != 0 && errno == EINTR &&
8977 !(async_err = PyErr_CheckSignals()));
8978 if (result != 0)
8979 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008980 Py_RETURN_NONE;
8981}
Victor Stinnerec39e262014-09-30 12:35:58 +02008982#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008983
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008984#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008985
Fred Drake762e2061999-08-26 17:23:54 +00008986/* Save putenv() parameters as values here, so we can collect them when they
8987 * get re-set with another call for the same key. */
8988static PyObject *posix_putenv_garbage;
8989
Larry Hastings2f936352014-08-05 14:04:04 +10008990static void
8991posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008992{
Larry Hastings2f936352014-08-05 14:04:04 +10008993 /* Install the first arg and newstr in posix_putenv_garbage;
8994 * this will cause previous value to be collected. This has to
8995 * happen after the real putenv() call because the old value
8996 * was still accessible until then. */
8997 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8998 /* really not much we can do; just leak */
8999 PyErr_Clear();
9000 else
9001 Py_DECREF(value);
9002}
9003
9004
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009005#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009006/*[clinic input]
9007os.putenv
9008
9009 name: unicode
9010 value: unicode
9011 /
9012
9013Change or add an environment variable.
9014[clinic start generated code]*/
9015
Larry Hastings2f936352014-08-05 14:04:04 +10009016static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009017os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9018/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009019{
9020 wchar_t *env;
9021
9022 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9023 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009024 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009025 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009026 }
Larry Hastings2f936352014-08-05 14:04:04 +10009027 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009028 PyErr_Format(PyExc_ValueError,
9029 "the environment variable is longer than %u characters",
9030 _MAX_ENV);
9031 goto error;
9032 }
9033
Larry Hastings2f936352014-08-05 14:04:04 +10009034 env = PyUnicode_AsUnicode(unicode);
9035 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009036 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009037 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009039 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009040 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009041
Larry Hastings2f936352014-08-05 14:04:04 +10009042 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009043 Py_RETURN_NONE;
9044
9045error:
Larry Hastings2f936352014-08-05 14:04:04 +10009046 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009047 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009048}
Larry Hastings2f936352014-08-05 14:04:04 +10009049#else /* MS_WINDOWS */
9050/*[clinic input]
9051os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009052
Larry Hastings2f936352014-08-05 14:04:04 +10009053 name: FSConverter
9054 value: FSConverter
9055 /
9056
9057Change or add an environment variable.
9058[clinic start generated code]*/
9059
Larry Hastings2f936352014-08-05 14:04:04 +10009060static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009061os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9062/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009063{
9064 PyObject *bytes = NULL;
9065 char *env;
9066 char *name_string = PyBytes_AsString(name);
9067 char *value_string = PyBytes_AsString(value);
9068
9069 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9070 if (bytes == NULL) {
9071 PyErr_NoMemory();
9072 return NULL;
9073 }
9074
9075 env = PyBytes_AS_STRING(bytes);
9076 if (putenv(env)) {
9077 Py_DECREF(bytes);
9078 return posix_error();
9079 }
9080
9081 posix_putenv_garbage_setitem(name, bytes);
9082 Py_RETURN_NONE;
9083}
9084#endif /* MS_WINDOWS */
9085#endif /* HAVE_PUTENV */
9086
9087
9088#ifdef HAVE_UNSETENV
9089/*[clinic input]
9090os.unsetenv
9091 name: FSConverter
9092 /
9093
9094Delete an environment variable.
9095[clinic start generated code]*/
9096
Larry Hastings2f936352014-08-05 14:04:04 +10009097static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009098os_unsetenv_impl(PyObject *module, PyObject *name)
9099/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009100{
Victor Stinner984890f2011-11-24 13:53:38 +01009101#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009102 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009103#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009104
Victor Stinner984890f2011-11-24 13:53:38 +01009105#ifdef HAVE_BROKEN_UNSETENV
9106 unsetenv(PyBytes_AS_STRING(name));
9107#else
Victor Stinner65170952011-11-22 22:16:17 +01009108 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009109 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009110 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009111#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009112
Victor Stinner8c62be82010-05-06 00:08:46 +00009113 /* Remove the key from posix_putenv_garbage;
9114 * this will cause it to be collected. This has to
9115 * happen after the real unsetenv() call because the
9116 * old value was still accessible until then.
9117 */
Victor Stinner65170952011-11-22 22:16:17 +01009118 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009119 /* really not much we can do; just leak */
9120 PyErr_Clear();
9121 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009122 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009123}
Larry Hastings2f936352014-08-05 14:04:04 +10009124#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009125
Larry Hastings2f936352014-08-05 14:04:04 +10009126
9127/*[clinic input]
9128os.strerror
9129
9130 code: int
9131 /
9132
9133Translate an error code to a message string.
9134[clinic start generated code]*/
9135
Larry Hastings2f936352014-08-05 14:04:04 +10009136static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009137os_strerror_impl(PyObject *module, int code)
9138/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009139{
9140 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009141 if (message == NULL) {
9142 PyErr_SetString(PyExc_ValueError,
9143 "strerror() argument out of range");
9144 return NULL;
9145 }
Victor Stinner1b579672011-12-17 05:47:23 +01009146 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009147}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009148
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009149
Guido van Rossumc9641791998-08-04 15:26:23 +00009150#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009151#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009152/*[clinic input]
9153os.WCOREDUMP -> bool
9154
9155 status: int
9156 /
9157
9158Return True if the process returning status was dumped to a core file.
9159[clinic start generated code]*/
9160
Larry Hastings2f936352014-08-05 14:04:04 +10009161static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009162os_WCOREDUMP_impl(PyObject *module, int status)
9163/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009164{
9165 WAIT_TYPE wait_status;
9166 WAIT_STATUS_INT(wait_status) = status;
9167 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009168}
9169#endif /* WCOREDUMP */
9170
Larry Hastings2f936352014-08-05 14:04:04 +10009171
Fred Drake106c1a02002-04-23 15:58:02 +00009172#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009173/*[clinic input]
9174os.WIFCONTINUED -> bool
9175
9176 status: int
9177
9178Return True if a particular process was continued from a job control stop.
9179
9180Return True if the process returning status was continued from a
9181job control stop.
9182[clinic start generated code]*/
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009185os_WIFCONTINUED_impl(PyObject *module, int status)
9186/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009187{
9188 WAIT_TYPE wait_status;
9189 WAIT_STATUS_INT(wait_status) = status;
9190 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009191}
9192#endif /* WIFCONTINUED */
9193
Larry Hastings2f936352014-08-05 14:04:04 +10009194
Guido van Rossumc9641791998-08-04 15:26:23 +00009195#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009196/*[clinic input]
9197os.WIFSTOPPED -> bool
9198
9199 status: int
9200
9201Return True if the process returning status was stopped.
9202[clinic start generated code]*/
9203
Larry Hastings2f936352014-08-05 14:04:04 +10009204static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009205os_WIFSTOPPED_impl(PyObject *module, int status)
9206/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009207{
9208 WAIT_TYPE wait_status;
9209 WAIT_STATUS_INT(wait_status) = status;
9210 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009211}
9212#endif /* WIFSTOPPED */
9213
Larry Hastings2f936352014-08-05 14:04:04 +10009214
Guido van Rossumc9641791998-08-04 15:26:23 +00009215#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009216/*[clinic input]
9217os.WIFSIGNALED -> bool
9218
9219 status: int
9220
9221Return True if the process returning status was terminated by a signal.
9222[clinic start generated code]*/
9223
Larry Hastings2f936352014-08-05 14:04:04 +10009224static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009225os_WIFSIGNALED_impl(PyObject *module, int status)
9226/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009227{
9228 WAIT_TYPE wait_status;
9229 WAIT_STATUS_INT(wait_status) = status;
9230 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009231}
9232#endif /* WIFSIGNALED */
9233
Larry Hastings2f936352014-08-05 14:04:04 +10009234
Guido van Rossumc9641791998-08-04 15:26:23 +00009235#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009236/*[clinic input]
9237os.WIFEXITED -> bool
9238
9239 status: int
9240
9241Return True if the process returning status exited via the exit() system call.
9242[clinic start generated code]*/
9243
Larry Hastings2f936352014-08-05 14:04:04 +10009244static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009245os_WIFEXITED_impl(PyObject *module, int status)
9246/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009247{
9248 WAIT_TYPE wait_status;
9249 WAIT_STATUS_INT(wait_status) = status;
9250 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009251}
9252#endif /* WIFEXITED */
9253
Larry Hastings2f936352014-08-05 14:04:04 +10009254
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009255#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009256/*[clinic input]
9257os.WEXITSTATUS -> int
9258
9259 status: int
9260
9261Return the process return code from status.
9262[clinic start generated code]*/
9263
Larry Hastings2f936352014-08-05 14:04:04 +10009264static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009265os_WEXITSTATUS_impl(PyObject *module, int status)
9266/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009267{
9268 WAIT_TYPE wait_status;
9269 WAIT_STATUS_INT(wait_status) = status;
9270 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009271}
9272#endif /* WEXITSTATUS */
9273
Larry Hastings2f936352014-08-05 14:04:04 +10009274
Guido van Rossumc9641791998-08-04 15:26:23 +00009275#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009276/*[clinic input]
9277os.WTERMSIG -> int
9278
9279 status: int
9280
9281Return the signal that terminated the process that provided the status value.
9282[clinic start generated code]*/
9283
Larry Hastings2f936352014-08-05 14:04:04 +10009284static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009285os_WTERMSIG_impl(PyObject *module, int status)
9286/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009287{
9288 WAIT_TYPE wait_status;
9289 WAIT_STATUS_INT(wait_status) = status;
9290 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009291}
9292#endif /* WTERMSIG */
9293
Larry Hastings2f936352014-08-05 14:04:04 +10009294
Guido van Rossumc9641791998-08-04 15:26:23 +00009295#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009296/*[clinic input]
9297os.WSTOPSIG -> int
9298
9299 status: int
9300
9301Return the signal that stopped the process that provided the status value.
9302[clinic start generated code]*/
9303
Larry Hastings2f936352014-08-05 14:04:04 +10009304static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009305os_WSTOPSIG_impl(PyObject *module, int status)
9306/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009307{
9308 WAIT_TYPE wait_status;
9309 WAIT_STATUS_INT(wait_status) = status;
9310 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009311}
9312#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009313#endif /* HAVE_SYS_WAIT_H */
9314
9315
Thomas Wouters477c8d52006-05-27 19:21:47 +00009316#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009317#ifdef _SCO_DS
9318/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9319 needed definitions in sys/statvfs.h */
9320#define _SVID3
9321#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009322#include <sys/statvfs.h>
9323
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009324static PyObject*
9325_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009326 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9327 if (v == NULL)
9328 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009329
9330#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009331 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9332 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9333 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9334 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9335 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9336 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9337 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9338 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9339 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9340 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009341#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009342 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9343 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9344 PyStructSequence_SET_ITEM(v, 2,
9345 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9346 PyStructSequence_SET_ITEM(v, 3,
9347 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9348 PyStructSequence_SET_ITEM(v, 4,
9349 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9350 PyStructSequence_SET_ITEM(v, 5,
9351 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9352 PyStructSequence_SET_ITEM(v, 6,
9353 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9354 PyStructSequence_SET_ITEM(v, 7,
9355 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9356 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9357 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009358#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009359 if (PyErr_Occurred()) {
9360 Py_DECREF(v);
9361 return NULL;
9362 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009363
Victor Stinner8c62be82010-05-06 00:08:46 +00009364 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009365}
9366
Larry Hastings2f936352014-08-05 14:04:04 +10009367
9368/*[clinic input]
9369os.fstatvfs
9370 fd: int
9371 /
9372
9373Perform an fstatvfs system call on the given fd.
9374
9375Equivalent to statvfs(fd).
9376[clinic start generated code]*/
9377
Larry Hastings2f936352014-08-05 14:04:04 +10009378static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009379os_fstatvfs_impl(PyObject *module, int fd)
9380/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009381{
9382 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009383 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009384 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009385
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009386 do {
9387 Py_BEGIN_ALLOW_THREADS
9388 result = fstatvfs(fd, &st);
9389 Py_END_ALLOW_THREADS
9390 } while (result != 0 && errno == EINTR &&
9391 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009392 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009393 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009394
Victor Stinner8c62be82010-05-06 00:08:46 +00009395 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009396}
Larry Hastings2f936352014-08-05 14:04:04 +10009397#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009398
9399
Thomas Wouters477c8d52006-05-27 19:21:47 +00009400#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009401#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009402/*[clinic input]
9403os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009404
Larry Hastings2f936352014-08-05 14:04:04 +10009405 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9406
9407Perform a statvfs system call on the given path.
9408
9409path may always be specified as a string.
9410On some platforms, path may also be specified as an open file descriptor.
9411 If this functionality is unavailable, using it raises an exception.
9412[clinic start generated code]*/
9413
Larry Hastings2f936352014-08-05 14:04:04 +10009414static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009415os_statvfs_impl(PyObject *module, path_t *path)
9416/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009417{
9418 int result;
9419 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009420
9421 Py_BEGIN_ALLOW_THREADS
9422#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009423 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009424#ifdef __APPLE__
9425 /* handle weak-linking on Mac OS X 10.3 */
9426 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009427 fd_specified("statvfs", path->fd);
9428 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009429 }
9430#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009431 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009432 }
9433 else
9434#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009435 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009436 Py_END_ALLOW_THREADS
9437
9438 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009439 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009440 }
9441
Larry Hastings2f936352014-08-05 14:04:04 +10009442 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009443}
Larry Hastings2f936352014-08-05 14:04:04 +10009444#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9445
Guido van Rossum94f6f721999-01-06 18:42:14 +00009446
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009447#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009448/*[clinic input]
9449os._getdiskusage
9450
9451 path: Py_UNICODE
9452
9453Return disk usage statistics about the given path as a (total, free) tuple.
9454[clinic start generated code]*/
9455
Larry Hastings2f936352014-08-05 14:04:04 +10009456static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009457os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9458/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009459{
9460 BOOL retval;
9461 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009462
9463 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009464 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009465 Py_END_ALLOW_THREADS
9466 if (retval == 0)
9467 return PyErr_SetFromWindowsErr(0);
9468
9469 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9470}
Larry Hastings2f936352014-08-05 14:04:04 +10009471#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009472
9473
Fred Drakec9680921999-12-13 16:37:25 +00009474/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9475 * It maps strings representing configuration variable names to
9476 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009477 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009478 * rarely-used constants. There are three separate tables that use
9479 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009480 *
9481 * This code is always included, even if none of the interfaces that
9482 * need it are included. The #if hackery needed to avoid it would be
9483 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009484 */
9485struct constdef {
9486 char *name;
9487 long value;
9488};
9489
Fred Drake12c6e2d1999-12-14 21:25:03 +00009490static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009491conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009492 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009493{
Christian Heimes217cfd12007-12-02 14:31:20 +00009494 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009495 *valuep = PyLong_AS_LONG(arg);
9496 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009497 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009498 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009499 /* look up the value in the table using a binary search */
9500 size_t lo = 0;
9501 size_t mid;
9502 size_t hi = tablesize;
9503 int cmp;
9504 const char *confname;
9505 if (!PyUnicode_Check(arg)) {
9506 PyErr_SetString(PyExc_TypeError,
9507 "configuration names must be strings or integers");
9508 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009510 confname = _PyUnicode_AsString(arg);
9511 if (confname == NULL)
9512 return 0;
9513 while (lo < hi) {
9514 mid = (lo + hi) / 2;
9515 cmp = strcmp(confname, table[mid].name);
9516 if (cmp < 0)
9517 hi = mid;
9518 else if (cmp > 0)
9519 lo = mid + 1;
9520 else {
9521 *valuep = table[mid].value;
9522 return 1;
9523 }
9524 }
9525 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9526 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009528}
9529
9530
9531#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9532static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009533#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009534 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009535#endif
9536#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009537 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009538#endif
Fred Drakec9680921999-12-13 16:37:25 +00009539#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009541#endif
9542#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009544#endif
9545#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009584#ifdef _PC_ACL_ENABLED
9585 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9586#endif
9587#ifdef _PC_MIN_HOLE_SIZE
9588 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9589#endif
9590#ifdef _PC_ALLOC_SIZE_MIN
9591 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9592#endif
9593#ifdef _PC_REC_INCR_XFER_SIZE
9594 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9595#endif
9596#ifdef _PC_REC_MAX_XFER_SIZE
9597 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9598#endif
9599#ifdef _PC_REC_MIN_XFER_SIZE
9600 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9601#endif
9602#ifdef _PC_REC_XFER_ALIGN
9603 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9604#endif
9605#ifdef _PC_SYMLINK_MAX
9606 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9607#endif
9608#ifdef _PC_XATTR_ENABLED
9609 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9610#endif
9611#ifdef _PC_XATTR_EXISTS
9612 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9613#endif
9614#ifdef _PC_TIMESTAMP_RESOLUTION
9615 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9616#endif
Fred Drakec9680921999-12-13 16:37:25 +00009617};
9618
Fred Drakec9680921999-12-13 16:37:25 +00009619static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009620conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009621{
9622 return conv_confname(arg, valuep, posix_constants_pathconf,
9623 sizeof(posix_constants_pathconf)
9624 / sizeof(struct constdef));
9625}
9626#endif
9627
Larry Hastings2f936352014-08-05 14:04:04 +10009628
Fred Drakec9680921999-12-13 16:37:25 +00009629#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009630/*[clinic input]
9631os.fpathconf -> long
9632
9633 fd: int
9634 name: path_confname
9635 /
9636
9637Return the configuration limit name for the file descriptor fd.
9638
9639If there is no limit, return -1.
9640[clinic start generated code]*/
9641
Larry Hastings2f936352014-08-05 14:04:04 +10009642static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009643os_fpathconf_impl(PyObject *module, int fd, int name)
9644/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009645{
9646 long limit;
9647
9648 errno = 0;
9649 limit = fpathconf(fd, name);
9650 if (limit == -1 && errno != 0)
9651 posix_error();
9652
9653 return limit;
9654}
9655#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009656
9657
9658#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009659/*[clinic input]
9660os.pathconf -> long
9661 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9662 name: path_confname
9663
9664Return the configuration limit name for the file or directory path.
9665
9666If there is no limit, return -1.
9667On some platforms, path may also be specified as an open file descriptor.
9668 If this functionality is unavailable, using it raises an exception.
9669[clinic start generated code]*/
9670
Larry Hastings2f936352014-08-05 14:04:04 +10009671static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009672os_pathconf_impl(PyObject *module, path_t *path, int name)
9673/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009674{
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009676
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009678#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009679 if (path->fd != -1)
9680 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009681 else
9682#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009683 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009684 if (limit == -1 && errno != 0) {
9685 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009686 /* could be a path or name problem */
9687 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009688 else
Larry Hastings2f936352014-08-05 14:04:04 +10009689 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 }
Larry Hastings2f936352014-08-05 14:04:04 +10009691
9692 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009693}
Larry Hastings2f936352014-08-05 14:04:04 +10009694#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009695
9696#ifdef HAVE_CONFSTR
9697static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009698#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009699 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009700#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009701#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009702 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009703#endif
9704#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009706#endif
Fred Draked86ed291999-12-15 15:34:33 +00009707#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009709#endif
9710#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009712#endif
9713#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009715#endif
9716#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
Fred Drakec9680921999-12-13 16:37:25 +00009719#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009721#endif
9722#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009724#endif
9725#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
Fred Draked86ed291999-12-15 15:34:33 +00009743#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009745#endif
Fred Drakec9680921999-12-13 16:37:25 +00009746#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
Fred Draked86ed291999-12-15 15:34:33 +00009749#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
9752#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009754#endif
9755#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
Fred Drakec9680921999-12-13 16:37:25 +00009761#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009763#endif
9764#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009766#endif
9767#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
Fred Draked86ed291999-12-15 15:34:33 +00009809#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009811#endif
9812#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009814#endif
9815#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
9818#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009820#endif
9821#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009823#endif
9824#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009826#endif
9827#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009829#endif
9830#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009832#endif
9833#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009835#endif
9836#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
9845#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
Fred Drakec9680921999-12-13 16:37:25 +00009848};
9849
9850static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009851conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009852{
9853 return conv_confname(arg, valuep, posix_constants_confstr,
9854 sizeof(posix_constants_confstr)
9855 / sizeof(struct constdef));
9856}
9857
Larry Hastings2f936352014-08-05 14:04:04 +10009858
9859/*[clinic input]
9860os.confstr
9861
9862 name: confstr_confname
9863 /
9864
9865Return a string-valued system configuration variable.
9866[clinic start generated code]*/
9867
Larry Hastings2f936352014-08-05 14:04:04 +10009868static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009869os_confstr_impl(PyObject *module, int name)
9870/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009871{
9872 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009873 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009874 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009875
Victor Stinnercb043522010-09-10 23:49:04 +00009876 errno = 0;
9877 len = confstr(name, buffer, sizeof(buffer));
9878 if (len == 0) {
9879 if (errno) {
9880 posix_error();
9881 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009882 }
9883 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009884 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009885 }
9886 }
Victor Stinnercb043522010-09-10 23:49:04 +00009887
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009888 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009889 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009890 char *buf = PyMem_Malloc(len);
9891 if (buf == NULL)
9892 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009893 len2 = confstr(name, buf, len);
9894 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009895 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009896 PyMem_Free(buf);
9897 }
9898 else
9899 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009900 return result;
9901}
Larry Hastings2f936352014-08-05 14:04:04 +10009902#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009903
9904
9905#ifdef HAVE_SYSCONF
9906static struct constdef posix_constants_sysconf[] = {
9907#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009908 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009909#endif
9910#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009911 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009912#endif
9913#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
Fred Draked86ed291999-12-15 15:34:33 +00009937#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009939#endif
9940#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009942#endif
Fred Drakec9680921999-12-13 16:37:25 +00009943#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009945#endif
Fred Drakec9680921999-12-13 16:37:25 +00009946#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009948#endif
9949#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
9952#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
Fred Draked86ed291999-12-15 15:34:33 +00009961#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009963#endif
Fred Drakec9680921999-12-13 16:37:25 +00009964#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
9967#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009969#endif
9970#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
Fred Draked86ed291999-12-15 15:34:33 +00009979#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009981#endif
Fred Drakec9680921999-12-13 16:37:25 +00009982#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
9985#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009987#endif
9988#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
Fred Draked86ed291999-12-15 15:34:33 +000010051#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010053#endif
Fred Drakec9680921999-12-13 16:37:25 +000010054#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
10057#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010059#endif
10060#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
Fred Draked86ed291999-12-15 15:34:33 +000010063#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010065#endif
Fred Drakec9680921999-12-13 16:37:25 +000010066#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
Fred Draked86ed291999-12-15 15:34:33 +000010069#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010071#endif
10072#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010074#endif
Fred Drakec9680921999-12-13 16:37:25 +000010075#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010077#endif
10078#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010080#endif
10081#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
Fred Draked86ed291999-12-15 15:34:33 +000010087#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010089#endif
Fred Drakec9680921999-12-13 16:37:25 +000010090#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
10093#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010095#endif
10096#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
Fred Draked86ed291999-12-15 15:34:33 +000010111#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010113#endif
Fred Drakec9680921999-12-13 16:37:25 +000010114#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
10117#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010119#endif
Fred Draked86ed291999-12-15 15:34:33 +000010120#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010122#endif
Fred Drakec9680921999-12-13 16:37:25 +000010123#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
10126#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010128#endif
10129#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
Fred Draked86ed291999-12-15 15:34:33 +000010150#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010152#endif
10153#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010155#endif
Fred Drakec9680921999-12-13 16:37:25 +000010156#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010158#endif
10159#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010161#endif
10162#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
Fred Draked86ed291999-12-15 15:34:33 +000010261#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010263#endif
Fred Drakec9680921999-12-13 16:37:25 +000010264#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
10267#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010269#endif
10270#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399};
10400
10401static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010402conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010403{
10404 return conv_confname(arg, valuep, posix_constants_sysconf,
10405 sizeof(posix_constants_sysconf)
10406 / sizeof(struct constdef));
10407}
10408
Larry Hastings2f936352014-08-05 14:04:04 +100010409
10410/*[clinic input]
10411os.sysconf -> long
10412 name: sysconf_confname
10413 /
10414
10415Return an integer-valued system configuration variable.
10416[clinic start generated code]*/
10417
Larry Hastings2f936352014-08-05 14:04:04 +100010418static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010419os_sysconf_impl(PyObject *module, int name)
10420/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010421{
10422 long value;
10423
10424 errno = 0;
10425 value = sysconf(name);
10426 if (value == -1 && errno != 0)
10427 posix_error();
10428 return value;
10429}
10430#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010431
10432
Fred Drakebec628d1999-12-15 18:31:10 +000010433/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010434 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010435 * the exported dictionaries that are used to publish information about the
10436 * names available on the host platform.
10437 *
10438 * Sorting the table at runtime ensures that the table is properly ordered
10439 * when used, even for platforms we're not able to test on. It also makes
10440 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010441 */
Fred Drakebec628d1999-12-15 18:31:10 +000010442
10443static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010444cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010445{
10446 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010448 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010449 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010450
10451 return strcmp(c1->name, c2->name);
10452}
10453
10454static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010455setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010456 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010457{
Fred Drakebec628d1999-12-15 18:31:10 +000010458 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010459 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010460
10461 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10462 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010463 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010464 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010465
Barry Warsaw3155db32000-04-13 15:20:40 +000010466 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010467 PyObject *o = PyLong_FromLong(table[i].value);
10468 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10469 Py_XDECREF(o);
10470 Py_DECREF(d);
10471 return -1;
10472 }
10473 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010474 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010475 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010476}
10477
Fred Drakebec628d1999-12-15 18:31:10 +000010478/* Return -1 on failure, 0 on success. */
10479static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010480setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010481{
10482#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010483 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010484 sizeof(posix_constants_pathconf)
10485 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010486 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010487 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010488#endif
10489#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010490 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010491 sizeof(posix_constants_confstr)
10492 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010493 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010494 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010495#endif
10496#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010497 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010498 sizeof(posix_constants_sysconf)
10499 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010500 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010501 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010502#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010503 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010504}
Fred Draked86ed291999-12-15 15:34:33 +000010505
10506
Larry Hastings2f936352014-08-05 14:04:04 +100010507/*[clinic input]
10508os.abort
10509
10510Abort the interpreter immediately.
10511
10512This function 'dumps core' or otherwise fails in the hardest way possible
10513on the hosting operating system. This function never returns.
10514[clinic start generated code]*/
10515
Larry Hastings2f936352014-08-05 14:04:04 +100010516static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010517os_abort_impl(PyObject *module)
10518/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010519{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010520 abort();
10521 /*NOTREACHED*/
10522 Py_FatalError("abort() called from Python code didn't abort!");
10523 return NULL;
10524}
Fred Drakebec628d1999-12-15 18:31:10 +000010525
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010526#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010527/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010528PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010529"startfile(filepath [, operation])\n\
10530\n\
10531Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010532\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010533When \"operation\" is not specified or \"open\", this acts like\n\
10534double-clicking the file in Explorer, or giving the file name as an\n\
10535argument to the DOS \"start\" command: the file is opened with whatever\n\
10536application (if any) its extension is associated.\n\
10537When another \"operation\" is given, it specifies what should be done with\n\
10538the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010539\n\
10540startfile returns as soon as the associated application is launched.\n\
10541There is no option to wait for the application to close, and no way\n\
10542to retrieve the application's exit status.\n\
10543\n\
10544The filepath is relative to the current directory. If you want to use\n\
10545an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010546the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010547
Steve Dower7d0e0c92015-01-24 08:18:24 -080010548/* Grab ShellExecute dynamically from shell32 */
10549static int has_ShellExecute = -1;
10550static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10551 LPCSTR, INT);
10552static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10553 LPCWSTR, INT);
10554static int
10555check_ShellExecute()
10556{
10557 HINSTANCE hShell32;
10558
10559 /* only recheck */
10560 if (-1 == has_ShellExecute) {
10561 Py_BEGIN_ALLOW_THREADS
10562 hShell32 = LoadLibraryW(L"SHELL32");
10563 Py_END_ALLOW_THREADS
10564 if (hShell32) {
10565 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10566 "ShellExecuteA");
10567 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10568 "ShellExecuteW");
10569 has_ShellExecute = Py_ShellExecuteA &&
10570 Py_ShellExecuteW;
10571 } else {
10572 has_ShellExecute = 0;
10573 }
10574 }
10575 return has_ShellExecute;
10576}
10577
10578
Tim Petersf58a7aa2000-09-22 10:05:54 +000010579static PyObject *
10580win32_startfile(PyObject *self, PyObject *args)
10581{
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 PyObject *ofilepath;
10583 char *filepath;
10584 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010585 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010586 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010587
Victor Stinnereb5657a2011-09-30 01:44:27 +020010588 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010589
10590 if(!check_ShellExecute()) {
10591 /* If the OS doesn't have ShellExecute, return a
10592 NotImplementedError. */
10593 return PyErr_Format(PyExc_NotImplementedError,
10594 "startfile not available on this platform");
10595 }
10596
Victor Stinner8c62be82010-05-06 00:08:46 +000010597 if (!PyArg_ParseTuple(args, "U|s:startfile",
10598 &unipath, &operation)) {
10599 PyErr_Clear();
10600 goto normal;
10601 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010602
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010604 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010606 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010607 PyErr_Clear();
10608 operation = NULL;
10609 goto normal;
10610 }
10611 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010612
Victor Stinnereb5657a2011-09-30 01:44:27 +020010613 wpath = PyUnicode_AsUnicode(unipath);
10614 if (wpath == NULL)
10615 goto normal;
10616 if (uoperation) {
10617 woperation = PyUnicode_AsUnicode(uoperation);
10618 if (woperation == NULL)
10619 goto normal;
10620 }
10621 else
10622 woperation = NULL;
10623
Victor Stinner8c62be82010-05-06 00:08:46 +000010624 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010625 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10626 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010627 Py_END_ALLOW_THREADS
10628
Victor Stinnereb5657a2011-09-30 01:44:27 +020010629 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010631 win32_error_object("startfile", unipath);
10632 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 }
10634 Py_INCREF(Py_None);
10635 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010636
10637normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010638 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10639 PyUnicode_FSConverter, &ofilepath,
10640 &operation))
10641 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010642 if (win32_warn_bytes_api()) {
10643 Py_DECREF(ofilepath);
10644 return NULL;
10645 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 filepath = PyBytes_AsString(ofilepath);
10647 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010648 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10649 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 Py_END_ALLOW_THREADS
10651 if (rc <= (HINSTANCE)32) {
10652 PyObject *errval = win32_error("startfile", filepath);
10653 Py_DECREF(ofilepath);
10654 return errval;
10655 }
10656 Py_DECREF(ofilepath);
10657 Py_INCREF(Py_None);
10658 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010659}
Larry Hastings2f936352014-08-05 14:04:04 +100010660#endif /* MS_WINDOWS */
10661
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010662
Martin v. Löwis438b5342002-12-27 10:16:42 +000010663#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010664/*[clinic input]
10665os.getloadavg
10666
10667Return average recent system load information.
10668
10669Return the number of processes in the system run queue averaged over
10670the last 1, 5, and 15 minutes as a tuple of three floats.
10671Raises OSError if the load average was unobtainable.
10672[clinic start generated code]*/
10673
Larry Hastings2f936352014-08-05 14:04:04 +100010674static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010675os_getloadavg_impl(PyObject *module)
10676/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010677{
10678 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010679 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010680 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10681 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010682 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010683 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010684}
Larry Hastings2f936352014-08-05 14:04:04 +100010685#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010686
Larry Hastings2f936352014-08-05 14:04:04 +100010687
10688/*[clinic input]
10689os.device_encoding
10690 fd: int
10691
10692Return a string describing the encoding of a terminal's file descriptor.
10693
10694The file descriptor must be attached to a terminal.
10695If the device is not a terminal, return None.
10696[clinic start generated code]*/
10697
Larry Hastings2f936352014-08-05 14:04:04 +100010698static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010699os_device_encoding_impl(PyObject *module, int fd)
10700/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010701{
Brett Cannonefb00c02012-02-29 18:31:31 -050010702 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010703}
10704
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010705
Larry Hastings2f936352014-08-05 14:04:04 +100010706#ifdef HAVE_SETRESUID
10707/*[clinic input]
10708os.setresuid
10709
10710 ruid: uid_t
10711 euid: uid_t
10712 suid: uid_t
10713 /
10714
10715Set the current process's real, effective, and saved user ids.
10716[clinic start generated code]*/
10717
Larry Hastings2f936352014-08-05 14:04:04 +100010718static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010719os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10720/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010721{
Victor Stinner8c62be82010-05-06 00:08:46 +000010722 if (setresuid(ruid, euid, suid) < 0)
10723 return posix_error();
10724 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010725}
Larry Hastings2f936352014-08-05 14:04:04 +100010726#endif /* HAVE_SETRESUID */
10727
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010728
10729#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010730/*[clinic input]
10731os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010732
Larry Hastings2f936352014-08-05 14:04:04 +100010733 rgid: gid_t
10734 egid: gid_t
10735 sgid: gid_t
10736 /
10737
10738Set the current process's real, effective, and saved group ids.
10739[clinic start generated code]*/
10740
Larry Hastings2f936352014-08-05 14:04:04 +100010741static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010742os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10743/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010744{
Victor Stinner8c62be82010-05-06 00:08:46 +000010745 if (setresgid(rgid, egid, sgid) < 0)
10746 return posix_error();
10747 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010748}
Larry Hastings2f936352014-08-05 14:04:04 +100010749#endif /* HAVE_SETRESGID */
10750
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010751
10752#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010753/*[clinic input]
10754os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010755
Larry Hastings2f936352014-08-05 14:04:04 +100010756Return a tuple of the current process's real, effective, and saved user ids.
10757[clinic start generated code]*/
10758
Larry Hastings2f936352014-08-05 14:04:04 +100010759static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010760os_getresuid_impl(PyObject *module)
10761/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010762{
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010764 if (getresuid(&ruid, &euid, &suid) < 0)
10765 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010766 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10767 _PyLong_FromUid(euid),
10768 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010769}
Larry Hastings2f936352014-08-05 14:04:04 +100010770#endif /* HAVE_GETRESUID */
10771
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010772
10773#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010774/*[clinic input]
10775os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010776
Larry Hastings2f936352014-08-05 14:04:04 +100010777Return a tuple of the current process's real, effective, and saved group ids.
10778[clinic start generated code]*/
10779
Larry Hastings2f936352014-08-05 14:04:04 +100010780static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010781os_getresgid_impl(PyObject *module)
10782/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010783{
10784 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010785 if (getresgid(&rgid, &egid, &sgid) < 0)
10786 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010787 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10788 _PyLong_FromGid(egid),
10789 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010790}
Larry Hastings2f936352014-08-05 14:04:04 +100010791#endif /* HAVE_GETRESGID */
10792
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010793
Benjamin Peterson9428d532011-09-14 11:45:52 -040010794#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010795/*[clinic input]
10796os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010797
Larry Hastings2f936352014-08-05 14:04:04 +100010798 path: path_t(allow_fd=True)
10799 attribute: path_t
10800 *
10801 follow_symlinks: bool = True
10802
10803Return the value of extended attribute attribute on path.
10804
10805path may be either a string or an open file descriptor.
10806If follow_symlinks is False, and the last element of the path is a symbolic
10807 link, getxattr will examine the symbolic link itself instead of the file
10808 the link points to.
10809
10810[clinic start generated code]*/
10811
Larry Hastings2f936352014-08-05 14:04:04 +100010812static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010813os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010814 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010815/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010816{
10817 Py_ssize_t i;
10818 PyObject *buffer = NULL;
10819
10820 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10821 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010822
Larry Hastings9cf065c2012-06-22 16:30:09 -070010823 for (i = 0; ; i++) {
10824 void *ptr;
10825 ssize_t result;
10826 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10827 Py_ssize_t buffer_size = buffer_sizes[i];
10828 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010829 path_error(path);
10830 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010831 }
10832 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10833 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010834 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010835 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010836
Larry Hastings9cf065c2012-06-22 16:30:09 -070010837 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010838 if (path->fd >= 0)
10839 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010840 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010841 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010842 else
Larry Hastings2f936352014-08-05 14:04:04 +100010843 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010844 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010845
Larry Hastings9cf065c2012-06-22 16:30:09 -070010846 if (result < 0) {
10847 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010848 if (errno == ERANGE)
10849 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010850 path_error(path);
10851 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010852 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010853
Larry Hastings9cf065c2012-06-22 16:30:09 -070010854 if (result != buffer_size) {
10855 /* Can only shrink. */
10856 _PyBytes_Resize(&buffer, result);
10857 }
10858 break;
10859 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860
Larry Hastings9cf065c2012-06-22 16:30:09 -070010861 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010862}
10863
Larry Hastings2f936352014-08-05 14:04:04 +100010864
10865/*[clinic input]
10866os.setxattr
10867
10868 path: path_t(allow_fd=True)
10869 attribute: path_t
10870 value: Py_buffer
10871 flags: int = 0
10872 *
10873 follow_symlinks: bool = True
10874
10875Set extended attribute attribute on path to value.
10876
10877path may be either a string or an open file descriptor.
10878If follow_symlinks is False, and the last element of the path is a symbolic
10879 link, setxattr will modify the symbolic link itself instead of the file
10880 the link points to.
10881
10882[clinic start generated code]*/
10883
Benjamin Peterson799bd802011-08-31 22:15:17 -040010884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010885os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010886 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010887/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010888{
Larry Hastings2f936352014-08-05 14:04:04 +100010889 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010890
Larry Hastings2f936352014-08-05 14:04:04 +100010891 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010892 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010893
Benjamin Peterson799bd802011-08-31 22:15:17 -040010894 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010895 if (path->fd > -1)
10896 result = fsetxattr(path->fd, attribute->narrow,
10897 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010898 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010899 result = setxattr(path->narrow, attribute->narrow,
10900 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010901 else
Larry Hastings2f936352014-08-05 14:04:04 +100010902 result = lsetxattr(path->narrow, attribute->narrow,
10903 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010905
Larry Hastings9cf065c2012-06-22 16:30:09 -070010906 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010907 path_error(path);
10908 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010909 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910
Larry Hastings2f936352014-08-05 14:04:04 +100010911 Py_RETURN_NONE;
10912}
10913
10914
10915/*[clinic input]
10916os.removexattr
10917
10918 path: path_t(allow_fd=True)
10919 attribute: path_t
10920 *
10921 follow_symlinks: bool = True
10922
10923Remove extended attribute attribute on path.
10924
10925path may be either a string or an open file descriptor.
10926If follow_symlinks is False, and the last element of the path is a symbolic
10927 link, removexattr will modify the symbolic link itself instead of the file
10928 the link points to.
10929
10930[clinic start generated code]*/
10931
Larry Hastings2f936352014-08-05 14:04:04 +100010932static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010933os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010934 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010935/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010936{
10937 ssize_t result;
10938
10939 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10940 return NULL;
10941
10942 Py_BEGIN_ALLOW_THREADS;
10943 if (path->fd > -1)
10944 result = fremovexattr(path->fd, attribute->narrow);
10945 else if (follow_symlinks)
10946 result = removexattr(path->narrow, attribute->narrow);
10947 else
10948 result = lremovexattr(path->narrow, attribute->narrow);
10949 Py_END_ALLOW_THREADS;
10950
10951 if (result) {
10952 return path_error(path);
10953 }
10954
10955 Py_RETURN_NONE;
10956}
10957
10958
10959/*[clinic input]
10960os.listxattr
10961
10962 path: path_t(allow_fd=True, nullable=True) = None
10963 *
10964 follow_symlinks: bool = True
10965
10966Return a list of extended attributes on path.
10967
10968path may be either None, a string, or an open file descriptor.
10969if path is None, listxattr will examine the current directory.
10970If follow_symlinks is False, and the last element of the path is a symbolic
10971 link, listxattr will examine the symbolic link itself instead of the file
10972 the link points to.
10973[clinic start generated code]*/
10974
Larry Hastings2f936352014-08-05 14:04:04 +100010975static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010976os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
10977/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010978{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010979 Py_ssize_t i;
10980 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010981 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010982 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010983
Larry Hastings2f936352014-08-05 14:04:04 +100010984 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010985 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010986
Larry Hastings2f936352014-08-05 14:04:04 +100010987 name = path->narrow ? path->narrow : ".";
10988
Larry Hastings9cf065c2012-06-22 16:30:09 -070010989 for (i = 0; ; i++) {
10990 char *start, *trace, *end;
10991 ssize_t length;
10992 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10993 Py_ssize_t buffer_size = buffer_sizes[i];
10994 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010995 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010996 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010997 break;
10998 }
10999 buffer = PyMem_MALLOC(buffer_size);
11000 if (!buffer) {
11001 PyErr_NoMemory();
11002 break;
11003 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011004
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011006 if (path->fd > -1)
11007 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011008 else if (follow_symlinks)
11009 length = listxattr(name, buffer, buffer_size);
11010 else
11011 length = llistxattr(name, buffer, buffer_size);
11012 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011013
Larry Hastings9cf065c2012-06-22 16:30:09 -070011014 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011015 if (errno == ERANGE) {
11016 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011017 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011018 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011019 }
Larry Hastings2f936352014-08-05 14:04:04 +100011020 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 break;
11022 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011023
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 result = PyList_New(0);
11025 if (!result) {
11026 goto exit;
11027 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011028
Larry Hastings9cf065c2012-06-22 16:30:09 -070011029 end = buffer + length;
11030 for (trace = start = buffer; trace != end; trace++) {
11031 if (!*trace) {
11032 int error;
11033 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11034 trace - start);
11035 if (!attribute) {
11036 Py_DECREF(result);
11037 result = NULL;
11038 goto exit;
11039 }
11040 error = PyList_Append(result, attribute);
11041 Py_DECREF(attribute);
11042 if (error) {
11043 Py_DECREF(result);
11044 result = NULL;
11045 goto exit;
11046 }
11047 start = trace + 1;
11048 }
11049 }
11050 break;
11051 }
11052exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011053 if (buffer)
11054 PyMem_FREE(buffer);
11055 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011056}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011057#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011058
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011059
Larry Hastings2f936352014-08-05 14:04:04 +100011060/*[clinic input]
11061os.urandom
11062
11063 size: Py_ssize_t
11064 /
11065
11066Return a bytes object containing random bytes suitable for cryptographic use.
11067[clinic start generated code]*/
11068
Larry Hastings2f936352014-08-05 14:04:04 +100011069static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011070os_urandom_impl(PyObject *module, Py_ssize_t size)
11071/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011072{
11073 PyObject *bytes;
11074 int result;
11075
Georg Brandl2fb477c2012-02-21 00:33:36 +010011076 if (size < 0)
11077 return PyErr_Format(PyExc_ValueError,
11078 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011079 bytes = PyBytes_FromStringAndSize(NULL, size);
11080 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011081 return NULL;
11082
Larry Hastings2f936352014-08-05 14:04:04 +100011083 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11084 PyBytes_GET_SIZE(bytes));
11085 if (result == -1) {
11086 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011087 return NULL;
11088 }
Larry Hastings2f936352014-08-05 14:04:04 +100011089 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011090}
11091
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011092/* Terminal size querying */
11093
11094static PyTypeObject TerminalSizeType;
11095
11096PyDoc_STRVAR(TerminalSize_docstring,
11097 "A tuple of (columns, lines) for holding terminal window size");
11098
11099static PyStructSequence_Field TerminalSize_fields[] = {
11100 {"columns", "width of the terminal window in characters"},
11101 {"lines", "height of the terminal window in characters"},
11102 {NULL, NULL}
11103};
11104
11105static PyStructSequence_Desc TerminalSize_desc = {
11106 "os.terminal_size",
11107 TerminalSize_docstring,
11108 TerminalSize_fields,
11109 2,
11110};
11111
11112#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011113/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011114PyDoc_STRVAR(termsize__doc__,
11115 "Return the size of the terminal window as (columns, lines).\n" \
11116 "\n" \
11117 "The optional argument fd (default standard output) specifies\n" \
11118 "which file descriptor should be queried.\n" \
11119 "\n" \
11120 "If the file descriptor is not connected to a terminal, an OSError\n" \
11121 "is thrown.\n" \
11122 "\n" \
11123 "This function will only be defined if an implementation is\n" \
11124 "available for this system.\n" \
11125 "\n" \
11126 "shutil.get_terminal_size is the high-level function which should \n" \
11127 "normally be used, os.get_terminal_size is the low-level implementation.");
11128
11129static PyObject*
11130get_terminal_size(PyObject *self, PyObject *args)
11131{
11132 int columns, lines;
11133 PyObject *termsize;
11134
11135 int fd = fileno(stdout);
11136 /* Under some conditions stdout may not be connected and
11137 * fileno(stdout) may point to an invalid file descriptor. For example
11138 * GUI apps don't have valid standard streams by default.
11139 *
11140 * If this happens, and the optional fd argument is not present,
11141 * the ioctl below will fail returning EBADF. This is what we want.
11142 */
11143
11144 if (!PyArg_ParseTuple(args, "|i", &fd))
11145 return NULL;
11146
11147#ifdef TERMSIZE_USE_IOCTL
11148 {
11149 struct winsize w;
11150 if (ioctl(fd, TIOCGWINSZ, &w))
11151 return PyErr_SetFromErrno(PyExc_OSError);
11152 columns = w.ws_col;
11153 lines = w.ws_row;
11154 }
11155#endif /* TERMSIZE_USE_IOCTL */
11156
11157#ifdef TERMSIZE_USE_CONIO
11158 {
11159 DWORD nhandle;
11160 HANDLE handle;
11161 CONSOLE_SCREEN_BUFFER_INFO csbi;
11162 switch (fd) {
11163 case 0: nhandle = STD_INPUT_HANDLE;
11164 break;
11165 case 1: nhandle = STD_OUTPUT_HANDLE;
11166 break;
11167 case 2: nhandle = STD_ERROR_HANDLE;
11168 break;
11169 default:
11170 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11171 }
11172 handle = GetStdHandle(nhandle);
11173 if (handle == NULL)
11174 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11175 if (handle == INVALID_HANDLE_VALUE)
11176 return PyErr_SetFromWindowsErr(0);
11177
11178 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11179 return PyErr_SetFromWindowsErr(0);
11180
11181 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11182 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11183 }
11184#endif /* TERMSIZE_USE_CONIO */
11185
11186 termsize = PyStructSequence_New(&TerminalSizeType);
11187 if (termsize == NULL)
11188 return NULL;
11189 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11190 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11191 if (PyErr_Occurred()) {
11192 Py_DECREF(termsize);
11193 return NULL;
11194 }
11195 return termsize;
11196}
11197#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11198
Larry Hastings2f936352014-08-05 14:04:04 +100011199
11200/*[clinic input]
11201os.cpu_count
11202
11203Return the number of CPUs in the system; return None if indeterminable.
11204[clinic start generated code]*/
11205
Larry Hastings2f936352014-08-05 14:04:04 +100011206static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011207os_cpu_count_impl(PyObject *module)
11208/*[clinic end generated code: output=5fc29463c3936a9c input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011209{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011210 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011211#ifdef MS_WINDOWS
11212 SYSTEM_INFO sysinfo;
11213 GetSystemInfo(&sysinfo);
11214 ncpu = sysinfo.dwNumberOfProcessors;
11215#elif defined(__hpux)
11216 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11217#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11218 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011219#elif defined(__DragonFly__) || \
11220 defined(__OpenBSD__) || \
11221 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011222 defined(__NetBSD__) || \
11223 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011224 int mib[2];
11225 size_t len = sizeof(ncpu);
11226 mib[0] = CTL_HW;
11227 mib[1] = HW_NCPU;
11228 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11229 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011230#endif
11231 if (ncpu >= 1)
11232 return PyLong_FromLong(ncpu);
11233 else
11234 Py_RETURN_NONE;
11235}
11236
Victor Stinnerdaf45552013-08-28 00:53:59 +020011237
Larry Hastings2f936352014-08-05 14:04:04 +100011238/*[clinic input]
11239os.get_inheritable -> bool
11240
11241 fd: int
11242 /
11243
11244Get the close-on-exe flag of the specified file descriptor.
11245[clinic start generated code]*/
11246
Larry Hastings2f936352014-08-05 14:04:04 +100011247static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011248os_get_inheritable_impl(PyObject *module, int fd)
11249/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011250{
Steve Dower8fc89802015-04-12 00:26:27 -040011251 int return_value;
11252 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011253 posix_error();
11254 return -1;
11255 }
11256
Steve Dower8fc89802015-04-12 00:26:27 -040011257 _Py_BEGIN_SUPPRESS_IPH
11258 return_value = _Py_get_inheritable(fd);
11259 _Py_END_SUPPRESS_IPH
11260 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011261}
11262
11263
11264/*[clinic input]
11265os.set_inheritable
11266 fd: int
11267 inheritable: int
11268 /
11269
11270Set the inheritable flag of the specified file descriptor.
11271[clinic start generated code]*/
11272
Larry Hastings2f936352014-08-05 14:04:04 +100011273static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011274os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11275/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011276{
Steve Dower8fc89802015-04-12 00:26:27 -040011277 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011278 if (!_PyVerify_fd(fd))
11279 return posix_error();
11280
Steve Dower8fc89802015-04-12 00:26:27 -040011281 _Py_BEGIN_SUPPRESS_IPH
11282 result = _Py_set_inheritable(fd, inheritable, NULL);
11283 _Py_END_SUPPRESS_IPH
11284 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011285 return NULL;
11286 Py_RETURN_NONE;
11287}
11288
11289
11290#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011291/*[clinic input]
11292os.get_handle_inheritable -> bool
11293 handle: Py_intptr_t
11294 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011295
Larry Hastings2f936352014-08-05 14:04:04 +100011296Get the close-on-exe flag of the specified file descriptor.
11297[clinic start generated code]*/
11298
Larry Hastings2f936352014-08-05 14:04:04 +100011299static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011300os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11301/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011302{
11303 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011304
11305 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11306 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011307 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011308 }
11309
Larry Hastings2f936352014-08-05 14:04:04 +100011310 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011311}
11312
Victor Stinnerdaf45552013-08-28 00:53:59 +020011313
Larry Hastings2f936352014-08-05 14:04:04 +100011314/*[clinic input]
11315os.set_handle_inheritable
11316 handle: Py_intptr_t
11317 inheritable: bool
11318 /
11319
11320Set the inheritable flag of the specified handle.
11321[clinic start generated code]*/
11322
Larry Hastings2f936352014-08-05 14:04:04 +100011323static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011324os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011325 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011326/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011327{
11328 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011329 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11330 PyErr_SetFromWindowsErr(0);
11331 return NULL;
11332 }
11333 Py_RETURN_NONE;
11334}
Larry Hastings2f936352014-08-05 14:04:04 +100011335#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011336
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011337#ifndef MS_WINDOWS
11338PyDoc_STRVAR(get_blocking__doc__,
11339 "get_blocking(fd) -> bool\n" \
11340 "\n" \
11341 "Get the blocking mode of the file descriptor:\n" \
11342 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11343
11344static PyObject*
11345posix_get_blocking(PyObject *self, PyObject *args)
11346{
11347 int fd;
11348 int blocking;
11349
11350 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11351 return NULL;
11352
11353 if (!_PyVerify_fd(fd))
11354 return posix_error();
11355
Steve Dower8fc89802015-04-12 00:26:27 -040011356 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011357 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011358 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011359 if (blocking < 0)
11360 return NULL;
11361 return PyBool_FromLong(blocking);
11362}
11363
11364PyDoc_STRVAR(set_blocking__doc__,
11365 "set_blocking(fd, blocking)\n" \
11366 "\n" \
11367 "Set the blocking mode of the specified file descriptor.\n" \
11368 "Set the O_NONBLOCK flag if blocking is False,\n" \
11369 "clear the O_NONBLOCK flag otherwise.");
11370
11371static PyObject*
11372posix_set_blocking(PyObject *self, PyObject *args)
11373{
Steve Dower8fc89802015-04-12 00:26:27 -040011374 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011375
11376 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11377 return NULL;
11378
11379 if (!_PyVerify_fd(fd))
11380 return posix_error();
11381
Steve Dower8fc89802015-04-12 00:26:27 -040011382 _Py_BEGIN_SUPPRESS_IPH
11383 result = _Py_set_blocking(fd, blocking);
11384 _Py_END_SUPPRESS_IPH
11385 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011386 return NULL;
11387 Py_RETURN_NONE;
11388}
11389#endif /* !MS_WINDOWS */
11390
11391
Victor Stinner6036e442015-03-08 01:58:04 +010011392PyDoc_STRVAR(posix_scandir__doc__,
11393"scandir(path='.') -> iterator of DirEntry objects for given path");
11394
11395static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11396
11397typedef struct {
11398 PyObject_HEAD
11399 PyObject *name;
11400 PyObject *path;
11401 PyObject *stat;
11402 PyObject *lstat;
11403#ifdef MS_WINDOWS
11404 struct _Py_stat_struct win32_lstat;
11405 __int64 win32_file_index;
11406 int got_file_index;
11407#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011408#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011409 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011410#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011411 ino_t d_ino;
11412#endif
11413} DirEntry;
11414
11415static void
11416DirEntry_dealloc(DirEntry *entry)
11417{
11418 Py_XDECREF(entry->name);
11419 Py_XDECREF(entry->path);
11420 Py_XDECREF(entry->stat);
11421 Py_XDECREF(entry->lstat);
11422 Py_TYPE(entry)->tp_free((PyObject *)entry);
11423}
11424
11425/* Forward reference */
11426static int
11427DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11428
11429/* Set exception and return -1 on error, 0 for False, 1 for True */
11430static int
11431DirEntry_is_symlink(DirEntry *self)
11432{
11433#ifdef MS_WINDOWS
11434 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011435#elif defined(HAVE_DIRENT_D_TYPE)
11436 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011437 if (self->d_type != DT_UNKNOWN)
11438 return self->d_type == DT_LNK;
11439 else
11440 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011441#else
11442 /* POSIX without d_type */
11443 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011444#endif
11445}
11446
11447static PyObject *
11448DirEntry_py_is_symlink(DirEntry *self)
11449{
11450 int result;
11451
11452 result = DirEntry_is_symlink(self);
11453 if (result == -1)
11454 return NULL;
11455 return PyBool_FromLong(result);
11456}
11457
11458static PyObject *
11459DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11460{
11461 int result;
11462 struct _Py_stat_struct st;
11463
11464#ifdef MS_WINDOWS
11465 wchar_t *path;
11466
11467 path = PyUnicode_AsUnicode(self->path);
11468 if (!path)
11469 return NULL;
11470
11471 if (follow_symlinks)
11472 result = win32_stat_w(path, &st);
11473 else
11474 result = win32_lstat_w(path, &st);
11475
11476 if (result != 0) {
11477 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11478 0, self->path);
11479 }
11480#else /* POSIX */
11481 PyObject *bytes;
11482 char *path;
11483
11484 if (!PyUnicode_FSConverter(self->path, &bytes))
11485 return NULL;
11486 path = PyBytes_AS_STRING(bytes);
11487
11488 if (follow_symlinks)
11489 result = STAT(path, &st);
11490 else
11491 result = LSTAT(path, &st);
11492 Py_DECREF(bytes);
11493
11494 if (result != 0)
11495 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11496#endif
11497
11498 return _pystat_fromstructstat(&st);
11499}
11500
11501static PyObject *
11502DirEntry_get_lstat(DirEntry *self)
11503{
11504 if (!self->lstat) {
11505#ifdef MS_WINDOWS
11506 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11507#else /* POSIX */
11508 self->lstat = DirEntry_fetch_stat(self, 0);
11509#endif
11510 }
11511 Py_XINCREF(self->lstat);
11512 return self->lstat;
11513}
11514
11515static PyObject *
11516DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11517{
11518 if (!follow_symlinks)
11519 return DirEntry_get_lstat(self);
11520
11521 if (!self->stat) {
11522 int result = DirEntry_is_symlink(self);
11523 if (result == -1)
11524 return NULL;
11525 else if (result)
11526 self->stat = DirEntry_fetch_stat(self, 1);
11527 else
11528 self->stat = DirEntry_get_lstat(self);
11529 }
11530
11531 Py_XINCREF(self->stat);
11532 return self->stat;
11533}
11534
11535static PyObject *
11536DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11537{
11538 int follow_symlinks = 1;
11539
11540 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11541 follow_symlinks_keywords, &follow_symlinks))
11542 return NULL;
11543
11544 return DirEntry_get_stat(self, follow_symlinks);
11545}
11546
11547/* Set exception and return -1 on error, 0 for False, 1 for True */
11548static int
11549DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11550{
11551 PyObject *stat = NULL;
11552 PyObject *st_mode = NULL;
11553 long mode;
11554 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011555#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011556 int is_symlink;
11557 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011558#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011559#ifdef MS_WINDOWS
11560 unsigned long dir_bits;
11561#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011562 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011563
11564#ifdef MS_WINDOWS
11565 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11566 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011567#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011568 is_symlink = self->d_type == DT_LNK;
11569 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11570#endif
11571
Victor Stinner35a97c02015-03-08 02:59:09 +010011572#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011573 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011574#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011575 stat = DirEntry_get_stat(self, follow_symlinks);
11576 if (!stat) {
11577 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11578 /* If file doesn't exist (anymore), then return False
11579 (i.e., say it's not a file/directory) */
11580 PyErr_Clear();
11581 return 0;
11582 }
11583 goto error;
11584 }
11585 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11586 if (!st_mode)
11587 goto error;
11588
11589 mode = PyLong_AsLong(st_mode);
11590 if (mode == -1 && PyErr_Occurred())
11591 goto error;
11592 Py_CLEAR(st_mode);
11593 Py_CLEAR(stat);
11594 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011595#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011596 }
11597 else if (is_symlink) {
11598 assert(mode_bits != S_IFLNK);
11599 result = 0;
11600 }
11601 else {
11602 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11603#ifdef MS_WINDOWS
11604 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11605 if (mode_bits == S_IFDIR)
11606 result = dir_bits != 0;
11607 else
11608 result = dir_bits == 0;
11609#else /* POSIX */
11610 if (mode_bits == S_IFDIR)
11611 result = self->d_type == DT_DIR;
11612 else
11613 result = self->d_type == DT_REG;
11614#endif
11615 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011616#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011617
11618 return result;
11619
11620error:
11621 Py_XDECREF(st_mode);
11622 Py_XDECREF(stat);
11623 return -1;
11624}
11625
11626static PyObject *
11627DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11628{
11629 int result;
11630
11631 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11632 if (result == -1)
11633 return NULL;
11634 return PyBool_FromLong(result);
11635}
11636
11637static PyObject *
11638DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11639{
11640 int follow_symlinks = 1;
11641
11642 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11643 follow_symlinks_keywords, &follow_symlinks))
11644 return NULL;
11645
11646 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11647}
11648
11649static PyObject *
11650DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11651{
11652 int follow_symlinks = 1;
11653
11654 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11655 follow_symlinks_keywords, &follow_symlinks))
11656 return NULL;
11657
11658 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11659}
11660
11661static PyObject *
11662DirEntry_inode(DirEntry *self)
11663{
11664#ifdef MS_WINDOWS
11665 if (!self->got_file_index) {
11666 wchar_t *path;
11667 struct _Py_stat_struct stat;
11668
11669 path = PyUnicode_AsUnicode(self->path);
11670 if (!path)
11671 return NULL;
11672
11673 if (win32_lstat_w(path, &stat) != 0) {
11674 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11675 0, self->path);
11676 }
11677
11678 self->win32_file_index = stat.st_ino;
11679 self->got_file_index = 1;
11680 }
11681 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11682#else /* POSIX */
11683#ifdef HAVE_LARGEFILE_SUPPORT
11684 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11685#else
11686 return PyLong_FromLong((long)self->d_ino);
11687#endif
11688#endif
11689}
11690
11691static PyObject *
11692DirEntry_repr(DirEntry *self)
11693{
11694 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11695}
11696
11697static PyMemberDef DirEntry_members[] = {
11698 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11699 "the entry's base filename, relative to scandir() \"path\" argument"},
11700 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11701 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11702 {NULL}
11703};
11704
11705static PyMethodDef DirEntry_methods[] = {
11706 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11707 "return True if the entry is a directory; cached per entry"
11708 },
11709 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11710 "return True if the entry is a file; cached per entry"
11711 },
11712 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11713 "return True if the entry is a symbolic link; cached per entry"
11714 },
11715 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11716 "return stat_result object for the entry; cached per entry"
11717 },
11718 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11719 "return inode of the entry; cached per entry",
11720 },
11721 {NULL}
11722};
11723
Benjamin Peterson5646de42015-04-12 17:56:34 -040011724static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011725 PyVarObject_HEAD_INIT(NULL, 0)
11726 MODNAME ".DirEntry", /* tp_name */
11727 sizeof(DirEntry), /* tp_basicsize */
11728 0, /* tp_itemsize */
11729 /* methods */
11730 (destructor)DirEntry_dealloc, /* tp_dealloc */
11731 0, /* tp_print */
11732 0, /* tp_getattr */
11733 0, /* tp_setattr */
11734 0, /* tp_compare */
11735 (reprfunc)DirEntry_repr, /* tp_repr */
11736 0, /* tp_as_number */
11737 0, /* tp_as_sequence */
11738 0, /* tp_as_mapping */
11739 0, /* tp_hash */
11740 0, /* tp_call */
11741 0, /* tp_str */
11742 0, /* tp_getattro */
11743 0, /* tp_setattro */
11744 0, /* tp_as_buffer */
11745 Py_TPFLAGS_DEFAULT, /* tp_flags */
11746 0, /* tp_doc */
11747 0, /* tp_traverse */
11748 0, /* tp_clear */
11749 0, /* tp_richcompare */
11750 0, /* tp_weaklistoffset */
11751 0, /* tp_iter */
11752 0, /* tp_iternext */
11753 DirEntry_methods, /* tp_methods */
11754 DirEntry_members, /* tp_members */
11755};
11756
11757#ifdef MS_WINDOWS
11758
11759static wchar_t *
11760join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11761{
11762 Py_ssize_t path_len;
11763 Py_ssize_t size;
11764 wchar_t *result;
11765 wchar_t ch;
11766
11767 if (!path_wide) { /* Default arg: "." */
11768 path_wide = L".";
11769 path_len = 1;
11770 }
11771 else {
11772 path_len = wcslen(path_wide);
11773 }
11774
11775 /* The +1's are for the path separator and the NUL */
11776 size = path_len + 1 + wcslen(filename) + 1;
11777 result = PyMem_New(wchar_t, size);
11778 if (!result) {
11779 PyErr_NoMemory();
11780 return NULL;
11781 }
11782 wcscpy(result, path_wide);
11783 if (path_len > 0) {
11784 ch = result[path_len - 1];
11785 if (ch != SEP && ch != ALTSEP && ch != L':')
11786 result[path_len++] = SEP;
11787 wcscpy(result + path_len, filename);
11788 }
11789 return result;
11790}
11791
11792static PyObject *
11793DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11794{
11795 DirEntry *entry;
11796 BY_HANDLE_FILE_INFORMATION file_info;
11797 ULONG reparse_tag;
11798 wchar_t *joined_path;
11799
11800 entry = PyObject_New(DirEntry, &DirEntryType);
11801 if (!entry)
11802 return NULL;
11803 entry->name = NULL;
11804 entry->path = NULL;
11805 entry->stat = NULL;
11806 entry->lstat = NULL;
11807 entry->got_file_index = 0;
11808
11809 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11810 if (!entry->name)
11811 goto error;
11812
11813 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11814 if (!joined_path)
11815 goto error;
11816
11817 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11818 PyMem_Free(joined_path);
11819 if (!entry->path)
11820 goto error;
11821
11822 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11823 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11824
11825 return (PyObject *)entry;
11826
11827error:
11828 Py_DECREF(entry);
11829 return NULL;
11830}
11831
11832#else /* POSIX */
11833
11834static char *
11835join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11836{
11837 Py_ssize_t path_len;
11838 Py_ssize_t size;
11839 char *result;
11840
11841 if (!path_narrow) { /* Default arg: "." */
11842 path_narrow = ".";
11843 path_len = 1;
11844 }
11845 else {
11846 path_len = strlen(path_narrow);
11847 }
11848
11849 if (filename_len == -1)
11850 filename_len = strlen(filename);
11851
11852 /* The +1's are for the path separator and the NUL */
11853 size = path_len + 1 + filename_len + 1;
11854 result = PyMem_New(char, size);
11855 if (!result) {
11856 PyErr_NoMemory();
11857 return NULL;
11858 }
11859 strcpy(result, path_narrow);
11860 if (path_len > 0 && result[path_len - 1] != '/')
11861 result[path_len++] = '/';
11862 strcpy(result + path_len, filename);
11863 return result;
11864}
11865
11866static PyObject *
11867DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011868 ino_t d_ino
11869#ifdef HAVE_DIRENT_D_TYPE
11870 , unsigned char d_type
11871#endif
11872 )
Victor Stinner6036e442015-03-08 01:58:04 +010011873{
11874 DirEntry *entry;
11875 char *joined_path;
11876
11877 entry = PyObject_New(DirEntry, &DirEntryType);
11878 if (!entry)
11879 return NULL;
11880 entry->name = NULL;
11881 entry->path = NULL;
11882 entry->stat = NULL;
11883 entry->lstat = NULL;
11884
11885 joined_path = join_path_filename(path->narrow, name, name_len);
11886 if (!joined_path)
11887 goto error;
11888
11889 if (!path->narrow || !PyBytes_Check(path->object)) {
11890 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11891 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11892 }
11893 else {
11894 entry->name = PyBytes_FromStringAndSize(name, name_len);
11895 entry->path = PyBytes_FromString(joined_path);
11896 }
11897 PyMem_Free(joined_path);
11898 if (!entry->name || !entry->path)
11899 goto error;
11900
Victor Stinner35a97c02015-03-08 02:59:09 +010011901#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011902 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011903#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011904 entry->d_ino = d_ino;
11905
11906 return (PyObject *)entry;
11907
11908error:
11909 Py_XDECREF(entry);
11910 return NULL;
11911}
11912
11913#endif
11914
11915
11916typedef struct {
11917 PyObject_HEAD
11918 path_t path;
11919#ifdef MS_WINDOWS
11920 HANDLE handle;
11921 WIN32_FIND_DATAW file_data;
11922 int first_time;
11923#else /* POSIX */
11924 DIR *dirp;
11925#endif
11926} ScandirIterator;
11927
11928#ifdef MS_WINDOWS
11929
11930static void
11931ScandirIterator_close(ScandirIterator *iterator)
11932{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011933 HANDLE handle = iterator->handle;
11934
11935 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011936 return;
11937
Victor Stinner6036e442015-03-08 01:58:04 +010011938 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011939 Py_BEGIN_ALLOW_THREADS
11940 FindClose(handle);
11941 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011942}
11943
11944static PyObject *
11945ScandirIterator_iternext(ScandirIterator *iterator)
11946{
11947 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11948 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011949 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011950
11951 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011952 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011953 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011954
11955 while (1) {
11956 if (!iterator->first_time) {
11957 Py_BEGIN_ALLOW_THREADS
11958 success = FindNextFileW(iterator->handle, file_data);
11959 Py_END_ALLOW_THREADS
11960 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011961 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011962 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011963 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011964 break;
11965 }
11966 }
11967 iterator->first_time = 0;
11968
11969 /* Skip over . and .. */
11970 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011971 wcscmp(file_data->cFileName, L"..") != 0) {
11972 entry = DirEntry_from_find_data(&iterator->path, file_data);
11973 if (!entry)
11974 break;
11975 return entry;
11976 }
Victor Stinner6036e442015-03-08 01:58:04 +010011977
11978 /* Loop till we get a non-dot directory or finish iterating */
11979 }
11980
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011981 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011982 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011983 return NULL;
11984}
11985
11986#else /* POSIX */
11987
11988static void
11989ScandirIterator_close(ScandirIterator *iterator)
11990{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011991 DIR *dirp = iterator->dirp;
11992
11993 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010011994 return;
11995
Victor Stinner6036e442015-03-08 01:58:04 +010011996 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011997 Py_BEGIN_ALLOW_THREADS
11998 closedir(dirp);
11999 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012000 return;
12001}
12002
12003static PyObject *
12004ScandirIterator_iternext(ScandirIterator *iterator)
12005{
12006 struct dirent *direntp;
12007 Py_ssize_t name_len;
12008 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012009 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012010
12011 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012012 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012013 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012014
12015 while (1) {
12016 errno = 0;
12017 Py_BEGIN_ALLOW_THREADS
12018 direntp = readdir(iterator->dirp);
12019 Py_END_ALLOW_THREADS
12020
12021 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012022 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012023 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012024 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012025 break;
12026 }
12027
12028 /* Skip over . and .. */
12029 name_len = NAMLEN(direntp);
12030 is_dot = direntp->d_name[0] == '.' &&
12031 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12032 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012033 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012034 name_len, direntp->d_ino
12035#ifdef HAVE_DIRENT_D_TYPE
12036 , direntp->d_type
12037#endif
12038 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012039 if (!entry)
12040 break;
12041 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012042 }
12043
12044 /* Loop till we get a non-dot directory or finish iterating */
12045 }
12046
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012047 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012048 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012049 return NULL;
12050}
12051
12052#endif
12053
12054static void
12055ScandirIterator_dealloc(ScandirIterator *iterator)
12056{
12057 ScandirIterator_close(iterator);
12058 Py_XDECREF(iterator->path.object);
12059 path_cleanup(&iterator->path);
12060 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12061}
12062
Benjamin Peterson5646de42015-04-12 17:56:34 -040012063static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012064 PyVarObject_HEAD_INIT(NULL, 0)
12065 MODNAME ".ScandirIterator", /* tp_name */
12066 sizeof(ScandirIterator), /* tp_basicsize */
12067 0, /* tp_itemsize */
12068 /* methods */
12069 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12070 0, /* tp_print */
12071 0, /* tp_getattr */
12072 0, /* tp_setattr */
12073 0, /* tp_compare */
12074 0, /* tp_repr */
12075 0, /* tp_as_number */
12076 0, /* tp_as_sequence */
12077 0, /* tp_as_mapping */
12078 0, /* tp_hash */
12079 0, /* tp_call */
12080 0, /* tp_str */
12081 0, /* tp_getattro */
12082 0, /* tp_setattro */
12083 0, /* tp_as_buffer */
12084 Py_TPFLAGS_DEFAULT, /* tp_flags */
12085 0, /* tp_doc */
12086 0, /* tp_traverse */
12087 0, /* tp_clear */
12088 0, /* tp_richcompare */
12089 0, /* tp_weaklistoffset */
12090 PyObject_SelfIter, /* tp_iter */
12091 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12092};
12093
12094static PyObject *
12095posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12096{
12097 ScandirIterator *iterator;
12098 static char *keywords[] = {"path", NULL};
12099#ifdef MS_WINDOWS
12100 wchar_t *path_strW;
12101#else
12102 char *path;
12103#endif
12104
12105 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12106 if (!iterator)
12107 return NULL;
12108 memset(&iterator->path, 0, sizeof(path_t));
12109 iterator->path.function_name = "scandir";
12110 iterator->path.nullable = 1;
12111
12112#ifdef MS_WINDOWS
12113 iterator->handle = INVALID_HANDLE_VALUE;
12114#else
12115 iterator->dirp = NULL;
12116#endif
12117
12118 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12119 path_converter, &iterator->path))
12120 goto error;
12121
12122 /* path_converter doesn't keep path.object around, so do it
12123 manually for the lifetime of the iterator here (the refcount
12124 is decremented in ScandirIterator_dealloc)
12125 */
12126 Py_XINCREF(iterator->path.object);
12127
12128#ifdef MS_WINDOWS
12129 if (iterator->path.narrow) {
12130 PyErr_SetString(PyExc_TypeError,
12131 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12132 goto error;
12133 }
12134 iterator->first_time = 1;
12135
12136 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12137 if (!path_strW)
12138 goto error;
12139
12140 Py_BEGIN_ALLOW_THREADS
12141 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12142 Py_END_ALLOW_THREADS
12143
12144 PyMem_Free(path_strW);
12145
12146 if (iterator->handle == INVALID_HANDLE_VALUE) {
12147 path_error(&iterator->path);
12148 goto error;
12149 }
12150#else /* POSIX */
12151 if (iterator->path.narrow)
12152 path = iterator->path.narrow;
12153 else
12154 path = ".";
12155
12156 errno = 0;
12157 Py_BEGIN_ALLOW_THREADS
12158 iterator->dirp = opendir(path);
12159 Py_END_ALLOW_THREADS
12160
12161 if (!iterator->dirp) {
12162 path_error(&iterator->path);
12163 goto error;
12164 }
12165#endif
12166
12167 return (PyObject *)iterator;
12168
12169error:
12170 Py_DECREF(iterator);
12171 return NULL;
12172}
12173
12174
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012175#include "clinic/posixmodule.c.h"
12176
Larry Hastings7726ac92014-01-31 22:03:12 -080012177/*[clinic input]
12178dump buffer
12179[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012180/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012181
Larry Hastings31826802013-10-19 00:09:25 -070012182
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012183static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012184
12185 OS_STAT_METHODDEF
12186 OS_ACCESS_METHODDEF
12187 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012188 OS_CHDIR_METHODDEF
12189 OS_CHFLAGS_METHODDEF
12190 OS_CHMOD_METHODDEF
12191 OS_FCHMOD_METHODDEF
12192 OS_LCHMOD_METHODDEF
12193 OS_CHOWN_METHODDEF
12194 OS_FCHOWN_METHODDEF
12195 OS_LCHOWN_METHODDEF
12196 OS_LCHFLAGS_METHODDEF
12197 OS_CHROOT_METHODDEF
12198 OS_CTERMID_METHODDEF
12199 OS_GETCWD_METHODDEF
12200 OS_GETCWDB_METHODDEF
12201 OS_LINK_METHODDEF
12202 OS_LISTDIR_METHODDEF
12203 OS_LSTAT_METHODDEF
12204 OS_MKDIR_METHODDEF
12205 OS_NICE_METHODDEF
12206 OS_GETPRIORITY_METHODDEF
12207 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012208#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012209 {"readlink", (PyCFunction)posix_readlink,
12210 METH_VARARGS | METH_KEYWORDS,
12211 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012212#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012213#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012214 {"readlink", (PyCFunction)win_readlink,
12215 METH_VARARGS | METH_KEYWORDS,
12216 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012217#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012218 OS_RENAME_METHODDEF
12219 OS_REPLACE_METHODDEF
12220 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012221 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012222 OS_SYMLINK_METHODDEF
12223 OS_SYSTEM_METHODDEF
12224 OS_UMASK_METHODDEF
12225 OS_UNAME_METHODDEF
12226 OS_UNLINK_METHODDEF
12227 OS_REMOVE_METHODDEF
12228 OS_UTIME_METHODDEF
12229 OS_TIMES_METHODDEF
12230 OS__EXIT_METHODDEF
12231 OS_EXECV_METHODDEF
12232 OS_EXECVE_METHODDEF
12233 OS_SPAWNV_METHODDEF
12234 OS_SPAWNVE_METHODDEF
12235 OS_FORK1_METHODDEF
12236 OS_FORK_METHODDEF
12237 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12238 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12239 OS_SCHED_GETPARAM_METHODDEF
12240 OS_SCHED_GETSCHEDULER_METHODDEF
12241 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12242 OS_SCHED_SETPARAM_METHODDEF
12243 OS_SCHED_SETSCHEDULER_METHODDEF
12244 OS_SCHED_YIELD_METHODDEF
12245 OS_SCHED_SETAFFINITY_METHODDEF
12246 OS_SCHED_GETAFFINITY_METHODDEF
12247 OS_OPENPTY_METHODDEF
12248 OS_FORKPTY_METHODDEF
12249 OS_GETEGID_METHODDEF
12250 OS_GETEUID_METHODDEF
12251 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012252#ifdef HAVE_GETGROUPLIST
12253 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12254#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012255 OS_GETGROUPS_METHODDEF
12256 OS_GETPID_METHODDEF
12257 OS_GETPGRP_METHODDEF
12258 OS_GETPPID_METHODDEF
12259 OS_GETUID_METHODDEF
12260 OS_GETLOGIN_METHODDEF
12261 OS_KILL_METHODDEF
12262 OS_KILLPG_METHODDEF
12263 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012264#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012265 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012266#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012267 OS_SETUID_METHODDEF
12268 OS_SETEUID_METHODDEF
12269 OS_SETREUID_METHODDEF
12270 OS_SETGID_METHODDEF
12271 OS_SETEGID_METHODDEF
12272 OS_SETREGID_METHODDEF
12273 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012274#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012275 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012276#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012277 OS_GETPGID_METHODDEF
12278 OS_SETPGRP_METHODDEF
12279 OS_WAIT_METHODDEF
12280 OS_WAIT3_METHODDEF
12281 OS_WAIT4_METHODDEF
12282 OS_WAITID_METHODDEF
12283 OS_WAITPID_METHODDEF
12284 OS_GETSID_METHODDEF
12285 OS_SETSID_METHODDEF
12286 OS_SETPGID_METHODDEF
12287 OS_TCGETPGRP_METHODDEF
12288 OS_TCSETPGRP_METHODDEF
12289 OS_OPEN_METHODDEF
12290 OS_CLOSE_METHODDEF
12291 OS_CLOSERANGE_METHODDEF
12292 OS_DEVICE_ENCODING_METHODDEF
12293 OS_DUP_METHODDEF
12294 OS_DUP2_METHODDEF
12295 OS_LOCKF_METHODDEF
12296 OS_LSEEK_METHODDEF
12297 OS_READ_METHODDEF
12298 OS_READV_METHODDEF
12299 OS_PREAD_METHODDEF
12300 OS_WRITE_METHODDEF
12301 OS_WRITEV_METHODDEF
12302 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012303#ifdef HAVE_SENDFILE
12304 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12305 posix_sendfile__doc__},
12306#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012307 OS_FSTAT_METHODDEF
12308 OS_ISATTY_METHODDEF
12309 OS_PIPE_METHODDEF
12310 OS_PIPE2_METHODDEF
12311 OS_MKFIFO_METHODDEF
12312 OS_MKNOD_METHODDEF
12313 OS_MAJOR_METHODDEF
12314 OS_MINOR_METHODDEF
12315 OS_MAKEDEV_METHODDEF
12316 OS_FTRUNCATE_METHODDEF
12317 OS_TRUNCATE_METHODDEF
12318 OS_POSIX_FALLOCATE_METHODDEF
12319 OS_POSIX_FADVISE_METHODDEF
12320 OS_PUTENV_METHODDEF
12321 OS_UNSETENV_METHODDEF
12322 OS_STRERROR_METHODDEF
12323 OS_FCHDIR_METHODDEF
12324 OS_FSYNC_METHODDEF
12325 OS_SYNC_METHODDEF
12326 OS_FDATASYNC_METHODDEF
12327 OS_WCOREDUMP_METHODDEF
12328 OS_WIFCONTINUED_METHODDEF
12329 OS_WIFSTOPPED_METHODDEF
12330 OS_WIFSIGNALED_METHODDEF
12331 OS_WIFEXITED_METHODDEF
12332 OS_WEXITSTATUS_METHODDEF
12333 OS_WTERMSIG_METHODDEF
12334 OS_WSTOPSIG_METHODDEF
12335 OS_FSTATVFS_METHODDEF
12336 OS_STATVFS_METHODDEF
12337 OS_CONFSTR_METHODDEF
12338 OS_SYSCONF_METHODDEF
12339 OS_FPATHCONF_METHODDEF
12340 OS_PATHCONF_METHODDEF
12341 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012342 OS__GETFULLPATHNAME_METHODDEF
12343 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012344 OS__GETDISKUSAGE_METHODDEF
12345 OS__GETFINALPATHNAME_METHODDEF
12346 OS__GETVOLUMEPATHNAME_METHODDEF
12347 OS_GETLOADAVG_METHODDEF
12348 OS_URANDOM_METHODDEF
12349 OS_SETRESUID_METHODDEF
12350 OS_SETRESGID_METHODDEF
12351 OS_GETRESUID_METHODDEF
12352 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012353
Larry Hastings2f936352014-08-05 14:04:04 +100012354 OS_GETXATTR_METHODDEF
12355 OS_SETXATTR_METHODDEF
12356 OS_REMOVEXATTR_METHODDEF
12357 OS_LISTXATTR_METHODDEF
12358
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012359#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12360 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12361#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012362 OS_CPU_COUNT_METHODDEF
12363 OS_GET_INHERITABLE_METHODDEF
12364 OS_SET_INHERITABLE_METHODDEF
12365 OS_GET_HANDLE_INHERITABLE_METHODDEF
12366 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012367#ifndef MS_WINDOWS
12368 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12369 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12370#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012371 {"scandir", (PyCFunction)posix_scandir,
12372 METH_VARARGS | METH_KEYWORDS,
12373 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012374 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012375};
12376
12377
Brian Curtin52173d42010-12-02 18:29:18 +000012378#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012379static int
Brian Curtin52173d42010-12-02 18:29:18 +000012380enable_symlink()
12381{
12382 HANDLE tok;
12383 TOKEN_PRIVILEGES tok_priv;
12384 LUID luid;
12385 int meth_idx = 0;
12386
12387 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012388 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012389
12390 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012391 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012392
12393 tok_priv.PrivilegeCount = 1;
12394 tok_priv.Privileges[0].Luid = luid;
12395 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12396
12397 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12398 sizeof(TOKEN_PRIVILEGES),
12399 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012400 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012401
Brian Curtin3b4499c2010-12-28 14:31:47 +000012402 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12403 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012404}
12405#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12406
Barry Warsaw4a342091996-12-19 23:50:02 +000012407static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012408all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012409{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012410#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012411 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012412#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012413#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012415#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012416#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012418#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012419#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012420 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012421#endif
Fred Drakec9680921999-12-13 16:37:25 +000012422#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012424#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012425#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012427#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012428#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012430#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012433#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012434#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012436#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012437#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012438 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012439#endif
12440#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012441 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012442#endif
12443#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012445#endif
12446#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012447 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012448#endif
12449#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012450 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012451#endif
12452#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012453 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012454#endif
12455#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012456 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012457#endif
12458#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012460#endif
12461#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012462 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012463#endif
12464#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012466#endif
12467#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012469#endif
12470#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012472#endif
12473#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012475#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012476#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012477 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012478#endif
12479#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012481#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012482#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012484#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012485#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012487#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012488#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012490#endif
12491#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012493#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012494#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012495 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012496#endif
12497#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012498 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012499#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012500#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012501 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012502#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012503#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012504 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012505#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012506#ifdef O_TMPFILE
12507 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12508#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012509#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012511#endif
12512#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012513 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012514#endif
12515#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012516 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012517#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012518#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012519 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012520#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012521#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012522 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012523#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012524
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012525
Jesus Cea94363612012-06-22 18:32:07 +020012526#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012527 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012528#endif
12529#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012531#endif
12532
Tim Peters5aa91602002-01-30 05:46:57 +000012533/* MS Windows */
12534#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012535 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012537#endif
12538#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012539 /* Optimize for short life (keep in memory). */
12540 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012541 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012542#endif
12543#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012544 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012545 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012546#endif
12547#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012548 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012549 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012550#endif
12551#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012552 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012553 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012554#endif
12555
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012556/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012557#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012558 /* Send a SIGIO signal whenever input or output
12559 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012560 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012561#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012562#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012563 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012564 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012565#endif
12566#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012567 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012568 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012569#endif
12570#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012571 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012573#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012574#ifdef O_NOLINKS
12575 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012576 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012577#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012578#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012579 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012580 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012581#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012582
Victor Stinner8c62be82010-05-06 00:08:46 +000012583 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012604#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012605#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012607#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012608#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012610#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012611#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012612 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012613#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012614#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012616#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012617#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012618 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012619#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012620#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012622#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012623#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012625#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012626#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012628#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012629#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012630 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012631#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012632#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012634#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012635
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012636 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012637#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012639#endif /* ST_RDONLY */
12640#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012642#endif /* ST_NOSUID */
12643
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012644 /* GNU extensions */
12645#ifdef ST_NODEV
12646 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12647#endif /* ST_NODEV */
12648#ifdef ST_NOEXEC
12649 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12650#endif /* ST_NOEXEC */
12651#ifdef ST_SYNCHRONOUS
12652 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12653#endif /* ST_SYNCHRONOUS */
12654#ifdef ST_MANDLOCK
12655 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12656#endif /* ST_MANDLOCK */
12657#ifdef ST_WRITE
12658 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12659#endif /* ST_WRITE */
12660#ifdef ST_APPEND
12661 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12662#endif /* ST_APPEND */
12663#ifdef ST_NOATIME
12664 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12665#endif /* ST_NOATIME */
12666#ifdef ST_NODIRATIME
12667 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12668#endif /* ST_NODIRATIME */
12669#ifdef ST_RELATIME
12670 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12671#endif /* ST_RELATIME */
12672
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012673 /* FreeBSD sendfile() constants */
12674#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012676#endif
12677#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012678 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012679#endif
12680#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012682#endif
12683
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684 /* constants for posix_fadvise */
12685#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012699#endif
12700#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012702#endif
12703
12704 /* constants for waitid */
12705#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12707 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12708 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012709#endif
12710#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012712#endif
12713#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012715#endif
12716#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012718#endif
12719#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012721#endif
12722#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012724#endif
12725#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012726 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012727#endif
12728#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012730#endif
12731
12732 /* constants for lockf */
12733#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012735#endif
12736#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012738#endif
12739#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012741#endif
12742#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012744#endif
12745
Guido van Rossum246bc171999-02-01 23:54:31 +000012746#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012747 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12748 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12749 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12750 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12751 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012752#endif
12753
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012754#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012755#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012757#endif
12758#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012760#endif
12761#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012763#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012764#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012766#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012767#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012769#endif
12770#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012772#endif
12773#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012775#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012776#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012777 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012778#endif
12779#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012781#endif
12782#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012783 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012784#endif
12785#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012787#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012788#endif
12789
Benjamin Peterson9428d532011-09-14 11:45:52 -040012790#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12792 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12793 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012794#endif
12795
Victor Stinner8b905bd2011-10-25 13:34:04 +020012796#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012798#endif
12799#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012801#endif
12802#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012804#endif
12805#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012807#endif
12808#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012809 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012810#endif
12811#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012812 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012813#endif
12814#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012815 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012816#endif
12817
Victor Stinner8c62be82010-05-06 00:08:46 +000012818 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012819}
12820
12821
Martin v. Löwis1a214512008-06-11 05:26:20 +000012822static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012823 PyModuleDef_HEAD_INIT,
12824 MODNAME,
12825 posix__doc__,
12826 -1,
12827 posix_methods,
12828 NULL,
12829 NULL,
12830 NULL,
12831 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012832};
12833
12834
Larry Hastings9cf065c2012-06-22 16:30:09 -070012835static char *have_functions[] = {
12836
12837#ifdef HAVE_FACCESSAT
12838 "HAVE_FACCESSAT",
12839#endif
12840
12841#ifdef HAVE_FCHDIR
12842 "HAVE_FCHDIR",
12843#endif
12844
12845#ifdef HAVE_FCHMOD
12846 "HAVE_FCHMOD",
12847#endif
12848
12849#ifdef HAVE_FCHMODAT
12850 "HAVE_FCHMODAT",
12851#endif
12852
12853#ifdef HAVE_FCHOWN
12854 "HAVE_FCHOWN",
12855#endif
12856
Larry Hastings00964ed2013-08-12 13:49:30 -040012857#ifdef HAVE_FCHOWNAT
12858 "HAVE_FCHOWNAT",
12859#endif
12860
Larry Hastings9cf065c2012-06-22 16:30:09 -070012861#ifdef HAVE_FEXECVE
12862 "HAVE_FEXECVE",
12863#endif
12864
12865#ifdef HAVE_FDOPENDIR
12866 "HAVE_FDOPENDIR",
12867#endif
12868
Georg Brandl306336b2012-06-24 12:55:33 +020012869#ifdef HAVE_FPATHCONF
12870 "HAVE_FPATHCONF",
12871#endif
12872
Larry Hastings9cf065c2012-06-22 16:30:09 -070012873#ifdef HAVE_FSTATAT
12874 "HAVE_FSTATAT",
12875#endif
12876
12877#ifdef HAVE_FSTATVFS
12878 "HAVE_FSTATVFS",
12879#endif
12880
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012881#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012882 "HAVE_FTRUNCATE",
12883#endif
12884
Larry Hastings9cf065c2012-06-22 16:30:09 -070012885#ifdef HAVE_FUTIMENS
12886 "HAVE_FUTIMENS",
12887#endif
12888
12889#ifdef HAVE_FUTIMES
12890 "HAVE_FUTIMES",
12891#endif
12892
12893#ifdef HAVE_FUTIMESAT
12894 "HAVE_FUTIMESAT",
12895#endif
12896
12897#ifdef HAVE_LINKAT
12898 "HAVE_LINKAT",
12899#endif
12900
12901#ifdef HAVE_LCHFLAGS
12902 "HAVE_LCHFLAGS",
12903#endif
12904
12905#ifdef HAVE_LCHMOD
12906 "HAVE_LCHMOD",
12907#endif
12908
12909#ifdef HAVE_LCHOWN
12910 "HAVE_LCHOWN",
12911#endif
12912
12913#ifdef HAVE_LSTAT
12914 "HAVE_LSTAT",
12915#endif
12916
12917#ifdef HAVE_LUTIMES
12918 "HAVE_LUTIMES",
12919#endif
12920
12921#ifdef HAVE_MKDIRAT
12922 "HAVE_MKDIRAT",
12923#endif
12924
12925#ifdef HAVE_MKFIFOAT
12926 "HAVE_MKFIFOAT",
12927#endif
12928
12929#ifdef HAVE_MKNODAT
12930 "HAVE_MKNODAT",
12931#endif
12932
12933#ifdef HAVE_OPENAT
12934 "HAVE_OPENAT",
12935#endif
12936
12937#ifdef HAVE_READLINKAT
12938 "HAVE_READLINKAT",
12939#endif
12940
12941#ifdef HAVE_RENAMEAT
12942 "HAVE_RENAMEAT",
12943#endif
12944
12945#ifdef HAVE_SYMLINKAT
12946 "HAVE_SYMLINKAT",
12947#endif
12948
12949#ifdef HAVE_UNLINKAT
12950 "HAVE_UNLINKAT",
12951#endif
12952
12953#ifdef HAVE_UTIMENSAT
12954 "HAVE_UTIMENSAT",
12955#endif
12956
12957#ifdef MS_WINDOWS
12958 "MS_WINDOWS",
12959#endif
12960
12961 NULL
12962};
12963
12964
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012965PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012966INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012967{
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012969 PyObject *list;
12970 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012971
Brian Curtin52173d42010-12-02 18:29:18 +000012972#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012973 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012974#endif
12975
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 m = PyModule_Create(&posixmodule);
12977 if (m == NULL)
12978 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012979
Victor Stinner8c62be82010-05-06 00:08:46 +000012980 /* Initialize environ dictionary */
12981 v = convertenviron();
12982 Py_XINCREF(v);
12983 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12984 return NULL;
12985 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012986
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 if (all_ins(m))
12988 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012989
Victor Stinner8c62be82010-05-06 00:08:46 +000012990 if (setup_confname_tables(m))
12991 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012992
Victor Stinner8c62be82010-05-06 00:08:46 +000012993 Py_INCREF(PyExc_OSError);
12994 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012995
Guido van Rossumb3d39562000-01-31 18:41:26 +000012996#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 if (posix_putenv_garbage == NULL)
12998 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012999#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013000
Victor Stinner8c62be82010-05-06 00:08:46 +000013001 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013002#if defined(HAVE_WAITID) && !defined(__APPLE__)
13003 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013004 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13005 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013006#endif
13007
Christian Heimes25827622013-10-12 01:27:08 +020013008 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013009 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13010 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13011 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013012 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13013 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 structseq_new = StatResultType.tp_new;
13015 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013016
Christian Heimes25827622013-10-12 01:27:08 +020013017 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013018 if (PyStructSequence_InitType2(&StatVFSResultType,
13019 &statvfs_result_desc) < 0)
13020 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013021#ifdef NEED_TICKS_PER_SECOND
13022# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013023 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013024# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013025 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013026# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013027 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013028# endif
13029#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013030
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013031#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013032 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013033 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13034 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013035 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013036#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013037
13038 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013039 if (PyStructSequence_InitType2(&TerminalSizeType,
13040 &TerminalSize_desc) < 0)
13041 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013042
13043 /* initialize scandir types */
13044 if (PyType_Ready(&ScandirIteratorType) < 0)
13045 return NULL;
13046 if (PyType_Ready(&DirEntryType) < 0)
13047 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013048 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013049#if defined(HAVE_WAITID) && !defined(__APPLE__)
13050 Py_INCREF((PyObject*) &WaitidResultType);
13051 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13052#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013053 Py_INCREF((PyObject*) &StatResultType);
13054 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13055 Py_INCREF((PyObject*) &StatVFSResultType);
13056 PyModule_AddObject(m, "statvfs_result",
13057 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013058
13059#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013060 Py_INCREF(&SchedParamType);
13061 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013062#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013063
Larry Hastings605a62d2012-06-24 04:33:36 -070013064 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013065 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13066 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013067 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13068
13069 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013070 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13071 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013072 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13073
Thomas Wouters477c8d52006-05-27 19:21:47 +000013074#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013075 /*
13076 * Step 2 of weak-linking support on Mac OS X.
13077 *
13078 * The code below removes functions that are not available on the
13079 * currently active platform.
13080 *
13081 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013082 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013083 * OSX 10.4.
13084 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013085#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013086 if (fstatvfs == NULL) {
13087 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13088 return NULL;
13089 }
13090 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013091#endif /* HAVE_FSTATVFS */
13092
13093#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013094 if (statvfs == NULL) {
13095 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13096 return NULL;
13097 }
13098 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013099#endif /* HAVE_STATVFS */
13100
13101# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013102 if (lchown == NULL) {
13103 if (PyObject_DelAttrString(m, "lchown") == -1) {
13104 return NULL;
13105 }
13106 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013107#endif /* HAVE_LCHOWN */
13108
13109
13110#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013111
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013112 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013113 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13114
Larry Hastings6fe20b32012-04-19 15:07:49 -070013115 billion = PyLong_FromLong(1000000000);
13116 if (!billion)
13117 return NULL;
13118
Larry Hastings9cf065c2012-06-22 16:30:09 -070013119 /* suppress "function not used" warnings */
13120 {
13121 int ignored;
13122 fd_specified("", -1);
13123 follow_symlinks_specified("", 1);
13124 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13125 dir_fd_converter(Py_None, &ignored);
13126 dir_fd_unavailable(Py_None, &ignored);
13127 }
13128
13129 /*
13130 * provide list of locally available functions
13131 * so os.py can populate support_* lists
13132 */
13133 list = PyList_New(0);
13134 if (!list)
13135 return NULL;
13136 for (trace = have_functions; *trace; trace++) {
13137 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13138 if (!unicode)
13139 return NULL;
13140 if (PyList_Append(list, unicode))
13141 return NULL;
13142 Py_DECREF(unicode);
13143 }
13144 PyModule_AddObject(m, "_have_functions", list);
13145
13146 initialized = 1;
13147
Victor Stinner8c62be82010-05-06 00:08:46 +000013148 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013149}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013150
13151#ifdef __cplusplus
13152}
13153#endif