blob: 3e446a524e9e93e1c4fd5f661691ae27c1e944bf [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002/* POSIX module implementation */
3
Jesus Ceaab70e2a2012-10-05 01:48:08 +02004/* This file is also used for Windows NT/MS-Win. In that case the
5 module actually calls itself 'nt', not 'posix', and a few
Andrew MacIntyre6c73af22002-03-03 03:07:07 +00006 functions are either unimplemented or implemented differently. The source
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00007 assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
Guido van Rossumad0ee831995-03-01 10:34:45 +00008 of the compiler used. Different compilers define their own feature
Victor Stinnerf427a142014-10-22 12:33:23 +02009 test macro, e.g. '_MSC_VER'. */
Guido van Rossumad0ee831995-03-01 10:34:45 +000010
Larry Hastings31826802013-10-19 00:09:25 -070011
12
Thomas Wouters477c8d52006-05-27 19:21:47 +000013#ifdef __APPLE__
14 /*
Victor Stinner8c62be82010-05-06 00:08:46 +000015 * Step 1 of support for weak-linking a number of symbols existing on
Thomas Wouters477c8d52006-05-27 19:21:47 +000016 * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
17 * at the end of this file for more information.
18 */
19# pragma weak lchown
20# pragma weak statvfs
21# pragma weak fstatvfs
22
23#endif /* __APPLE__ */
24
Thomas Wouters68bc4f92006-03-01 01:05:10 +000025#define PY_SSIZE_T_CLEAN
26
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000027#include "Python.h"
Victor Stinner6036e442015-03-08 01:58:04 +010028#include "structmember.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020029#ifndef MS_WINDOWS
30#include "posixmodule.h"
Tim Golden0321cf22014-05-05 19:46:17 +010031#else
32#include "winreparse.h"
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020033#endif
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000034
Gregory P. Smith ext:(%20%5BGoogle%20Inc.%5D)fa76eee2016-05-28 21:03:48 +000035#include <stdio.h> /* needed for ctermid() */
36
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000037#ifdef __cplusplus
38extern "C" {
39#endif
40
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000041PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000042"This module provides access to operating system functionality that is\n\
43standardized by the C Standard and the POSIX standard (a thinly\n\
44disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000045corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000046
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000047
Ross Lagerwall4d076da2011-03-18 06:56:53 +020048#ifdef HAVE_SYS_UIO_H
49#include <sys/uio.h>
50#endif
51
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000053#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054#endif /* HAVE_SYS_TYPES_H */
55
56#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000057#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000059
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000061#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000062#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000063
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000065#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000066#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000067
Guido van Rossumb6775db1994-08-01 11:34:53 +000068#ifdef HAVE_FCNTL_H
69#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000070#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000071
Guido van Rossuma6535fd2001-10-18 19:44:10 +000072#ifdef HAVE_GRP_H
73#include <grp.h>
74#endif
75
Barry Warsaw5676bd12003-01-07 20:57:09 +000076#ifdef HAVE_SYSEXITS_H
77#include <sysexits.h>
78#endif /* HAVE_SYSEXITS_H */
79
Anthony Baxter8a560de2004-10-13 15:30:56 +000080#ifdef HAVE_SYS_LOADAVG_H
81#include <sys/loadavg.h>
82#endif
83
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000084#ifdef HAVE_LANGINFO_H
85#include <langinfo.h>
86#endif
87
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000088#ifdef HAVE_SYS_SENDFILE_H
89#include <sys/sendfile.h>
90#endif
91
Benjamin Peterson94b580d2011-08-02 17:30:04 -050092#ifdef HAVE_SCHED_H
93#include <sched.h>
94#endif
95
Benjamin Peterson2dbda072012-03-16 10:12:55 -050096#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050097#undef HAVE_SCHED_SETAFFINITY
98#endif
99
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +0200100#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -0400101#define USE_XATTRS
102#endif
103
104#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400105#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400106#endif
107
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000108#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
109#ifdef HAVE_SYS_SOCKET_H
110#include <sys/socket.h>
111#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000112#endif
113
Victor Stinner8b905bd2011-10-25 13:34:04 +0200114#ifdef HAVE_DLFCN_H
115#include <dlfcn.h>
116#endif
117
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200118#ifdef __hpux
119#include <sys/mpctl.h>
120#endif
121
122#if defined(__DragonFly__) || \
123 defined(__OpenBSD__) || \
124 defined(__FreeBSD__) || \
125 defined(__NetBSD__) || \
126 defined(__APPLE__)
127#include <sys/sysctl.h>
128#endif
129
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100130#if defined(MS_WINDOWS)
131# define TERMSIZE_USE_CONIO
132#elif defined(HAVE_SYS_IOCTL_H)
133# include <sys/ioctl.h>
134# if defined(HAVE_TERMIOS_H)
135# include <termios.h>
136# endif
137# if defined(TIOCGWINSZ)
138# define TERMSIZE_USE_IOCTL
139# endif
140#endif /* MS_WINDOWS */
141
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000142/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000143/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000146#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000147#include <process.h>
148#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000149#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000150#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000151#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000152#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000153#define HAVE_EXECV 1
154#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000155#define HAVE_SYSTEM 1
156#define HAVE_CWAIT 1
157#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000158#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000159#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000160/* Unix functions that the configure script doesn't check for */
161#define HAVE_EXECV 1
162#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000163#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000164#define HAVE_FORK1 1
165#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000166#define HAVE_GETEGID 1
167#define HAVE_GETEUID 1
168#define HAVE_GETGID 1
169#define HAVE_GETPPID 1
170#define HAVE_GETUID 1
171#define HAVE_KILL 1
172#define HAVE_OPENDIR 1
173#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000176#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000177#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000178#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000179
Victor Stinnera2f7c002012-02-08 03:36:25 +0100180
Larry Hastings61272b72014-01-07 12:41:53 -0800181/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000182# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800183module os
Larry Hastings61272b72014-01-07 12:41:53 -0800184[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000185/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100186
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000187#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000188
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000189#if defined(__sgi)&&_COMPILER_VERSION>=700
190/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
191 (default) */
192extern char *ctermid_r(char *);
193#endif
194
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000195#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000197extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000198#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000199#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000202extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000203#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000204#endif
205#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000206extern int chdir(char *);
207extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000208#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000209extern int chdir(const char *);
210extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000211#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000212extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000213/*#ifdef HAVE_FCHMOD
214extern int fchmod(int, mode_t);
215#endif*/
216/*#ifdef HAVE_LCHMOD
217extern int lchmod(const char *, mode_t);
218#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000219extern int chown(const char *, uid_t, gid_t);
220extern char *getcwd(char *, int);
221extern char *strerror(int);
222extern int link(const char *, const char *);
223extern int rename(const char *, const char *);
224extern int stat(const char *, struct stat *);
225extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000226#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000227extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000228#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000229#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000230extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000231#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000232#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000233
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000234#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000235
Guido van Rossumb6775db1994-08-01 11:34:53 +0000236#ifdef HAVE_UTIME_H
237#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000238#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000239
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000240#ifdef HAVE_SYS_UTIME_H
241#include <sys/utime.h>
242#define HAVE_UTIME_H /* pretend we do for the rest of this file */
243#endif /* HAVE_SYS_UTIME_H */
244
Guido van Rossumb6775db1994-08-01 11:34:53 +0000245#ifdef HAVE_SYS_TIMES_H
246#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000247#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000248
249#ifdef HAVE_SYS_PARAM_H
250#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000251#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000252
253#ifdef HAVE_SYS_UTSNAME_H
254#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000255#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000258#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000259#define NAMLEN(dirent) strlen((dirent)->d_name)
260#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000261#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000262#include <direct.h>
263#define NAMLEN(dirent) strlen((dirent)->d_name)
264#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000265#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000267#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000269#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000270#endif
271#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000272#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000273#endif
274#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000275#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000276#endif
277#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000278
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000279#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000280#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000281#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000282#endif
283#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000284#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000285#endif
286#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000287#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000288#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000289#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000290#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000291#endif
292#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000293#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000294#endif
295#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000296#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000297#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100298#ifndef IO_REPARSE_TAG_MOUNT_POINT
299#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
300#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000301#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000302#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000303#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000304#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000305#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000306#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
307#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000308static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000309#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000310#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000311
Tim Petersbc2e10e2002-03-03 23:17:02 +0000312#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000313#if defined(PATH_MAX) && PATH_MAX > 1024
314#define MAXPATHLEN PATH_MAX
315#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000317#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000318#endif /* MAXPATHLEN */
319
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000320#ifdef UNION_WAIT
321/* Emulate some macros on systems that have a union instead of macros */
322
323#ifndef WIFEXITED
324#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
325#endif
326
327#ifndef WEXITSTATUS
328#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
329#endif
330
331#ifndef WTERMSIG
332#define WTERMSIG(u_wait) ((u_wait).w_termsig)
333#endif
334
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000335#define WAIT_TYPE union wait
336#define WAIT_STATUS_INT(s) (s.w_status)
337
338#else /* !UNION_WAIT */
339#define WAIT_TYPE int
340#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000341#endif /* UNION_WAIT */
342
Greg Wardb48bc172000-03-01 21:51:56 +0000343/* Don't use the "_r" form if we don't need it (also, won't have a
344 prototype for it, at least on Solaris -- maybe others as well?). */
345#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
346#define USE_CTERMID_R
347#endif
348
Fred Drake699f3522000-06-29 21:12:41 +0000349/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000350#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000351#undef FSTAT
352#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200353#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000354# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700355# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200356# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800357# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000358#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700360# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000361# define FSTAT fstat
362# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000363#endif
364
Tim Peters11b23062003-04-23 02:39:17 +0000365#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000366#include <sys/mkdev.h>
367#else
368#if defined(MAJOR_IN_SYSMACROS)
369#include <sys/sysmacros.h>
370#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000371#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
372#include <sys/mkdev.h>
373#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000374#endif
Fred Drake699f3522000-06-29 21:12:41 +0000375
Victor Stinner6edddfa2013-11-24 19:22:57 +0100376#define DWORD_MAX 4294967295U
377
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200378#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100379#define INITFUNC PyInit_nt
380#define MODNAME "nt"
381#else
382#define INITFUNC PyInit_posix
383#define MODNAME "posix"
384#endif
385
386#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200387/* defined in fileutils.c */
388PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
389PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
390 ULONG, struct _Py_stat_struct *);
391#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700392
393#ifdef MS_WINDOWS
394static int
395win32_warn_bytes_api()
396{
397 return PyErr_WarnEx(PyExc_DeprecationWarning,
398 "The Windows bytes API has been deprecated, "
399 "use Unicode filenames instead",
400 1);
401}
402#endif
403
404
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200405#ifndef MS_WINDOWS
406PyObject *
407_PyLong_FromUid(uid_t uid)
408{
409 if (uid == (uid_t)-1)
410 return PyLong_FromLong(-1);
411 return PyLong_FromUnsignedLong(uid);
412}
413
414PyObject *
415_PyLong_FromGid(gid_t gid)
416{
417 if (gid == (gid_t)-1)
418 return PyLong_FromLong(-1);
419 return PyLong_FromUnsignedLong(gid);
420}
421
422int
423_Py_Uid_Converter(PyObject *obj, void *p)
424{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700425 uid_t uid;
426 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200427 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200428 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700429 unsigned long uresult;
430
431 index = PyNumber_Index(obj);
432 if (index == NULL) {
433 PyErr_Format(PyExc_TypeError,
434 "uid should be integer, not %.200s",
435 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200436 return 0;
437 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700438
439 /*
440 * Handling uid_t is complicated for two reasons:
441 * * Although uid_t is (always?) unsigned, it still
442 * accepts -1.
443 * * We don't know its size in advance--it may be
444 * bigger than an int, or it may be smaller than
445 * a long.
446 *
447 * So a bit of defensive programming is in order.
448 * Start with interpreting the value passed
449 * in as a signed long and see if it works.
450 */
451
452 result = PyLong_AsLongAndOverflow(index, &overflow);
453
454 if (!overflow) {
455 uid = (uid_t)result;
456
457 if (result == -1) {
458 if (PyErr_Occurred())
459 goto fail;
460 /* It's a legitimate -1, we're done. */
461 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200462 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700463
464 /* Any other negative number is disallowed. */
465 if (result < 0)
466 goto underflow;
467
468 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200469 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700470 (long)uid != result)
471 goto underflow;
472 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200473 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700474
475 if (overflow < 0)
476 goto underflow;
477
478 /*
479 * Okay, the value overflowed a signed long. If it
480 * fits in an *unsigned* long, it may still be okay,
481 * as uid_t may be unsigned long on this platform.
482 */
483 uresult = PyLong_AsUnsignedLong(index);
484 if (PyErr_Occurred()) {
485 if (PyErr_ExceptionMatches(PyExc_OverflowError))
486 goto overflow;
487 goto fail;
488 }
489
490 uid = (uid_t)uresult;
491
492 /*
493 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
494 * but this value would get interpreted as (uid_t)-1 by chown
495 * and its siblings. That's not what the user meant! So we
496 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100497 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700498 */
499 if (uid == (uid_t)-1)
500 goto overflow;
501
502 /* Ensure the value wasn't truncated. */
503 if (sizeof(uid_t) < sizeof(long) &&
504 (unsigned long)uid != uresult)
505 goto overflow;
506 /* fallthrough */
507
508success:
509 Py_DECREF(index);
510 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200511 return 1;
512
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200514 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700515 "uid is less than minimum");
516 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200519 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700520 "uid is greater than maximum");
521 /* fallthrough */
522
523fail:
524 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200525 return 0;
526}
527
528int
529_Py_Gid_Converter(PyObject *obj, void *p)
530{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700531 gid_t gid;
532 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200533 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200534 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700535 unsigned long uresult;
536
537 index = PyNumber_Index(obj);
538 if (index == NULL) {
539 PyErr_Format(PyExc_TypeError,
540 "gid should be integer, not %.200s",
541 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200542 return 0;
543 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700544
545 /*
546 * Handling gid_t is complicated for two reasons:
547 * * Although gid_t is (always?) unsigned, it still
548 * accepts -1.
549 * * We don't know its size in advance--it may be
550 * bigger than an int, or it may be smaller than
551 * a long.
552 *
553 * So a bit of defensive programming is in order.
554 * Start with interpreting the value passed
555 * in as a signed long and see if it works.
556 */
557
558 result = PyLong_AsLongAndOverflow(index, &overflow);
559
560 if (!overflow) {
561 gid = (gid_t)result;
562
563 if (result == -1) {
564 if (PyErr_Occurred())
565 goto fail;
566 /* It's a legitimate -1, we're done. */
567 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200568 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700569
570 /* Any other negative number is disallowed. */
571 if (result < 0) {
572 goto underflow;
573 }
574
575 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200576 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700577 (long)gid != result)
578 goto underflow;
579 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200580 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700581
582 if (overflow < 0)
583 goto underflow;
584
585 /*
586 * Okay, the value overflowed a signed long. If it
587 * fits in an *unsigned* long, it may still be okay,
588 * as gid_t may be unsigned long on this platform.
589 */
590 uresult = PyLong_AsUnsignedLong(index);
591 if (PyErr_Occurred()) {
592 if (PyErr_ExceptionMatches(PyExc_OverflowError))
593 goto overflow;
594 goto fail;
595 }
596
597 gid = (gid_t)uresult;
598
599 /*
600 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
601 * but this value would get interpreted as (gid_t)-1 by chown
602 * and its siblings. That's not what the user meant! So we
603 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100604 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700605 */
606 if (gid == (gid_t)-1)
607 goto overflow;
608
609 /* Ensure the value wasn't truncated. */
610 if (sizeof(gid_t) < sizeof(long) &&
611 (unsigned long)gid != uresult)
612 goto overflow;
613 /* fallthrough */
614
615success:
616 Py_DECREF(index);
617 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200618 return 1;
619
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200621 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700622 "gid is less than minimum");
623 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200626 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700627 "gid is greater than maximum");
628 /* fallthrough */
629
630fail:
631 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200632 return 0;
633}
634#endif /* MS_WINDOWS */
635
636
Gregory P. Smith702dada2015-01-28 16:07:52 -0800637#ifdef HAVE_LONG_LONG
638# define _PyLong_FromDev PyLong_FromLongLong
639#else
640# define _PyLong_FromDev PyLong_FromLong
641#endif
642
643
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200644#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
645static int
646_Py_Dev_Converter(PyObject *obj, void *p)
647{
648#ifdef HAVE_LONG_LONG
649 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
650#else
651 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
652#endif
653 if (PyErr_Occurred())
654 return 0;
655 return 1;
656}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800657#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200658
659
Larry Hastings9cf065c2012-06-22 16:30:09 -0700660#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400661/*
662 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
663 * without the int cast, the value gets interpreted as uint (4291925331),
664 * which doesn't play nicely with all the initializer lines in this file that
665 * look like this:
666 * int dir_fd = DEFAULT_DIR_FD;
667 */
668#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700669#else
670#define DEFAULT_DIR_FD (-100)
671#endif
672
673static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200674_fd_converter(PyObject *o, int *p, const char *allowed)
675{
676 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700677 long long_value;
678
679 PyObject *index = PyNumber_Index(o);
680 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200681 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700682 "argument should be %s, not %.200s",
683 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700684 return 0;
685 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700686
687 long_value = PyLong_AsLongAndOverflow(index, &overflow);
688 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200689 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700691 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700692 return 0;
693 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200694 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700696 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700697 return 0;
698 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700699
Larry Hastings9cf065c2012-06-22 16:30:09 -0700700 *p = (int)long_value;
701 return 1;
702}
703
704static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200705dir_fd_converter(PyObject *o, void *p)
706{
707 if (o == Py_None) {
708 *(int *)p = DEFAULT_DIR_FD;
709 return 1;
710 }
711 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700712}
713
714
Larry Hastings9cf065c2012-06-22 16:30:09 -0700715/*
716 * A PyArg_ParseTuple "converter" function
717 * that handles filesystem paths in the manner
718 * preferred by the os module.
719 *
720 * path_converter accepts (Unicode) strings and their
721 * subclasses, and bytes and their subclasses. What
722 * it does with the argument depends on the platform:
723 *
724 * * On Windows, if we get a (Unicode) string we
725 * extract the wchar_t * and return it; if we get
726 * bytes we extract the char * and return that.
727 *
728 * * On all other platforms, strings are encoded
729 * to bytes using PyUnicode_FSConverter, then we
730 * extract the char * from the bytes object and
731 * return that.
732 *
733 * path_converter also optionally accepts signed
734 * integers (representing open file descriptors) instead
735 * of path strings.
736 *
737 * Input fields:
738 * path.nullable
739 * If nonzero, the path is permitted to be None.
740 * path.allow_fd
741 * If nonzero, the path is permitted to be a file handle
742 * (a signed int) instead of a string.
743 * path.function_name
744 * If non-NULL, path_converter will use that as the name
745 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700746 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700747 * path.argument_name
748 * If non-NULL, path_converter will use that as the name
749 * of the parameter in error messages.
750 * (If path.argument_name is NULL it uses "path".)
751 *
752 * Output fields:
753 * path.wide
754 * Points to the path if it was expressed as Unicode
755 * and was not encoded. (Only used on Windows.)
756 * path.narrow
757 * Points to the path if it was expressed as bytes,
758 * or it was Unicode and was encoded to bytes.
759 * path.fd
760 * Contains a file descriptor if path.accept_fd was true
761 * and the caller provided a signed integer instead of any
762 * sort of string.
763 *
764 * WARNING: if your "path" parameter is optional, and is
765 * unspecified, path_converter will never get called.
766 * So if you set allow_fd, you *MUST* initialize path.fd = -1
767 * yourself!
768 * path.length
769 * The length of the path in characters, if specified as
770 * a string.
771 * path.object
772 * The original object passed in.
773 * path.cleanup
774 * For internal use only. May point to a temporary object.
775 * (Pay no attention to the man behind the curtain.)
776 *
777 * At most one of path.wide or path.narrow will be non-NULL.
778 * If path was None and path.nullable was set,
779 * or if path was an integer and path.allow_fd was set,
780 * both path.wide and path.narrow will be NULL
781 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200782 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700783 * path_converter takes care to not write to the path_t
784 * unless it's successful. However it must reset the
785 * "cleanup" field each time it's called.
786 *
787 * Use as follows:
788 * path_t path;
789 * memset(&path, 0, sizeof(path));
790 * PyArg_ParseTuple(args, "O&", path_converter, &path);
791 * // ... use values from path ...
792 * path_cleanup(&path);
793 *
794 * (Note that if PyArg_Parse fails you don't need to call
795 * path_cleanup(). However it is safe to do so.)
796 */
797typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100798 const char *function_name;
799 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700800 int nullable;
801 int allow_fd;
802 wchar_t *wide;
803 char *narrow;
804 int fd;
805 Py_ssize_t length;
806 PyObject *object;
807 PyObject *cleanup;
808} path_t;
809
Larry Hastings2f936352014-08-05 14:04:04 +1000810#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
811 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700812
Larry Hastings9cf065c2012-06-22 16:30:09 -0700813static void
814path_cleanup(path_t *path) {
815 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200816 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700817 }
818}
819
820static int
821path_converter(PyObject *o, void *p) {
822 path_t *path = (path_t *)p;
823 PyObject *unicode, *bytes;
824 Py_ssize_t length;
825 char *narrow;
826
827#define FORMAT_EXCEPTION(exc, fmt) \
828 PyErr_Format(exc, "%s%s" fmt, \
829 path->function_name ? path->function_name : "", \
830 path->function_name ? ": " : "", \
831 path->argument_name ? path->argument_name : "path")
832
833 /* Py_CLEANUP_SUPPORTED support */
834 if (o == NULL) {
835 path_cleanup(path);
836 return 1;
837 }
838
839 /* ensure it's always safe to call path_cleanup() */
840 path->cleanup = NULL;
841
842 if (o == Py_None) {
843 if (!path->nullable) {
844 FORMAT_EXCEPTION(PyExc_TypeError,
845 "can't specify None for %s argument");
846 return 0;
847 }
848 path->wide = NULL;
849 path->narrow = NULL;
850 path->length = 0;
851 path->object = o;
852 path->fd = -1;
853 return 1;
854 }
855
856 unicode = PyUnicode_FromObject(o);
857 if (unicode) {
858#ifdef MS_WINDOWS
859 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100860
861 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
862 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700863 Py_DECREF(unicode);
864 return 0;
865 }
Victor Stinner59799a82013-11-13 14:17:30 +0100866 if (length > 32767) {
867 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700868 Py_DECREF(unicode);
869 return 0;
870 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300871 if (wcslen(wide) != length) {
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +0300872 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300873 Py_DECREF(unicode);
874 return 0;
875 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700876
877 path->wide = wide;
878 path->narrow = NULL;
879 path->length = length;
880 path->object = o;
881 path->fd = -1;
882 path->cleanup = unicode;
883 return Py_CLEANUP_SUPPORTED;
884#else
885 int converted = PyUnicode_FSConverter(unicode, &bytes);
886 Py_DECREF(unicode);
887 if (!converted)
888 bytes = NULL;
889#endif
890 }
891 else {
892 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200893 if (PyObject_CheckBuffer(o))
894 bytes = PyBytes_FromObject(o);
895 else
896 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700897 if (!bytes) {
898 PyErr_Clear();
899 if (path->allow_fd) {
900 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200901 int result = _fd_converter(o, &fd,
902 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700903 if (result) {
904 path->wide = NULL;
905 path->narrow = NULL;
906 path->length = 0;
907 path->object = o;
908 path->fd = fd;
909 return result;
910 }
911 }
912 }
913 }
914
915 if (!bytes) {
916 if (!PyErr_Occurred())
917 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
918 return 0;
919 }
920
921#ifdef MS_WINDOWS
922 if (win32_warn_bytes_api()) {
923 Py_DECREF(bytes);
924 return 0;
925 }
926#endif
927
928 length = PyBytes_GET_SIZE(bytes);
929#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100930 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700931 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
932 Py_DECREF(bytes);
933 return 0;
934 }
935#endif
936
937 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200938 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300939 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700940 Py_DECREF(bytes);
941 return 0;
942 }
943
944 path->wide = NULL;
945 path->narrow = narrow;
946 path->length = length;
947 path->object = o;
948 path->fd = -1;
949 path->cleanup = bytes;
950 return Py_CLEANUP_SUPPORTED;
951}
952
953static void
954argument_unavailable_error(char *function_name, char *argument_name) {
955 PyErr_Format(PyExc_NotImplementedError,
956 "%s%s%s unavailable on this platform",
957 (function_name != NULL) ? function_name : "",
958 (function_name != NULL) ? ": ": "",
959 argument_name);
960}
961
962static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200963dir_fd_unavailable(PyObject *o, void *p)
964{
965 int dir_fd;
966 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200968 if (dir_fd != DEFAULT_DIR_FD) {
969 argument_unavailable_error(NULL, "dir_fd");
970 return 0;
971 }
972 *(int *)p = dir_fd;
973 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700974}
975
976static int
977fd_specified(char *function_name, int fd) {
978 if (fd == -1)
979 return 0;
980
981 argument_unavailable_error(function_name, "fd");
982 return 1;
983}
984
985static int
986follow_symlinks_specified(char *function_name, int follow_symlinks) {
987 if (follow_symlinks)
988 return 0;
989
990 argument_unavailable_error(function_name, "follow_symlinks");
991 return 1;
992}
993
994static int
995path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
996 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
997 PyErr_Format(PyExc_ValueError,
998 "%s: can't specify dir_fd without matching path",
999 function_name);
1000 return 1;
1001 }
1002 return 0;
1003}
1004
1005static int
1006dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
1007 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1008 PyErr_Format(PyExc_ValueError,
1009 "%s: can't specify both dir_fd and fd",
1010 function_name);
1011 return 1;
1012 }
1013 return 0;
1014}
1015
1016static int
1017fd_and_follow_symlinks_invalid(char *function_name, int fd,
1018 int follow_symlinks) {
1019 if ((fd > 0) && (!follow_symlinks)) {
1020 PyErr_Format(PyExc_ValueError,
1021 "%s: cannot use fd and follow_symlinks together",
1022 function_name);
1023 return 1;
1024 }
1025 return 0;
1026}
1027
1028static int
1029dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1030 int follow_symlinks) {
1031 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1032 PyErr_Format(PyExc_ValueError,
1033 "%s: cannot use dir_fd and follow_symlinks together",
1034 function_name);
1035 return 1;
1036 }
1037 return 0;
1038}
1039
Larry Hastings2f936352014-08-05 14:04:04 +10001040#ifdef MS_WINDOWS
1041 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001042#else
Larry Hastings2f936352014-08-05 14:04:04 +10001043 typedef off_t Py_off_t;
1044#endif
1045
1046static int
1047Py_off_t_converter(PyObject *arg, void *addr)
1048{
1049#ifdef HAVE_LARGEFILE_SUPPORT
1050 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1051#else
1052 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001053#endif
1054 if (PyErr_Occurred())
1055 return 0;
1056 return 1;
1057}
Larry Hastings2f936352014-08-05 14:04:04 +10001058
1059static PyObject *
1060PyLong_FromPy_off_t(Py_off_t offset)
1061{
1062#ifdef HAVE_LARGEFILE_SUPPORT
1063 return PyLong_FromLongLong(offset);
1064#else
1065 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001066#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001067}
1068
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001069
Steve Dowerd81431f2015-03-06 14:47:02 -08001070#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1071/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1072 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001074#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001075#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001076#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001077#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001078#define _NO_CONSOLE_FILENO (intptr_t)-2
1079
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001080/* the special case of checking dup2. The target fd must be in a sensible range */
1081static int
1082_PyVerify_fd_dup2(int fd1, int fd2)
1083{
Victor Stinner8c62be82010-05-06 00:08:46 +00001084 if (!_PyVerify_fd(fd1))
1085 return 0;
1086 if (fd2 == _NO_CONSOLE_FILENO)
1087 return 0;
1088 if ((unsigned)fd2 < _NHANDLE_)
1089 return 1;
1090 else
1091 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001092}
1093#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001094#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001095#endif
1096
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001097#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001098
1099static int
Brian Curtind25aef52011-06-13 15:16:04 -05001100win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001101{
1102 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1103 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1104 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001105
1106 if (0 == DeviceIoControl(
1107 reparse_point_handle,
1108 FSCTL_GET_REPARSE_POINT,
1109 NULL, 0, /* in buffer */
1110 target_buffer, sizeof(target_buffer),
1111 &n_bytes_returned,
1112 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001113 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001114
1115 if (reparse_tag)
1116 *reparse_tag = rdb->ReparseTag;
1117
Brian Curtind25aef52011-06-13 15:16:04 -05001118 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001119}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001120
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001121#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001122
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001123/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001124#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001125/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001126** environ directly, we must obtain it with _NSGetEnviron(). See also
1127** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001128*/
1129#include <crt_externs.h>
1130static char **environ;
1131#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001133#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001134
Barry Warsaw53699e91996-12-10 23:23:01 +00001135static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001136convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137{
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001139#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001140 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001141#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001142 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001143#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001144
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 d = PyDict_New();
1146 if (d == NULL)
1147 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001148#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001149 if (environ == NULL)
1150 environ = *_NSGetEnviron();
1151#endif
1152#ifdef MS_WINDOWS
1153 /* _wenviron must be initialized in this way if the program is started
1154 through main() instead of wmain(). */
1155 _wgetenv(L"");
1156 if (_wenviron == NULL)
1157 return d;
1158 /* This part ignores errors */
1159 for (e = _wenviron; *e != NULL; e++) {
1160 PyObject *k;
1161 PyObject *v;
1162 wchar_t *p = wcschr(*e, L'=');
1163 if (p == NULL)
1164 continue;
1165 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1166 if (k == NULL) {
1167 PyErr_Clear();
1168 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001169 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001170 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1171 if (v == NULL) {
1172 PyErr_Clear();
1173 Py_DECREF(k);
1174 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001175 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001176 if (PyDict_GetItem(d, k) == NULL) {
1177 if (PyDict_SetItem(d, k, v) != 0)
1178 PyErr_Clear();
1179 }
1180 Py_DECREF(k);
1181 Py_DECREF(v);
1182 }
1183#else
1184 if (environ == NULL)
1185 return d;
1186 /* This part ignores errors */
1187 for (e = environ; *e != NULL; e++) {
1188 PyObject *k;
1189 PyObject *v;
1190 char *p = strchr(*e, '=');
1191 if (p == NULL)
1192 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001193 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001194 if (k == NULL) {
1195 PyErr_Clear();
1196 continue;
1197 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001198 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 if (v == NULL) {
1200 PyErr_Clear();
1201 Py_DECREF(k);
1202 continue;
1203 }
1204 if (PyDict_GetItem(d, k) == NULL) {
1205 if (PyDict_SetItem(d, k, v) != 0)
1206 PyErr_Clear();
1207 }
1208 Py_DECREF(k);
1209 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001210 }
1211#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001212 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213}
1214
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001215/* Set a POSIX-specific error from errno, and return NULL */
1216
Barry Warsawd58d7641998-07-23 16:14:40 +00001217static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001218posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001219{
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001221}
Mark Hammondef8b6542001-05-13 08:04:26 +00001222
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001223#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001224static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001225win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001226{
Victor Stinner8c62be82010-05-06 00:08:46 +00001227 /* XXX We should pass the function name along in the future.
1228 (winreg.c also wants to pass the function name.)
1229 This would however require an additional param to the
1230 Windows error object, which is non-trivial.
1231 */
1232 errno = GetLastError();
1233 if (filename)
1234 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1235 else
1236 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001237}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001238
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001239static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001240win32_error_object(char* function, PyObject* filename)
1241{
1242 /* XXX - see win32_error for comments on 'function' */
1243 errno = GetLastError();
1244 if (filename)
1245 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001246 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001247 errno,
1248 filename);
1249 else
1250 return PyErr_SetFromWindowsErr(errno);
1251}
1252
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001253#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001254
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001256path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001257{
1258#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001259 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1260 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001261#else
Victor Stinner292c8352012-10-30 02:17:38 +01001262 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001263#endif
1264}
1265
Larry Hastings31826802013-10-19 00:09:25 -07001266
Larry Hastingsb0827312014-02-09 22:05:19 -08001267static PyObject *
1268path_error2(path_t *path, path_t *path2)
1269{
1270#ifdef MS_WINDOWS
1271 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1272 0, path->object, path2->object);
1273#else
1274 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1275 path->object, path2->object);
1276#endif
1277}
1278
1279
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001280/* POSIX generic methods */
1281
Larry Hastings2f936352014-08-05 14:04:04 +10001282static int
1283fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001284{
Victor Stinner8c62be82010-05-06 00:08:46 +00001285 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001286 int *pointer = (int *)p;
1287 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001288 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001289 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001290 *pointer = fd;
1291 return 1;
1292}
1293
1294static PyObject *
1295posix_fildes_fd(int fd, int (*func)(int))
1296{
1297 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001298 int async_err = 0;
1299
Steve Dower8fc89802015-04-12 00:26:27 -04001300 if (!_PyVerify_fd(fd))
1301 return posix_error();
1302
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001303 do {
1304 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001305 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001306 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001307 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001308 Py_END_ALLOW_THREADS
1309 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1310 if (res != 0)
1311 return (!async_err) ? posix_error() : NULL;
1312 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001313}
Guido van Rossum21142a01999-01-08 21:05:37 +00001314
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001315
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001316#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001317/* This is a reimplementation of the C library's chdir function,
1318 but one that produces Win32 errors instead of DOS error codes.
1319 chdir is essentially a wrapper around SetCurrentDirectory; however,
1320 it also needs to set "magic" environment variables indicating
1321 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001322static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001323win32_chdir(LPCSTR path)
1324{
Victor Stinner75875072013-11-24 19:23:25 +01001325 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001326 int result;
1327 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328
Victor Stinner8c62be82010-05-06 00:08:46 +00001329 if(!SetCurrentDirectoryA(path))
1330 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001331 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001332 if (!result)
1333 return FALSE;
1334 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001335 than MAX_PATH-1 (not including the final null character). */
1336 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001337 if (strncmp(new_path, "\\\\", 2) == 0 ||
1338 strncmp(new_path, "//", 2) == 0)
1339 /* UNC path, nothing to do. */
1340 return TRUE;
1341 env[1] = new_path[0];
1342 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001343}
1344
1345/* The Unicode version differs from the ANSI version
1346 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001347static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001348win32_wchdir(LPCWSTR path)
1349{
Victor Stinnered537822015-12-13 21:40:26 +01001350 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001351 int result;
1352 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001353
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 if(!SetCurrentDirectoryW(path))
1355 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001356 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001357 if (!result)
1358 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001359 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001360 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 if (!new_path) {
1362 SetLastError(ERROR_OUTOFMEMORY);
1363 return FALSE;
1364 }
1365 result = GetCurrentDirectoryW(result, new_path);
1366 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001367 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001368 return FALSE;
1369 }
1370 }
1371 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1372 wcsncmp(new_path, L"//", 2) == 0)
1373 /* UNC path, nothing to do. */
1374 return TRUE;
1375 env[1] = new_path[0];
1376 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001377 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001378 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001379 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001380}
1381#endif
1382
Martin v. Löwis14694662006-02-03 12:54:16 +00001383#ifdef MS_WINDOWS
1384/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1385 - time stamps are restricted to second resolution
1386 - file modification times suffer from forth-and-back conversions between
1387 UTC and local time
1388 Therefore, we implement our own stat, based on the Win32 API directly.
1389*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001390#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001391#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001392
Guido van Rossumd8faa362007-04-27 19:54:29 +00001393static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001394attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001395{
Victor Stinner8c62be82010-05-06 00:08:46 +00001396 HANDLE hFindFile;
1397 WIN32_FIND_DATAA FileData;
1398 hFindFile = FindFirstFileA(pszFile, &FileData);
1399 if (hFindFile == INVALID_HANDLE_VALUE)
1400 return FALSE;
1401 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001402 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001403 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001404 info->dwFileAttributes = FileData.dwFileAttributes;
1405 info->ftCreationTime = FileData.ftCreationTime;
1406 info->ftLastAccessTime = FileData.ftLastAccessTime;
1407 info->ftLastWriteTime = FileData.ftLastWriteTime;
1408 info->nFileSizeHigh = FileData.nFileSizeHigh;
1409 info->nFileSizeLow = FileData.nFileSizeLow;
1410/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001411 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1412 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001413 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001414}
1415
Victor Stinner6036e442015-03-08 01:58:04 +01001416static void
1417find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1418 BY_HANDLE_FILE_INFORMATION *info,
1419 ULONG *reparse_tag)
1420{
1421 memset(info, 0, sizeof(*info));
1422 info->dwFileAttributes = pFileData->dwFileAttributes;
1423 info->ftCreationTime = pFileData->ftCreationTime;
1424 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1425 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1426 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1427 info->nFileSizeLow = pFileData->nFileSizeLow;
1428/* info->nNumberOfLinks = 1; */
1429 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1430 *reparse_tag = pFileData->dwReserved0;
1431 else
1432 *reparse_tag = 0;
1433}
1434
Guido van Rossumd8faa362007-04-27 19:54:29 +00001435static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001436attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001437{
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 HANDLE hFindFile;
1439 WIN32_FIND_DATAW FileData;
1440 hFindFile = FindFirstFileW(pszFile, &FileData);
1441 if (hFindFile == INVALID_HANDLE_VALUE)
1442 return FALSE;
1443 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001444 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001445 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001446}
1447
Brian Curtind25aef52011-06-13 15:16:04 -05001448static BOOL
1449get_target_path(HANDLE hdl, wchar_t **target_path)
1450{
1451 int buf_size, result_length;
1452 wchar_t *buf;
1453
1454 /* We have a good handle to the target, use it to determine
1455 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001456 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1457 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001458 if(!buf_size)
1459 return FALSE;
1460
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001461 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001462 if (!buf) {
1463 SetLastError(ERROR_OUTOFMEMORY);
1464 return FALSE;
1465 }
1466
Steve Dower2ea51c92015-03-20 21:49:12 -07001467 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001468 buf, buf_size, VOLUME_NAME_DOS);
1469
1470 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001471 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001472 return FALSE;
1473 }
1474
1475 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001476 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001477 return FALSE;
1478 }
1479
1480 buf[result_length] = 0;
1481
1482 *target_path = buf;
1483 return TRUE;
1484}
1485
1486static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001487win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001488 BOOL traverse);
1489static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001490win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001491 BOOL traverse)
1492{
Victor Stinner26de69d2011-06-17 15:15:38 +02001493 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001494 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001495 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001496 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001497 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001498 const char *dot;
1499
1500 hFile = CreateFileA(
1501 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001502 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001503 0, /* share mode */
1504 NULL, /* security attributes */
1505 OPEN_EXISTING,
1506 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001507 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1508 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001509 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001510 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1511 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001512 NULL);
1513
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001514 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001515 /* Either the target doesn't exist, or we don't have access to
1516 get a handle to it. If the former, we need to return an error.
1517 If the latter, we can use attributes_from_dir. */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001518 DWORD lastError = GetLastError();
1519 if (lastError != ERROR_ACCESS_DENIED &&
1520 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001521 return -1;
1522 /* Could not get attributes on open file. Fall back to
1523 reading the directory. */
1524 if (!attributes_from_dir(path, &info, &reparse_tag))
1525 /* Very strange. This should not fail now */
1526 return -1;
1527 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1528 if (traverse) {
1529 /* Should traverse, but could not open reparse point handle */
Berker Peksag0b4dc482016-09-17 15:49:59 +03001530 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001531 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001532 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001534 } else {
1535 if (!GetFileInformationByHandle(hFile, &info)) {
1536 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001537 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001538 }
1539 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001540 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1541 return -1;
1542
1543 /* Close the outer open file handle now that we're about to
1544 reopen it with different flags. */
1545 if (!CloseHandle(hFile))
1546 return -1;
1547
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001548 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001549 /* In order to call GetFinalPathNameByHandle we need to open
1550 the file without the reparse handling flag set. */
1551 hFile2 = CreateFileA(
1552 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1553 NULL, OPEN_EXISTING,
1554 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1555 NULL);
1556 if (hFile2 == INVALID_HANDLE_VALUE)
1557 return -1;
1558
1559 if (!get_target_path(hFile2, &target_path))
1560 return -1;
1561
1562 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001563 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001564 return code;
1565 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001566 } else
1567 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001568 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001569 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001570
1571 /* Set S_IEXEC if it is an .exe, .bat, ... */
1572 dot = strrchr(path, '.');
1573 if (dot) {
1574 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1575 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1576 result->st_mode |= 0111;
1577 }
1578 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001579}
1580
1581static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001582win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001583 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001584{
1585 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001586 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001587 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001588 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001589 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001590 const wchar_t *dot;
1591
1592 hFile = CreateFileW(
1593 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001594 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 0, /* share mode */
1596 NULL, /* security attributes */
1597 OPEN_EXISTING,
1598 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001599 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1600 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001601 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001602 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001603 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001604 NULL);
1605
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001606 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607 /* Either the target doesn't exist, or we don't have access to
1608 get a handle to it. If the former, we need to return an error.
1609 If the latter, we can use attributes_from_dir. */
Berker Peksagbf3c1c32016-09-18 13:56:29 +03001610 DWORD lastError = GetLastError();
1611 if (lastError != ERROR_ACCESS_DENIED &&
1612 lastError != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001613 return -1;
1614 /* Could not get attributes on open file. Fall back to
1615 reading the directory. */
1616 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1617 /* Very strange. This should not fail now */
1618 return -1;
1619 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1620 if (traverse) {
1621 /* Should traverse, but could not open reparse point handle */
Berker Peksagbf3c1c32016-09-18 13:56:29 +03001622 SetLastError(lastError);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001623 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001624 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001626 } else {
1627 if (!GetFileInformationByHandle(hFile, &info)) {
1628 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001629 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001630 }
1631 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001632 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1633 return -1;
1634
1635 /* Close the outer open file handle now that we're about to
1636 reopen it with different flags. */
1637 if (!CloseHandle(hFile))
1638 return -1;
1639
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001640 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001641 /* In order to call GetFinalPathNameByHandle we need to open
1642 the file without the reparse handling flag set. */
1643 hFile2 = CreateFileW(
1644 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1645 NULL, OPEN_EXISTING,
1646 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1647 NULL);
1648 if (hFile2 == INVALID_HANDLE_VALUE)
1649 return -1;
1650
1651 if (!get_target_path(hFile2, &target_path))
1652 return -1;
1653
1654 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001655 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001656 return code;
1657 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001658 } else
1659 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001661 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001662
1663 /* Set S_IEXEC if it is an .exe, .bat, ... */
1664 dot = wcsrchr(path, '.');
1665 if (dot) {
1666 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1667 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1668 result->st_mode |= 0111;
1669 }
1670 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671}
1672
1673static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001674win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001675{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001676 /* Protocol violation: we explicitly clear errno, instead of
1677 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001678 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679 errno = 0;
1680 return code;
1681}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001682
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001684win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001685{
1686 /* Protocol violation: we explicitly clear errno, instead of
1687 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001688 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001689 errno = 0;
1690 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001691}
Brian Curtind25aef52011-06-13 15:16:04 -05001692/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001693
1694 In Posix, stat automatically traverses symlinks and returns the stat
1695 structure for the target. In Windows, the equivalent GetFileAttributes by
1696 default does not traverse symlinks and instead returns attributes for
1697 the symlink.
1698
1699 Therefore, win32_lstat will get the attributes traditionally, and
1700 win32_stat will first explicitly resolve the symlink target and then will
1701 call win32_lstat on that result.
1702
Ezio Melotti4969f702011-03-15 05:59:46 +02001703 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001704
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001705static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001706win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001707{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001708 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001709}
1710
Victor Stinner8c62be82010-05-06 00:08:46 +00001711static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001712win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001713{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001715}
1716
1717static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001718win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001719{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001721}
1722
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001723static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001724win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001725{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001726 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001727}
1728
Martin v. Löwis14694662006-02-03 12:54:16 +00001729#endif /* MS_WINDOWS */
1730
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001731PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001732"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001733This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001734 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001735or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1736\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001737Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1738or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001739\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001740See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001741
1742static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001743 {"st_mode", "protection bits"},
1744 {"st_ino", "inode"},
1745 {"st_dev", "device"},
1746 {"st_nlink", "number of hard links"},
1747 {"st_uid", "user ID of owner"},
1748 {"st_gid", "group ID of owner"},
1749 {"st_size", "total size, in bytes"},
1750 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1751 {NULL, "integer time of last access"},
1752 {NULL, "integer time of last modification"},
1753 {NULL, "integer time of last change"},
1754 {"st_atime", "time of last access"},
1755 {"st_mtime", "time of last modification"},
1756 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001757 {"st_atime_ns", "time of last access in nanoseconds"},
1758 {"st_mtime_ns", "time of last modification in nanoseconds"},
1759 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001760#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001763#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001765#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001766#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001768#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001769#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001771#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001772#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001773 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001774#endif
1775#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001776 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001777#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001778#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1779 {"st_file_attributes", "Windows file attribute bits"},
1780#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001781 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782};
1783
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001785#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001787#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001788#endif
1789
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1792#else
1793#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1794#endif
1795
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001796#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001797#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1798#else
1799#define ST_RDEV_IDX ST_BLOCKS_IDX
1800#endif
1801
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001802#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1803#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1804#else
1805#define ST_FLAGS_IDX ST_RDEV_IDX
1806#endif
1807
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001808#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001809#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001810#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001811#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001812#endif
1813
1814#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1815#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1816#else
1817#define ST_BIRTHTIME_IDX ST_GEN_IDX
1818#endif
1819
Zachary Ware63f277b2014-06-19 09:46:37 -05001820#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1821#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1822#else
1823#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1824#endif
1825
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001826static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001827 "stat_result", /* name */
1828 stat_result__doc__, /* doc */
1829 stat_result_fields,
1830 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001831};
1832
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1835This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001836 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001837or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001838\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001839See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001840
1841static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001842 {"f_bsize", },
1843 {"f_frsize", },
1844 {"f_blocks", },
1845 {"f_bfree", },
1846 {"f_bavail", },
1847 {"f_files", },
1848 {"f_ffree", },
1849 {"f_favail", },
1850 {"f_flag", },
1851 {"f_namemax",},
1852 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001853};
1854
1855static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001856 "statvfs_result", /* name */
1857 statvfs_result__doc__, /* doc */
1858 statvfs_result_fields,
1859 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001860};
1861
Ross Lagerwall7807c352011-03-17 20:20:30 +02001862#if defined(HAVE_WAITID) && !defined(__APPLE__)
1863PyDoc_STRVAR(waitid_result__doc__,
1864"waitid_result: Result from waitid.\n\n\
1865This object may be accessed either as a tuple of\n\
1866 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1867or via the attributes si_pid, si_uid, and so on.\n\
1868\n\
1869See os.waitid for more information.");
1870
1871static PyStructSequence_Field waitid_result_fields[] = {
1872 {"si_pid", },
1873 {"si_uid", },
1874 {"si_signo", },
1875 {"si_status", },
1876 {"si_code", },
1877 {0}
1878};
1879
1880static PyStructSequence_Desc waitid_result_desc = {
1881 "waitid_result", /* name */
1882 waitid_result__doc__, /* doc */
1883 waitid_result_fields,
1884 5
1885};
1886static PyTypeObject WaitidResultType;
1887#endif
1888
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001889static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001890static PyTypeObject StatResultType;
1891static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001892#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001893static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001894#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001895static newfunc structseq_new;
1896
1897static PyObject *
1898statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1899{
Victor Stinner8c62be82010-05-06 00:08:46 +00001900 PyStructSequence *result;
1901 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001902
Victor Stinner8c62be82010-05-06 00:08:46 +00001903 result = (PyStructSequence*)structseq_new(type, args, kwds);
1904 if (!result)
1905 return NULL;
1906 /* If we have been initialized from a tuple,
1907 st_?time might be set to None. Initialize it
1908 from the int slots. */
1909 for (i = 7; i <= 9; i++) {
1910 if (result->ob_item[i+3] == Py_None) {
1911 Py_DECREF(Py_None);
1912 Py_INCREF(result->ob_item[i]);
1913 result->ob_item[i+3] = result->ob_item[i];
1914 }
1915 }
1916 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001917}
1918
1919
1920
1921/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001922static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001923
1924PyDoc_STRVAR(stat_float_times__doc__,
1925"stat_float_times([newval]) -> oldval\n\n\
1926Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001927\n\
1928If value is True, future calls to stat() return floats; if it is False,\n\
1929future calls return ints.\n\
1930If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001931
Larry Hastings2f936352014-08-05 14:04:04 +10001932/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001933static PyObject*
1934stat_float_times(PyObject* self, PyObject *args)
1935{
Victor Stinner8c62be82010-05-06 00:08:46 +00001936 int newval = -1;
1937 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1938 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001939 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1940 "stat_float_times() is deprecated",
1941 1))
1942 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001943 if (newval == -1)
1944 /* Return old value */
1945 return PyBool_FromLong(_stat_float_times);
1946 _stat_float_times = newval;
1947 Py_INCREF(Py_None);
1948 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001949}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001950
Larry Hastings6fe20b32012-04-19 15:07:49 -07001951static PyObject *billion = NULL;
1952
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001953static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001954fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001955{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001956 PyObject *s = _PyLong_FromTime_t(sec);
1957 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1958 PyObject *s_in_ns = NULL;
1959 PyObject *ns_total = NULL;
1960 PyObject *float_s = NULL;
1961
1962 if (!(s && ns_fractional))
1963 goto exit;
1964
1965 s_in_ns = PyNumber_Multiply(s, billion);
1966 if (!s_in_ns)
1967 goto exit;
1968
1969 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1970 if (!ns_total)
1971 goto exit;
1972
Victor Stinner4195b5c2012-02-08 23:03:19 +01001973 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001974 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1975 if (!float_s)
1976 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001977 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001978 else {
1979 float_s = s;
1980 Py_INCREF(float_s);
1981 }
1982
1983 PyStructSequence_SET_ITEM(v, index, s);
1984 PyStructSequence_SET_ITEM(v, index+3, float_s);
1985 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1986 s = NULL;
1987 float_s = NULL;
1988 ns_total = NULL;
1989exit:
1990 Py_XDECREF(s);
1991 Py_XDECREF(ns_fractional);
1992 Py_XDECREF(s_in_ns);
1993 Py_XDECREF(ns_total);
1994 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001995}
1996
Tim Peters5aa91602002-01-30 05:46:57 +00001997/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001998 (used by posix_stat() and posix_fstat()) */
1999static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002000_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002001{
Victor Stinner8c62be82010-05-06 00:08:46 +00002002 unsigned long ansec, mnsec, cnsec;
2003 PyObject *v = PyStructSequence_New(&StatResultType);
2004 if (v == NULL)
2005 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002006
Victor Stinner8c62be82010-05-06 00:08:46 +00002007 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002008#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002009 PyStructSequence_SET_ITEM(v, 1,
2010 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002011#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002012 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002013#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002014#ifdef MS_WINDOWS
2015 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002016#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002017 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002018#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002019 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002020#if defined(MS_WINDOWS)
2021 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2022 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2023#else
2024 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2025 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2026#endif
Fred Drake699f3522000-06-29 21:12:41 +00002027#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002028 PyStructSequence_SET_ITEM(v, 6,
2029 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002030#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002031 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002032#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002033
Martin v. Löwis14694662006-02-03 12:54:16 +00002034#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002035 ansec = st->st_atim.tv_nsec;
2036 mnsec = st->st_mtim.tv_nsec;
2037 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002038#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002039 ansec = st->st_atimespec.tv_nsec;
2040 mnsec = st->st_mtimespec.tv_nsec;
2041 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002042#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002043 ansec = st->st_atime_nsec;
2044 mnsec = st->st_mtime_nsec;
2045 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002046#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002048#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002049 fill_time(v, 7, st->st_atime, ansec);
2050 fill_time(v, 8, st->st_mtime, mnsec);
2051 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002052
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002053#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002054 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2055 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002056#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002057#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002058 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2059 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002060#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002061#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002062 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2063 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002064#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002066 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2067 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002068#endif
2069#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002070 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002071 PyObject *val;
2072 unsigned long bsec,bnsec;
2073 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002074#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002075 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002077 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002078#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002079 if (_stat_float_times) {
2080 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2081 } else {
2082 val = PyLong_FromLong((long)bsec);
2083 }
2084 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2085 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002087#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002088#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002089 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2090 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002091#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002092#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2093 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2094 PyLong_FromUnsignedLong(st->st_file_attributes));
2095#endif
Fred Drake699f3522000-06-29 21:12:41 +00002096
Victor Stinner8c62be82010-05-06 00:08:46 +00002097 if (PyErr_Occurred()) {
2098 Py_DECREF(v);
2099 return NULL;
2100 }
Fred Drake699f3522000-06-29 21:12:41 +00002101
Victor Stinner8c62be82010-05-06 00:08:46 +00002102 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002103}
2104
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002105/* POSIX methods */
2106
Guido van Rossum94f6f721999-01-06 18:42:14 +00002107
2108static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002109posix_do_stat(char *function_name, path_t *path,
2110 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002111{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002112 STRUCT_STAT st;
2113 int result;
2114
2115#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2116 if (follow_symlinks_specified(function_name, follow_symlinks))
2117 return NULL;
2118#endif
2119
2120 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2121 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2122 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2123 return NULL;
2124
2125 Py_BEGIN_ALLOW_THREADS
2126 if (path->fd != -1)
2127 result = FSTAT(path->fd, &st);
2128 else
2129#ifdef MS_WINDOWS
2130 if (path->wide) {
2131 if (follow_symlinks)
2132 result = win32_stat_w(path->wide, &st);
2133 else
2134 result = win32_lstat_w(path->wide, &st);
2135 }
2136 else
2137#endif
2138#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2139 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2140 result = LSTAT(path->narrow, &st);
2141 else
2142#endif
2143#ifdef HAVE_FSTATAT
2144 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2145 result = fstatat(dir_fd, path->narrow, &st,
2146 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2147 else
2148#endif
2149 result = STAT(path->narrow, &st);
2150 Py_END_ALLOW_THREADS
2151
Victor Stinner292c8352012-10-30 02:17:38 +01002152 if (result != 0) {
2153 return path_error(path);
2154 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002155
2156 return _pystat_fromstructstat(&st);
2157}
2158
Larry Hastings2f936352014-08-05 14:04:04 +10002159/*[python input]
2160
2161for s in """
2162
2163FACCESSAT
2164FCHMODAT
2165FCHOWNAT
2166FSTATAT
2167LINKAT
2168MKDIRAT
2169MKFIFOAT
2170MKNODAT
2171OPENAT
2172READLINKAT
2173SYMLINKAT
2174UNLINKAT
2175
2176""".strip().split():
2177 s = s.strip()
2178 print("""
2179#ifdef HAVE_{s}
2180 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002181#else
Larry Hastings2f936352014-08-05 14:04:04 +10002182 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002183#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002184""".rstrip().format(s=s))
2185
2186for s in """
2187
2188FCHDIR
2189FCHMOD
2190FCHOWN
2191FDOPENDIR
2192FEXECVE
2193FPATHCONF
2194FSTATVFS
2195FTRUNCATE
2196
2197""".strip().split():
2198 s = s.strip()
2199 print("""
2200#ifdef HAVE_{s}
2201 #define PATH_HAVE_{s} 1
2202#else
2203 #define PATH_HAVE_{s} 0
2204#endif
2205
2206""".rstrip().format(s=s))
2207[python start generated code]*/
2208
2209#ifdef HAVE_FACCESSAT
2210 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2211#else
2212 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2213#endif
2214
2215#ifdef HAVE_FCHMODAT
2216 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2217#else
2218 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2219#endif
2220
2221#ifdef HAVE_FCHOWNAT
2222 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2223#else
2224 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2225#endif
2226
2227#ifdef HAVE_FSTATAT
2228 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2229#else
2230 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2231#endif
2232
2233#ifdef HAVE_LINKAT
2234 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2235#else
2236 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2237#endif
2238
2239#ifdef HAVE_MKDIRAT
2240 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2241#else
2242 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2243#endif
2244
2245#ifdef HAVE_MKFIFOAT
2246 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_MKNODAT
2252 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_OPENAT
2258 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_READLINKAT
2264 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_SYMLINKAT
2270 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2271#else
2272 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2273#endif
2274
2275#ifdef HAVE_UNLINKAT
2276 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2277#else
2278 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2279#endif
2280
2281#ifdef HAVE_FCHDIR
2282 #define PATH_HAVE_FCHDIR 1
2283#else
2284 #define PATH_HAVE_FCHDIR 0
2285#endif
2286
2287#ifdef HAVE_FCHMOD
2288 #define PATH_HAVE_FCHMOD 1
2289#else
2290 #define PATH_HAVE_FCHMOD 0
2291#endif
2292
2293#ifdef HAVE_FCHOWN
2294 #define PATH_HAVE_FCHOWN 1
2295#else
2296 #define PATH_HAVE_FCHOWN 0
2297#endif
2298
2299#ifdef HAVE_FDOPENDIR
2300 #define PATH_HAVE_FDOPENDIR 1
2301#else
2302 #define PATH_HAVE_FDOPENDIR 0
2303#endif
2304
2305#ifdef HAVE_FEXECVE
2306 #define PATH_HAVE_FEXECVE 1
2307#else
2308 #define PATH_HAVE_FEXECVE 0
2309#endif
2310
2311#ifdef HAVE_FPATHCONF
2312 #define PATH_HAVE_FPATHCONF 1
2313#else
2314 #define PATH_HAVE_FPATHCONF 0
2315#endif
2316
2317#ifdef HAVE_FSTATVFS
2318 #define PATH_HAVE_FSTATVFS 1
2319#else
2320 #define PATH_HAVE_FSTATVFS 0
2321#endif
2322
2323#ifdef HAVE_FTRUNCATE
2324 #define PATH_HAVE_FTRUNCATE 1
2325#else
2326 #define PATH_HAVE_FTRUNCATE 0
2327#endif
2328/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002329
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002330#ifdef MS_WINDOWS
2331 #undef PATH_HAVE_FTRUNCATE
2332 #define PATH_HAVE_FTRUNCATE 1
2333#endif
Larry Hastings31826802013-10-19 00:09:25 -07002334
Larry Hastings61272b72014-01-07 12:41:53 -08002335/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002336
2337class path_t_converter(CConverter):
2338
2339 type = "path_t"
2340 impl_by_reference = True
2341 parse_by_reference = True
2342
2343 converter = 'path_converter'
2344
2345 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002346 # right now path_t doesn't support default values.
2347 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002348 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002349 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002350
Larry Hastings2f936352014-08-05 14:04:04 +10002351 if self.c_default not in (None, 'Py_None'):
2352 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002353
2354 self.nullable = nullable
2355 self.allow_fd = allow_fd
2356
Larry Hastings7726ac92014-01-31 22:03:12 -08002357 def pre_render(self):
2358 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002359 if isinstance(value, str):
2360 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002361 return str(int(bool(value)))
2362
2363 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002364 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002365 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002366 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002367 strify(self.nullable),
2368 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002369 )
2370
2371 def cleanup(self):
2372 return "path_cleanup(&" + self.name + ");\n"
2373
2374
2375class dir_fd_converter(CConverter):
2376 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002377
Larry Hastings2f936352014-08-05 14:04:04 +10002378 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002379 if self.default in (unspecified, None):
2380 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002381 if isinstance(requires, str):
2382 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2383 else:
2384 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002385
Larry Hastings2f936352014-08-05 14:04:04 +10002386class fildes_converter(CConverter):
2387 type = 'int'
2388 converter = 'fildes_converter'
2389
2390class uid_t_converter(CConverter):
2391 type = "uid_t"
2392 converter = '_Py_Uid_Converter'
2393
2394class gid_t_converter(CConverter):
2395 type = "gid_t"
2396 converter = '_Py_Gid_Converter'
2397
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002398class dev_t_converter(CConverter):
2399 type = 'dev_t'
2400 converter = '_Py_Dev_Converter'
2401
2402class dev_t_return_converter(unsigned_long_return_converter):
2403 type = 'dev_t'
2404 conversion_fn = '_PyLong_FromDev'
2405 unsigned_cast = '(dev_t)'
2406
Larry Hastings2f936352014-08-05 14:04:04 +10002407class FSConverter_converter(CConverter):
2408 type = 'PyObject *'
2409 converter = 'PyUnicode_FSConverter'
2410 def converter_init(self):
2411 if self.default is not unspecified:
2412 fail("FSConverter_converter does not support default values")
2413 self.c_default = 'NULL'
2414
2415 def cleanup(self):
2416 return "Py_XDECREF(" + self.name + ");\n"
2417
2418class pid_t_converter(CConverter):
2419 type = 'pid_t'
2420 format_unit = '" _Py_PARSE_PID "'
2421
2422class idtype_t_converter(int_converter):
2423 type = 'idtype_t'
2424
2425class id_t_converter(CConverter):
2426 type = 'id_t'
2427 format_unit = '" _Py_PARSE_PID "'
2428
2429class Py_intptr_t_converter(CConverter):
2430 type = 'Py_intptr_t'
2431 format_unit = '" _Py_PARSE_INTPTR "'
2432
2433class Py_off_t_converter(CConverter):
2434 type = 'Py_off_t'
2435 converter = 'Py_off_t_converter'
2436
2437class Py_off_t_return_converter(long_return_converter):
2438 type = 'Py_off_t'
2439 conversion_fn = 'PyLong_FromPy_off_t'
2440
2441class path_confname_converter(CConverter):
2442 type="int"
2443 converter="conv_path_confname"
2444
2445class confstr_confname_converter(path_confname_converter):
2446 converter='conv_confstr_confname'
2447
2448class sysconf_confname_converter(path_confname_converter):
2449 converter="conv_sysconf_confname"
2450
2451class sched_param_converter(CConverter):
2452 type = 'struct sched_param'
2453 converter = 'convert_sched_param'
2454 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002455
Larry Hastings61272b72014-01-07 12:41:53 -08002456[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002457/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002458
Larry Hastings61272b72014-01-07 12:41:53 -08002459/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002460
Larry Hastings2a727912014-01-16 11:32:01 -08002461os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002462
2463 path : path_t(allow_fd=True)
2464 Path to be examined; can be string, bytes, or open-file-descriptor int.
2465
2466 *
2467
Larry Hastings2f936352014-08-05 14:04:04 +10002468 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002469 If not None, it should be a file descriptor open to a directory,
2470 and path should be a relative string; path will then be relative to
2471 that directory.
2472
2473 follow_symlinks: bool = True
2474 If False, and the last element of the path is a symbolic link,
2475 stat will examine the symbolic link itself instead of the file
2476 the link points to.
2477
2478Perform a stat system call on the given path.
2479
2480dir_fd and follow_symlinks may not be implemented
2481 on your platform. If they are unavailable, using them will raise a
2482 NotImplementedError.
2483
2484It's an error to use dir_fd or follow_symlinks when specifying path as
2485 an open file descriptor.
2486
Larry Hastings61272b72014-01-07 12:41:53 -08002487[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002488
Larry Hastings31826802013-10-19 00:09:25 -07002489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002490os_stat_impl(PyObject *module, path_t *path, int dir_fd, int follow_symlinks)
2491/*[clinic end generated code: output=7d4976e6f18a59c5 input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002492{
2493 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2494}
2495
Larry Hastings2f936352014-08-05 14:04:04 +10002496
2497/*[clinic input]
2498os.lstat
2499
2500 path : path_t
2501
2502 *
2503
2504 dir_fd : dir_fd(requires='fstatat') = None
2505
2506Perform a stat system call on the given path, without following symbolic links.
2507
2508Like stat(), but do not follow symbolic links.
2509Equivalent to stat(path, follow_symlinks=False).
2510[clinic start generated code]*/
2511
Larry Hastings2f936352014-08-05 14:04:04 +10002512static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002513os_lstat_impl(PyObject *module, path_t *path, int dir_fd)
2514/*[clinic end generated code: output=ef82a5d35ce8ab37 input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002515{
2516 int follow_symlinks = 0;
2517 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2518}
Larry Hastings31826802013-10-19 00:09:25 -07002519
Larry Hastings2f936352014-08-05 14:04:04 +10002520
Larry Hastings61272b72014-01-07 12:41:53 -08002521/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002522os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002523
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002524 path: path_t
2525 Path to be tested; can be string or bytes
Larry Hastings31826802013-10-19 00:09:25 -07002526
2527 mode: int
2528 Operating-system mode bitfield. Can be F_OK to test existence,
2529 or the inclusive-OR of R_OK, W_OK, and X_OK.
2530
2531 *
2532
Larry Hastings2f936352014-08-05 14:04:04 +10002533 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002534 If not None, it should be a file descriptor open to a directory,
2535 and path should be relative; path will then be relative to that
2536 directory.
2537
2538 effective_ids: bool = False
2539 If True, access will use the effective uid/gid instead of
2540 the real uid/gid.
2541
2542 follow_symlinks: bool = True
2543 If False, and the last element of the path is a symbolic link,
2544 access will examine the symbolic link itself instead of the file
2545 the link points to.
2546
2547Use the real uid/gid to test for access to a path.
2548
2549{parameters}
2550dir_fd, effective_ids, and follow_symlinks may not be implemented
2551 on your platform. If they are unavailable, using them will raise a
2552 NotImplementedError.
2553
2554Note that most operations will use the effective uid/gid, therefore this
2555 routine can be used in a suid/sgid environment to test if the invoking user
2556 has the specified access to the path.
2557
Larry Hastings61272b72014-01-07 12:41:53 -08002558[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559
Larry Hastings2f936352014-08-05 14:04:04 +10002560static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002561os_access_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002562 int effective_ids, int follow_symlinks)
Benjamin Peterson768f3b42016-09-05 15:29:33 -07002563/*[clinic end generated code: output=cf84158bc90b1a77 input=8e8c3a6ba791fee3]*/
Larry Hastings31826802013-10-19 00:09:25 -07002564{
Larry Hastings2f936352014-08-05 14:04:04 +10002565 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002566
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002567#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002568 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002569#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002570 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002571#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572
Larry Hastings9cf065c2012-06-22 16:30:09 -07002573#ifndef HAVE_FACCESSAT
2574 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002575 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002576
2577 if (effective_ids) {
2578 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002579 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002580 }
2581#endif
2582
2583#ifdef MS_WINDOWS
2584 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002585 if (path->wide != NULL)
2586 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002587 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002588 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589 Py_END_ALLOW_THREADS
2590
2591 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002592 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002593 * * we didn't get a -1, and
2594 * * write access wasn't requested,
2595 * * or the file isn't read-only,
2596 * * or it's a directory.
2597 * (Directories cannot be read-only on Windows.)
2598 */
Larry Hastings2f936352014-08-05 14:04:04 +10002599 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002600 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002601 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002602 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603#else
2604
2605 Py_BEGIN_ALLOW_THREADS
2606#ifdef HAVE_FACCESSAT
2607 if ((dir_fd != DEFAULT_DIR_FD) ||
2608 effective_ids ||
2609 !follow_symlinks) {
2610 int flags = 0;
2611 if (!follow_symlinks)
2612 flags |= AT_SYMLINK_NOFOLLOW;
2613 if (effective_ids)
2614 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002615 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002616 }
2617 else
2618#endif
Larry Hastings31826802013-10-19 00:09:25 -07002619 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002620 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002621 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622#endif
2623
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002625}
2626
Guido van Rossumd371ff11999-01-25 16:12:23 +00002627#ifndef F_OK
2628#define F_OK 0
2629#endif
2630#ifndef R_OK
2631#define R_OK 4
2632#endif
2633#ifndef W_OK
2634#define W_OK 2
2635#endif
2636#ifndef X_OK
2637#define X_OK 1
2638#endif
2639
Larry Hastings31826802013-10-19 00:09:25 -07002640
Guido van Rossumd371ff11999-01-25 16:12:23 +00002641#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002642/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002643os.ttyname -> DecodeFSDefault
2644
2645 fd: int
2646 Integer file descriptor handle.
2647
2648 /
2649
2650Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002651[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002652
Larry Hastings31826802013-10-19 00:09:25 -07002653static char *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002654os_ttyname_impl(PyObject *module, int fd)
2655/*[clinic end generated code: output=ed16ad216d813591 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002656{
2657 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002658
Larry Hastings31826802013-10-19 00:09:25 -07002659 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002660 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002661 posix_error();
2662 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002663}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002664#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002666#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002667/*[clinic input]
2668os.ctermid
2669
2670Return the name of the controlling terminal for this process.
2671[clinic start generated code]*/
2672
Larry Hastings2f936352014-08-05 14:04:04 +10002673static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002674os_ctermid_impl(PyObject *module)
2675/*[clinic end generated code: output=02f017e6c9e620db input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002676{
Victor Stinner8c62be82010-05-06 00:08:46 +00002677 char *ret;
2678 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679
Greg Wardb48bc172000-03-01 21:51:56 +00002680#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002681 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002682#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 if (ret == NULL)
2686 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002687 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002688}
Larry Hastings2f936352014-08-05 14:04:04 +10002689#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690
Larry Hastings2f936352014-08-05 14:04:04 +10002691
2692/*[clinic input]
2693os.chdir
2694
2695 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2696
2697Change the current working directory to the specified path.
2698
2699path may always be specified as a string.
2700On some platforms, path may also be specified as an open file descriptor.
2701 If this functionality is unavailable, using it raises an exception.
2702[clinic start generated code]*/
2703
Larry Hastings2f936352014-08-05 14:04:04 +10002704static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002705os_chdir_impl(PyObject *module, path_t *path)
2706/*[clinic end generated code: output=3be6400eee26eaae input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002707{
2708 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709
2710 Py_BEGIN_ALLOW_THREADS
2711#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002712 if (path->wide)
2713 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002714 else
Larry Hastings2f936352014-08-05 14:04:04 +10002715 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002716 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717#else
2718#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002719 if (path->fd != -1)
2720 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002721 else
2722#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002723 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724#endif
2725 Py_END_ALLOW_THREADS
2726
2727 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002728 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002729 }
2730
Larry Hastings2f936352014-08-05 14:04:04 +10002731 Py_RETURN_NONE;
2732}
2733
2734
2735#ifdef HAVE_FCHDIR
2736/*[clinic input]
2737os.fchdir
2738
2739 fd: fildes
2740
2741Change to the directory of the given file descriptor.
2742
2743fd must be opened on a directory, not a file.
2744Equivalent to os.chdir(fd).
2745
2746[clinic start generated code]*/
2747
Fred Drake4d1e64b2002-04-15 19:40:07 +00002748static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002749os_fchdir_impl(PyObject *module, int fd)
2750/*[clinic end generated code: output=42e064ec4dc00ab0 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002751{
Larry Hastings2f936352014-08-05 14:04:04 +10002752 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002753}
2754#endif /* HAVE_FCHDIR */
2755
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002756
Larry Hastings2f936352014-08-05 14:04:04 +10002757/*[clinic input]
2758os.chmod
2759
2760 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2761 Path to be modified. May always be specified as a str or bytes.
2762 On some platforms, path may also be specified as an open file descriptor.
2763 If this functionality is unavailable, using it raises an exception.
2764
2765 mode: int
2766 Operating-system mode bitfield.
2767
2768 *
2769
2770 dir_fd : dir_fd(requires='fchmodat') = None
2771 If not None, it should be a file descriptor open to a directory,
2772 and path should be relative; path will then be relative to that
2773 directory.
2774
2775 follow_symlinks: bool = True
2776 If False, and the last element of the path is a symbolic link,
2777 chmod will modify the symbolic link itself instead of the file
2778 the link points to.
2779
2780Change the access permissions of a file.
2781
2782It is an error to use dir_fd or follow_symlinks when specifying path as
2783 an open file descriptor.
2784dir_fd and follow_symlinks may not be implemented on your platform.
2785 If they are unavailable, using them will raise a NotImplementedError.
2786
2787[clinic start generated code]*/
2788
Larry Hastings2f936352014-08-05 14:04:04 +10002789static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002790os_chmod_impl(PyObject *module, path_t *path, int mode, int dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04002791 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002792/*[clinic end generated code: output=5cf6a94915cc7bff input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002793{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002796#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002798#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002799
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800#ifdef HAVE_FCHMODAT
2801 int fchmodat_nofollow_unsupported = 0;
2802#endif
2803
Larry Hastings9cf065c2012-06-22 16:30:09 -07002804#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2805 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002806 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002807#endif
2808
2809#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002810 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002811 if (path->wide)
2812 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 else
Larry Hastings2f936352014-08-05 14:04:04 +10002814 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002815 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002816 result = 0;
2817 else {
2818 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002819 attr &= ~FILE_ATTRIBUTE_READONLY;
2820 else
2821 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002822 if (path->wide)
2823 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 else
Larry Hastings2f936352014-08-05 14:04:04 +10002825 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 }
2827 Py_END_ALLOW_THREADS
2828
2829 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002830 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002831 }
2832#else /* MS_WINDOWS */
2833 Py_BEGIN_ALLOW_THREADS
2834#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002835 if (path->fd != -1)
2836 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 else
2838#endif
2839#ifdef HAVE_LCHMOD
2840 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002841 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002842 else
2843#endif
2844#ifdef HAVE_FCHMODAT
2845 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2846 /*
2847 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2848 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002849 * and then says it isn't implemented yet.
2850 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002851 *
2852 * Once it is supported, os.chmod will automatically
2853 * support dir_fd and follow_symlinks=False. (Hopefully.)
2854 * Until then, we need to be careful what exception we raise.
2855 */
Larry Hastings2f936352014-08-05 14:04:04 +10002856 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2858 /*
2859 * But wait! We can't throw the exception without allowing threads,
2860 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2861 */
2862 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002863 result &&
2864 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2865 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002866 }
2867 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002868#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002869 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002870 Py_END_ALLOW_THREADS
2871
2872 if (result) {
2873#ifdef HAVE_FCHMODAT
2874 if (fchmodat_nofollow_unsupported) {
2875 if (dir_fd != DEFAULT_DIR_FD)
2876 dir_fd_and_follow_symlinks_invalid("chmod",
2877 dir_fd, follow_symlinks);
2878 else
2879 follow_symlinks_specified("chmod", follow_symlinks);
2880 }
2881 else
2882#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002883 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002884 }
2885#endif
2886
Larry Hastings2f936352014-08-05 14:04:04 +10002887 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002888}
2889
Larry Hastings9cf065c2012-06-22 16:30:09 -07002890
Christian Heimes4e30a842007-11-30 22:12:06 +00002891#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002892/*[clinic input]
2893os.fchmod
2894
2895 fd: int
2896 mode: int
2897
2898Change the access permissions of the file given by file descriptor fd.
2899
2900Equivalent to os.chmod(fd, mode).
2901[clinic start generated code]*/
2902
Larry Hastings2f936352014-08-05 14:04:04 +10002903static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002904os_fchmod_impl(PyObject *module, int fd, int mode)
2905/*[clinic end generated code: output=afd9bc05b4e426b3 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002906{
2907 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002908 int async_err = 0;
2909
2910 do {
2911 Py_BEGIN_ALLOW_THREADS
2912 res = fchmod(fd, mode);
2913 Py_END_ALLOW_THREADS
2914 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2915 if (res != 0)
2916 return (!async_err) ? posix_error() : NULL;
2917
Victor Stinner8c62be82010-05-06 00:08:46 +00002918 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002919}
2920#endif /* HAVE_FCHMOD */
2921
Larry Hastings2f936352014-08-05 14:04:04 +10002922
Christian Heimes4e30a842007-11-30 22:12:06 +00002923#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002924/*[clinic input]
2925os.lchmod
2926
2927 path: path_t
2928 mode: int
2929
2930Change the access permissions of a file, without following symbolic links.
2931
2932If path is a symlink, this affects the link itself rather than the target.
2933Equivalent to chmod(path, mode, follow_symlinks=False)."
2934[clinic start generated code]*/
2935
Larry Hastings2f936352014-08-05 14:04:04 +10002936static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002937os_lchmod_impl(PyObject *module, path_t *path, int mode)
2938/*[clinic end generated code: output=082344022b51a1d5 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002939{
Victor Stinner8c62be82010-05-06 00:08:46 +00002940 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002941 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002942 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002944 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002945 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002946 return NULL;
2947 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002948 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002949}
2950#endif /* HAVE_LCHMOD */
2951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002952
Thomas Wouterscf297e42007-02-23 15:07:44 +00002953#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002954/*[clinic input]
2955os.chflags
2956
2957 path: path_t
2958 flags: unsigned_long(bitwise=True)
2959 follow_symlinks: bool=True
2960
2961Set file flags.
2962
2963If follow_symlinks is False, and the last element of the path is a symbolic
2964 link, chflags will change flags on the symbolic link itself instead of the
2965 file the link points to.
2966follow_symlinks may not be implemented on your platform. If it is
2967unavailable, using it will raise a NotImplementedError.
2968
2969[clinic start generated code]*/
2970
Larry Hastings2f936352014-08-05 14:04:04 +10002971static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002972os_chflags_impl(PyObject *module, path_t *path, unsigned long flags,
Larry Hastings89964c42015-04-14 18:07:59 -04002973 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03002974/*[clinic end generated code: output=85571c6737661ce9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002975{
2976 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977
2978#ifndef HAVE_LCHFLAGS
2979 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002980 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002981#endif
2982
Victor Stinner8c62be82010-05-06 00:08:46 +00002983 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002984#ifdef HAVE_LCHFLAGS
2985 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002986 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002987 else
2988#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002989 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002990 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002991
Larry Hastings2f936352014-08-05 14:04:04 +10002992 if (result)
2993 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002994
Larry Hastings2f936352014-08-05 14:04:04 +10002995 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002996}
2997#endif /* HAVE_CHFLAGS */
2998
Larry Hastings2f936352014-08-05 14:04:04 +10002999
Thomas Wouterscf297e42007-02-23 15:07:44 +00003000#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003001/*[clinic input]
3002os.lchflags
3003
3004 path: path_t
3005 flags: unsigned_long(bitwise=True)
3006
3007Set file flags.
3008
3009This function will not follow symbolic links.
3010Equivalent to chflags(path, flags, follow_symlinks=False).
3011[clinic start generated code]*/
3012
Larry Hastings2f936352014-08-05 14:04:04 +10003013static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003014os_lchflags_impl(PyObject *module, path_t *path, unsigned long flags)
3015/*[clinic end generated code: output=30ae958695c07316 input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003016{
Victor Stinner8c62be82010-05-06 00:08:46 +00003017 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003018 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003019 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003021 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003022 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003023 }
Victor Stinner292c8352012-10-30 02:17:38 +01003024 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003025}
3026#endif /* HAVE_LCHFLAGS */
3027
Larry Hastings2f936352014-08-05 14:04:04 +10003028
Martin v. Löwis244edc82001-10-04 22:44:26 +00003029#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003030/*[clinic input]
3031os.chroot
3032 path: path_t
3033
3034Change root directory to path.
3035
3036[clinic start generated code]*/
3037
Larry Hastings2f936352014-08-05 14:04:04 +10003038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003039os_chroot_impl(PyObject *module, path_t *path)
3040/*[clinic end generated code: output=de80befc763a4475 input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003041{
3042 int res;
3043 Py_BEGIN_ALLOW_THREADS
3044 res = chroot(path->narrow);
3045 Py_END_ALLOW_THREADS
3046 if (res < 0)
3047 return path_error(path);
3048 Py_RETURN_NONE;
3049}
3050#endif /* HAVE_CHROOT */
3051
Martin v. Löwis244edc82001-10-04 22:44:26 +00003052
Guido van Rossum21142a01999-01-08 21:05:37 +00003053#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003054/*[clinic input]
3055os.fsync
3056
3057 fd: fildes
3058
3059Force write of fd to disk.
3060[clinic start generated code]*/
3061
Larry Hastings2f936352014-08-05 14:04:04 +10003062static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003063os_fsync_impl(PyObject *module, int fd)
3064/*[clinic end generated code: output=4a10d773f52b3584 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003065{
3066 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003067}
3068#endif /* HAVE_FSYNC */
3069
Larry Hastings2f936352014-08-05 14:04:04 +10003070
Ross Lagerwall7807c352011-03-17 20:20:30 +02003071#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003072/*[clinic input]
3073os.sync
3074
3075Force write of everything to disk.
3076[clinic start generated code]*/
3077
Larry Hastings2f936352014-08-05 14:04:04 +10003078static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003079os_sync_impl(PyObject *module)
3080/*[clinic end generated code: output=2796b1f0818cd71c input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003081{
3082 Py_BEGIN_ALLOW_THREADS
3083 sync();
3084 Py_END_ALLOW_THREADS
3085 Py_RETURN_NONE;
3086}
Larry Hastings2f936352014-08-05 14:04:04 +10003087#endif /* HAVE_SYNC */
3088
Ross Lagerwall7807c352011-03-17 20:20:30 +02003089
Guido van Rossum21142a01999-01-08 21:05:37 +00003090#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003091#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003092extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3093#endif
3094
Larry Hastings2f936352014-08-05 14:04:04 +10003095/*[clinic input]
3096os.fdatasync
3097
3098 fd: fildes
3099
3100Force write of fd to disk without forcing update of metadata.
3101[clinic start generated code]*/
3102
Larry Hastings2f936352014-08-05 14:04:04 +10003103static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003104os_fdatasync_impl(PyObject *module, int fd)
3105/*[clinic end generated code: output=b4b9698b5d7e26dd input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003106{
3107 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003108}
3109#endif /* HAVE_FDATASYNC */
3110
3111
Fredrik Lundh10723342000-07-10 16:38:09 +00003112#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003113/*[clinic input]
3114os.chown
3115
3116 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3117 Path to be examined; can be string, bytes, or open-file-descriptor int.
3118
3119 uid: uid_t
3120
3121 gid: gid_t
3122
3123 *
3124
3125 dir_fd : dir_fd(requires='fchownat') = None
3126 If not None, it should be a file descriptor open to a directory,
3127 and path should be relative; path will then be relative to that
3128 directory.
3129
3130 follow_symlinks: bool = True
3131 If False, and the last element of the path is a symbolic link,
3132 stat will examine the symbolic link itself instead of the file
3133 the link points to.
3134
3135Change the owner and group id of path to the numeric uid and gid.\
3136
3137path may always be specified as a string.
3138On some platforms, path may also be specified as an open file descriptor.
3139 If this functionality is unavailable, using it raises an exception.
3140If dir_fd is not None, it should be a file descriptor open to a directory,
3141 and path should be relative; path will then be relative to that directory.
3142If follow_symlinks is False, and the last element of the path is a symbolic
3143 link, chown will modify the symbolic link itself instead of the file the
3144 link points to.
3145It is an error to use dir_fd or follow_symlinks when specifying path as
3146 an open file descriptor.
3147dir_fd and follow_symlinks may not be implemented on your platform.
3148 If they are unavailable, using them will raise a NotImplementedError.
3149
3150[clinic start generated code]*/
3151
Larry Hastings2f936352014-08-05 14:04:04 +10003152static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003153os_chown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid,
Larry Hastings89964c42015-04-14 18:07:59 -04003154 int dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003155/*[clinic end generated code: output=4beadab0db5f70cd input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003156{
3157 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003158
3159#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3160 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003161 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003163 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3164 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3165 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166
3167#ifdef __APPLE__
3168 /*
3169 * This is for Mac OS X 10.3, which doesn't have lchown.
3170 * (But we still have an lchown symbol because of weak-linking.)
3171 * It doesn't have fchownat either. So there's no possibility
3172 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003173 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 if ((!follow_symlinks) && (lchown == NULL)) {
3175 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003176 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003177 }
3178#endif
3179
Victor Stinner8c62be82010-05-06 00:08:46 +00003180 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003181#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003182 if (path->fd != -1)
3183 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184 else
3185#endif
3186#ifdef HAVE_LCHOWN
3187 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003188 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189 else
3190#endif
3191#ifdef HAVE_FCHOWNAT
3192 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003193 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3195 else
3196#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003197 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003198 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003199
Larry Hastings2f936352014-08-05 14:04:04 +10003200 if (result)
3201 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003202
Larry Hastings2f936352014-08-05 14:04:04 +10003203 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003204}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003205#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003206
Larry Hastings2f936352014-08-05 14:04:04 +10003207
Christian Heimes4e30a842007-11-30 22:12:06 +00003208#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003209/*[clinic input]
3210os.fchown
3211
3212 fd: int
3213 uid: uid_t
3214 gid: gid_t
3215
3216Change the owner and group id of the file specified by file descriptor.
3217
3218Equivalent to os.chown(fd, uid, gid).
3219
3220[clinic start generated code]*/
3221
Larry Hastings2f936352014-08-05 14:04:04 +10003222static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003223os_fchown_impl(PyObject *module, int fd, uid_t uid, gid_t gid)
3224/*[clinic end generated code: output=97d21cbd5a4350a6 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003225{
Victor Stinner8c62be82010-05-06 00:08:46 +00003226 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003227 int async_err = 0;
3228
3229 do {
3230 Py_BEGIN_ALLOW_THREADS
3231 res = fchown(fd, uid, gid);
3232 Py_END_ALLOW_THREADS
3233 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3234 if (res != 0)
3235 return (!async_err) ? posix_error() : NULL;
3236
Victor Stinner8c62be82010-05-06 00:08:46 +00003237 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003238}
3239#endif /* HAVE_FCHOWN */
3240
Larry Hastings2f936352014-08-05 14:04:04 +10003241
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003242#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003243/*[clinic input]
3244os.lchown
3245
3246 path : path_t
3247 uid: uid_t
3248 gid: gid_t
3249
3250Change the owner and group id of path to the numeric uid and gid.
3251
3252This function will not follow symbolic links.
3253Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3254[clinic start generated code]*/
3255
Larry Hastings2f936352014-08-05 14:04:04 +10003256static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003257os_lchown_impl(PyObject *module, path_t *path, uid_t uid, gid_t gid)
3258/*[clinic end generated code: output=25eaf6af412fdf2f input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003259{
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003261 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003262 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003264 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003265 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003266 }
Larry Hastings2f936352014-08-05 14:04:04 +10003267 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003268}
3269#endif /* HAVE_LCHOWN */
3270
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003271
Barry Warsaw53699e91996-12-10 23:23:01 +00003272static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003273posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003274{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003275 char *buf, *tmpbuf;
3276 char *cwd;
3277 const size_t chunk = 1024;
3278 size_t buflen = 0;
3279 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003280
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003281#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003282 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003283 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 wchar_t *wbuf2 = wbuf;
3285 PyObject *resobj;
3286 DWORD len;
3287 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003288 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 /* If the buffer is large enough, len does not include the
3290 terminating \0. If the buffer is too small, len includes
3291 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003292 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003293 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003294 if (wbuf2)
3295 len = GetCurrentDirectoryW(len, wbuf2);
3296 }
3297 Py_END_ALLOW_THREADS
3298 if (!wbuf2) {
3299 PyErr_NoMemory();
3300 return NULL;
3301 }
3302 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003304 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003305 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003306 }
3307 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003308 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003309 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003310 return resobj;
3311 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003312
3313 if (win32_warn_bytes_api())
3314 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003315#endif
3316
Victor Stinner4403d7d2015-04-25 00:16:10 +02003317 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003318 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003319 do {
3320 buflen += chunk;
3321 tmpbuf = PyMem_RawRealloc(buf, buflen);
3322 if (tmpbuf == NULL)
3323 break;
3324
3325 buf = tmpbuf;
3326 cwd = getcwd(buf, buflen);
3327 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003328 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003329
3330 if (cwd == NULL) {
3331 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003332 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003333 }
3334
Victor Stinner8c62be82010-05-06 00:08:46 +00003335 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003336 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3337 else
3338 obj = PyUnicode_DecodeFSDefault(buf);
3339 PyMem_RawFree(buf);
3340
3341 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003342}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003343
Larry Hastings2f936352014-08-05 14:04:04 +10003344
3345/*[clinic input]
3346os.getcwd
3347
3348Return a unicode string representing the current working directory.
3349[clinic start generated code]*/
3350
Larry Hastings2f936352014-08-05 14:04:04 +10003351static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003352os_getcwd_impl(PyObject *module)
3353/*[clinic end generated code: output=21badfae2ea99ddc input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003354{
3355 return posix_getcwd(0);
3356}
3357
Larry Hastings2f936352014-08-05 14:04:04 +10003358
3359/*[clinic input]
3360os.getcwdb
3361
3362Return a bytes string representing the current working directory.
3363[clinic start generated code]*/
3364
Larry Hastings2f936352014-08-05 14:04:04 +10003365static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003366os_getcwdb_impl(PyObject *module)
3367/*[clinic end generated code: output=3dd47909480e4824 input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003368{
3369 return posix_getcwd(1);
3370}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003371
Larry Hastings2f936352014-08-05 14:04:04 +10003372
Larry Hastings9cf065c2012-06-22 16:30:09 -07003373#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3374#define HAVE_LINK 1
3375#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003376
Guido van Rossumb6775db1994-08-01 11:34:53 +00003377#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003378/*[clinic input]
3379
3380os.link
3381
3382 src : path_t
3383 dst : path_t
3384 *
3385 src_dir_fd : dir_fd = None
3386 dst_dir_fd : dir_fd = None
3387 follow_symlinks: bool = True
3388
3389Create a hard link to a file.
3390
3391If either src_dir_fd or dst_dir_fd is not None, it should be a file
3392 descriptor open to a directory, and the respective path string (src or dst)
3393 should be relative; the path will then be relative to that directory.
3394If follow_symlinks is False, and the last element of src is a symbolic
3395 link, link will create a link to the symbolic link itself instead of the
3396 file the link points to.
3397src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3398 platform. If they are unavailable, using them will raise a
3399 NotImplementedError.
3400[clinic start generated code]*/
3401
Larry Hastings2f936352014-08-05 14:04:04 +10003402static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003403os_link_impl(PyObject *module, path_t *src, path_t *dst, int src_dir_fd,
Larry Hastings89964c42015-04-14 18:07:59 -04003404 int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003405/*[clinic end generated code: output=7f00f6007fd5269a input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003406{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003407#ifdef MS_WINDOWS
3408 BOOL result;
3409#else
3410 int result;
3411#endif
3412
Larry Hastings9cf065c2012-06-22 16:30:09 -07003413#ifndef HAVE_LINKAT
3414 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3415 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003416 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003417 }
3418#endif
3419
Larry Hastings2f936352014-08-05 14:04:04 +10003420 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003421 PyErr_SetString(PyExc_NotImplementedError,
3422 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003423 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003424 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003425
Brian Curtin1b9df392010-11-24 20:24:31 +00003426#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003428 if (src->wide)
3429 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003430 else
Larry Hastings2f936352014-08-05 14:04:04 +10003431 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003433
Larry Hastings2f936352014-08-05 14:04:04 +10003434 if (!result)
3435 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436#else
3437 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003438#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3440 (dst_dir_fd != DEFAULT_DIR_FD) ||
3441 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003442 result = linkat(src_dir_fd, src->narrow,
3443 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3445 else
3446#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003447 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003449
Larry Hastings2f936352014-08-05 14:04:04 +10003450 if (result)
3451 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003452#endif
3453
Larry Hastings2f936352014-08-05 14:04:04 +10003454 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003455}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456#endif
3457
Brian Curtin1b9df392010-11-24 20:24:31 +00003458
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003459#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003460static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003461_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003462{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 PyObject *v;
3464 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3465 BOOL result;
3466 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003467 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003468 char *bufptr = namebuf;
3469 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003470 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 PyObject *po = NULL;
3472 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003477
Gregory P. Smith40a21602013-03-20 20:52:50 -07003478 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003479 po_wchars = L".";
3480 len = 1;
3481 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003482 po_wchars = path->wide;
3483 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003484 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003486 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 if (!wnamebuf) {
3488 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003491 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003493 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003494 if (wch != SEP && wch != ALTSEP && wch != L':')
3495 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 wcscpy(wnamebuf + len, L"*.*");
3497 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 if ((list = PyList_New(0)) == NULL) {
3499 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003501 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003503 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 if (hFindFile == INVALID_HANDLE_VALUE) {
3505 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if (error == ERROR_FILE_NOT_FOUND)
3507 goto exit;
3508 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
3512 do {
3513 /* Skip over . and .. */
3514 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3515 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 v = PyUnicode_FromWideChar(wFileData.cFileName,
3517 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_DECREF(list);
3520 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 break;
3522 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 break;
3528 }
3529 Py_DECREF(v);
3530 }
3531 Py_BEGIN_ALLOW_THREADS
3532 result = FindNextFileW(hFindFile, &wFileData);
3533 Py_END_ALLOW_THREADS
3534 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3535 it got to the end of the directory. */
3536 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003538 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 }
3541 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003542
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545 strcpy(namebuf, path->narrow);
3546 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 if (len > 0) {
3548 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003549 if (ch != '\\' && ch != '/' && ch != ':')
3550 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 strcpy(namebuf + len, "*.*");
3552 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003556
Antoine Pitroub73caab2010-08-09 23:39:31 +00003557 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003559 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 if (hFindFile == INVALID_HANDLE_VALUE) {
3561 int error = GetLastError();
3562 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 goto exit;
3564 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003565 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 }
3568 do {
3569 /* Skip over . and .. */
3570 if (strcmp(FileData.cFileName, ".") != 0 &&
3571 strcmp(FileData.cFileName, "..") != 0) {
3572 v = PyBytes_FromString(FileData.cFileName);
3573 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 Py_DECREF(list);
3575 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 break;
3577 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 Py_DECREF(list);
3581 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 break;
3583 }
3584 Py_DECREF(v);
3585 }
3586 Py_BEGIN_ALLOW_THREADS
3587 result = FindNextFile(hFindFile, &FileData);
3588 Py_END_ALLOW_THREADS
3589 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3590 it got to the end of the directory. */
3591 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 }
3596 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003597
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598exit:
3599 if (hFindFile != INVALID_HANDLE_VALUE) {
3600 if (FindClose(hFindFile) == FALSE) {
3601 if (list != NULL) {
3602 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 }
3605 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003607 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003608
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003610} /* end of _listdir_windows_no_opendir */
3611
3612#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3613
3614static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003615_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003616{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003617 PyObject *v;
3618 DIR *dirp = NULL;
3619 struct dirent *ep;
3620 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003621#ifdef HAVE_FDOPENDIR
3622 int fd = -1;
3623#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003624
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003627 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003629 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003630 if (fd == -1)
3631 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632
Larry Hastingsfdaea062012-06-25 04:42:23 -07003633 return_str = 1;
3634
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 Py_BEGIN_ALLOW_THREADS
3636 dirp = fdopendir(fd);
3637 Py_END_ALLOW_THREADS
3638 }
3639 else
3640#endif
3641 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003642 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003643 if (path->narrow) {
3644 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003645 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003646 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003647 }
3648 else {
3649 name = ".";
3650 return_str = 1;
3651 }
3652
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 Py_BEGIN_ALLOW_THREADS
3654 dirp = opendir(name);
3655 Py_END_ALLOW_THREADS
3656 }
3657
3658 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003659 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003660#ifdef HAVE_FDOPENDIR
3661 if (fd != -1) {
3662 Py_BEGIN_ALLOW_THREADS
3663 close(fd);
3664 Py_END_ALLOW_THREADS
3665 }
3666#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 goto exit;
3668 }
3669 if ((list = PyList_New(0)) == NULL) {
3670 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 }
3672 for (;;) {
3673 errno = 0;
3674 Py_BEGIN_ALLOW_THREADS
3675 ep = readdir(dirp);
3676 Py_END_ALLOW_THREADS
3677 if (ep == NULL) {
3678 if (errno == 0) {
3679 break;
3680 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003682 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
3685 }
3686 if (ep->d_name[0] == '.' &&
3687 (NAMLEN(ep) == 1 ||
3688 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3689 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003690 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003691 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3692 else
3693 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003700 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 break;
3702 }
3703 Py_DECREF(v);
3704 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003705
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706exit:
3707 if (dirp != NULL) {
3708 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003709#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 if (fd > -1)
3711 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003712#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 closedir(dirp);
3714 Py_END_ALLOW_THREADS
3715 }
3716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003718} /* end of _posix_listdir */
3719#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003720
Larry Hastings2f936352014-08-05 14:04:04 +10003721
3722/*[clinic input]
3723os.listdir
3724
3725 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3726
3727Return a list containing the names of the files in the directory.
3728
3729path can be specified as either str or bytes. If path is bytes,
3730 the filenames returned will also be bytes; in all other circumstances
3731 the filenames returned will be str.
3732If path is None, uses the path='.'.
3733On some platforms, path may also be specified as an open file descriptor;\
3734 the file descriptor must refer to a directory.
3735 If this functionality is unavailable, using it raises NotImplementedError.
3736
3737The list is in arbitrary order. It does not include the special
3738entries '.' and '..' even if they are present in the directory.
3739
3740
3741[clinic start generated code]*/
3742
Larry Hastings2f936352014-08-05 14:04:04 +10003743static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003744os_listdir_impl(PyObject *module, path_t *path)
3745/*[clinic end generated code: output=293045673fcd1a75 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003746{
3747#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3748 return _listdir_windows_no_opendir(path, NULL);
3749#else
3750 return _posix_listdir(path, NULL);
3751#endif
3752}
3753
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003754#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003755/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003756/*[clinic input]
3757os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003758
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003759 path: path_t
3760 /
3761
3762[clinic start generated code]*/
3763
3764static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003765os__getfullpathname_impl(PyObject *module, path_t *path)
3766/*[clinic end generated code: output=bb8679d56845bc9b input=332ed537c29d0a3e]*/
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003767{
3768 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769 {
Victor Stinner75875072013-11-24 19:23:25 +01003770 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003771 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 DWORD result;
3773 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003775 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003776 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003778 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003779 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 if (!woutbufp)
3781 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003782 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 }
3784 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003785 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003789 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 return v;
3791 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003792 else {
3793 char outbuf[MAX_PATH];
3794 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003795
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003796 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3797 outbuf, &temp)) {
3798 win32_error_object("GetFullPathName", path->object);
3799 return NULL;
3800 }
3801 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 }
Larry Hastings2f936352014-08-05 14:04:04 +10003803}
Brian Curtind40e6f72010-07-08 21:39:08 +00003804
Brian Curtind25aef52011-06-13 15:16:04 -05003805
Larry Hastings2f936352014-08-05 14:04:04 +10003806/*[clinic input]
3807os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003808
Larry Hastings2f936352014-08-05 14:04:04 +10003809 path: unicode
3810 /
3811
3812A helper function for samepath on windows.
3813[clinic start generated code]*/
3814
Larry Hastings2f936352014-08-05 14:04:04 +10003815static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03003816os__getfinalpathname_impl(PyObject *module, PyObject *path)
3817/*[clinic end generated code: output=9bd78d0e52782e75 input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003818{
3819 HANDLE hFile;
3820 int buf_size;
3821 wchar_t *target_path;
3822 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003823 PyObject *result;
3824 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003825
Larry Hastings2f936352014-08-05 14:04:04 +10003826 path_wchar = PyUnicode_AsUnicode(path);
3827 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003828 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003829
Brian Curtind40e6f72010-07-08 21:39:08 +00003830 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003831 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003832 0, /* desired access */
3833 0, /* share mode */
3834 NULL, /* security attributes */
3835 OPEN_EXISTING,
3836 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3837 FILE_FLAG_BACKUP_SEMANTICS,
3838 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003839
Victor Stinnereb5657a2011-09-30 01:44:27 +02003840 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003841 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003842
3843 /* We have a good handle to the target, use it to determine the
3844 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003845 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003846
3847 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003848 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003849
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003850 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003851 if(!target_path)
3852 return PyErr_NoMemory();
3853
Steve Dower2ea51c92015-03-20 21:49:12 -07003854 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3855 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003857 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003858
3859 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003860 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003861
3862 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003863 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003864 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003865 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003866}
Brian Curtin62857742010-09-06 17:07:27 +00003867
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003868/*[clinic input]
3869os._isdir
3870
3871 path: path_t
3872 /
3873
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003874Return true if the pathname refers to an existing directory.
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003875[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)
Serhiy Storchaka579f0382016-11-08 20:21:22 +02003879/*[clinic end generated code: output=75f56f32720836cb input=5e0800149c0ad95f]*/
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 }
Steve Dower11f43262016-11-19 18:33:39 -08005189#ifdef MS_WINDOWS
5190 /* Avoid changing behavior in maintenance release, but
5191 the previous Windows behavior was to crash, so this
5192 is a "compatible" improvement. */
5193 if (argc == 0) {
5194 PyErr_SetString(PyExc_ValueError,
5195 "spawnv() arg 2 cannot be empty");
5196 return NULL;
5197 }
5198#endif
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 argvlist = PyMem_NEW(char *, argc+1);
5201 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 return PyErr_NoMemory();
5203 }
5204 for (i = 0; i < argc; i++) {
5205 if (!fsconvert_strdup((*getitem)(argv, i),
5206 &argvlist[i])) {
5207 free_string_array(argvlist, i);
5208 PyErr_SetString(
5209 PyExc_TypeError,
5210 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 return NULL;
5212 }
Steve Dower93ff8722016-11-19 19:03:54 -08005213#ifdef MS_WINDOWS
5214 if (i == 0 && !argvlist[0][0]) {
5215 free_string_array(argvlist, i);
5216 PyErr_SetString(
5217 PyExc_ValueError,
5218 "spawnv() arg 2 first element cannot be empty");
5219 return NULL;
5220 }
5221#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 }
5223 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005224
Victor Stinner8c62be82010-05-06 00:08:46 +00005225 if (mode == _OLD_P_OVERLAY)
5226 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005227
Victor Stinner8c62be82010-05-06 00:08:46 +00005228 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08005229 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10005230 spawnval = _spawnv(mode, path_char, argvlist);
Steve Dower11f43262016-11-19 18:33:39 -08005231 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005232 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005233
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005235
Victor Stinner8c62be82010-05-06 00:08:46 +00005236 if (spawnval == -1)
5237 return posix_error();
5238 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005239 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005240}
5241
5242
Larry Hastings2f936352014-08-05 14:04:04 +10005243/*[clinic input]
5244os.spawnve
5245
5246 mode: int
5247 Mode of process creation.
5248 path: FSConverter
5249 Path of executable file.
5250 argv: object
5251 Tuple or list of strings.
5252 env: object
5253 Dictionary of strings mapping to strings.
5254 /
5255
5256Execute the program specified by path in a new process.
5257[clinic start generated code]*/
5258
Larry Hastings2f936352014-08-05 14:04:04 +10005259static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005260os_spawnve_impl(PyObject *module, int mode, PyObject *path, PyObject *argv,
5261 PyObject *env)
5262/*[clinic end generated code: output=ebcfa5f7ba2f4219 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005263{
5264 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005265 char **argvlist;
5266 char **envlist;
5267 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005268 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005269 Py_intptr_t spawnval;
5270 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5271 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005272
Victor Stinner8c62be82010-05-06 00:08:46 +00005273 /* spawnve has four arguments: (mode, path, argv, env), where
5274 argv is a list or tuple of strings and env is a dictionary
5275 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005276
Larry Hastings2f936352014-08-05 14:04:04 +10005277 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 if (PyList_Check(argv)) {
5279 argc = PyList_Size(argv);
5280 getitem = PyList_GetItem;
5281 }
5282 else if (PyTuple_Check(argv)) {
5283 argc = PyTuple_Size(argv);
5284 getitem = PyTuple_GetItem;
5285 }
5286 else {
5287 PyErr_SetString(PyExc_TypeError,
5288 "spawnve() arg 2 must be a tuple or list");
5289 goto fail_0;
5290 }
5291 if (!PyMapping_Check(env)) {
5292 PyErr_SetString(PyExc_TypeError,
5293 "spawnve() arg 3 must be a mapping object");
5294 goto fail_0;
5295 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 argvlist = PyMem_NEW(char *, argc+1);
5298 if (argvlist == NULL) {
5299 PyErr_NoMemory();
5300 goto fail_0;
5301 }
5302 for (i = 0; i < argc; i++) {
5303 if (!fsconvert_strdup((*getitem)(argv, i),
5304 &argvlist[i]))
5305 {
5306 lastarg = i;
5307 goto fail_1;
5308 }
5309 }
5310 lastarg = argc;
5311 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005312
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 envlist = parse_envlist(env, &envc);
5314 if (envlist == NULL)
5315 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005316
Victor Stinner8c62be82010-05-06 00:08:46 +00005317 if (mode == _OLD_P_OVERLAY)
5318 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005319
Victor Stinner8c62be82010-05-06 00:08:46 +00005320 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08005321 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10005322 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Steve Dower11f43262016-11-19 18:33:39 -08005323 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00005324 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005325
Victor Stinner8c62be82010-05-06 00:08:46 +00005326 if (spawnval == -1)
5327 (void) posix_error();
5328 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005329 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005330
Victor Stinner8c62be82010-05-06 00:08:46 +00005331 while (--envc >= 0)
5332 PyMem_DEL(envlist[envc]);
5333 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005334 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005335 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005336 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005337 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005338}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005339
Guido van Rossuma1065681999-01-25 23:20:23 +00005340#endif /* HAVE_SPAWNV */
5341
5342
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005343#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005344/*[clinic input]
5345os.fork1
5346
5347Fork a child process with a single multiplexed (i.e., not bound) thread.
5348
5349Return 0 to child process and PID of child to parent process.
5350[clinic start generated code]*/
5351
Larry Hastings2f936352014-08-05 14:04:04 +10005352static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005353os_fork1_impl(PyObject *module)
5354/*[clinic end generated code: output=0de8e67ce2a310bc input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005355{
Victor Stinner8c62be82010-05-06 00:08:46 +00005356 pid_t pid;
5357 int result = 0;
5358 _PyImport_AcquireLock();
5359 pid = fork1();
5360 if (pid == 0) {
5361 /* child: this clobbers and resets the import lock. */
5362 PyOS_AfterFork();
5363 } else {
5364 /* parent: release the import lock. */
5365 result = _PyImport_ReleaseLock();
5366 }
5367 if (pid == -1)
5368 return posix_error();
5369 if (result < 0) {
5370 /* Don't clobber the OSError if the fork failed. */
5371 PyErr_SetString(PyExc_RuntimeError,
5372 "not holding the import lock");
5373 return NULL;
5374 }
5375 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005376}
Larry Hastings2f936352014-08-05 14:04:04 +10005377#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005378
5379
Guido van Rossumad0ee831995-03-01 10:34:45 +00005380#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005381/*[clinic input]
5382os.fork
5383
5384Fork a child process.
5385
5386Return 0 to child process and PID of child to parent process.
5387[clinic start generated code]*/
5388
Larry Hastings2f936352014-08-05 14:04:04 +10005389static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005390os_fork_impl(PyObject *module)
5391/*[clinic end generated code: output=3626c81f98985d49 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005392{
Victor Stinner8c62be82010-05-06 00:08:46 +00005393 pid_t pid;
5394 int result = 0;
5395 _PyImport_AcquireLock();
5396 pid = fork();
5397 if (pid == 0) {
5398 /* child: this clobbers and resets the import lock. */
5399 PyOS_AfterFork();
5400 } else {
5401 /* parent: release the import lock. */
5402 result = _PyImport_ReleaseLock();
5403 }
5404 if (pid == -1)
5405 return posix_error();
5406 if (result < 0) {
5407 /* Don't clobber the OSError if the fork failed. */
5408 PyErr_SetString(PyExc_RuntimeError,
5409 "not holding the import lock");
5410 return NULL;
5411 }
5412 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005413}
Larry Hastings2f936352014-08-05 14:04:04 +10005414#endif /* HAVE_FORK */
5415
Guido van Rossum85e3b011991-06-03 12:42:10 +00005416
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005417#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005418#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005419/*[clinic input]
5420os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005421
Larry Hastings2f936352014-08-05 14:04:04 +10005422 policy: int
5423
5424Get the maximum scheduling priority for policy.
5425[clinic start generated code]*/
5426
Larry Hastings2f936352014-08-05 14:04:04 +10005427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005428os_sched_get_priority_max_impl(PyObject *module, int policy)
5429/*[clinic end generated code: output=9e465c6e43130521 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005430{
5431 int max;
5432
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005433 max = sched_get_priority_max(policy);
5434 if (max < 0)
5435 return posix_error();
5436 return PyLong_FromLong(max);
5437}
5438
Larry Hastings2f936352014-08-05 14:04:04 +10005439
5440/*[clinic input]
5441os.sched_get_priority_min
5442
5443 policy: int
5444
5445Get the minimum scheduling priority for policy.
5446[clinic start generated code]*/
5447
Larry Hastings2f936352014-08-05 14:04:04 +10005448static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005449os_sched_get_priority_min_impl(PyObject *module, int policy)
5450/*[clinic end generated code: output=7595c1138cc47a6d input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005451{
5452 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005453 if (min < 0)
5454 return posix_error();
5455 return PyLong_FromLong(min);
5456}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005457#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5458
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005459
Larry Hastings2f936352014-08-05 14:04:04 +10005460#ifdef HAVE_SCHED_SETSCHEDULER
5461/*[clinic input]
5462os.sched_getscheduler
5463 pid: pid_t
5464 /
5465
5466Get the scheduling policy for the process identifiedy by pid.
5467
5468Passing 0 for pid returns the scheduling policy for the calling process.
5469[clinic start generated code]*/
5470
Larry Hastings2f936352014-08-05 14:04:04 +10005471static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005472os_sched_getscheduler_impl(PyObject *module, pid_t pid)
5473/*[clinic end generated code: output=dce4c0bd3f1b34c8 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005474{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475 int policy;
5476
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005477 policy = sched_getscheduler(pid);
5478 if (policy < 0)
5479 return posix_error();
5480 return PyLong_FromLong(policy);
5481}
Larry Hastings2f936352014-08-05 14:04:04 +10005482#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005483
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005484
5485#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005486/*[clinic input]
5487class os.sched_param "PyObject *" "&SchedParamType"
5488
5489@classmethod
5490os.sched_param.__new__
5491
5492 sched_priority: object
5493 A scheduling parameter.
5494
5495Current has only one field: sched_priority");
5496[clinic start generated code]*/
5497
Larry Hastings2f936352014-08-05 14:04:04 +10005498static PyObject *
5499os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005500/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005501{
5502 PyObject *res;
5503
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005504 res = PyStructSequence_New(type);
5505 if (!res)
5506 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005507 Py_INCREF(sched_priority);
5508 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005509 return res;
5510}
5511
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005512
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005513PyDoc_VAR(os_sched_param__doc__);
5514
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005515static PyStructSequence_Field sched_param_fields[] = {
5516 {"sched_priority", "the scheduling priority"},
5517 {0}
5518};
5519
5520static PyStructSequence_Desc sched_param_desc = {
5521 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005522 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005523 sched_param_fields,
5524 1
5525};
5526
5527static int
5528convert_sched_param(PyObject *param, struct sched_param *res)
5529{
5530 long priority;
5531
5532 if (Py_TYPE(param) != &SchedParamType) {
5533 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5534 return 0;
5535 }
5536 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5537 if (priority == -1 && PyErr_Occurred())
5538 return 0;
5539 if (priority > INT_MAX || priority < INT_MIN) {
5540 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5541 return 0;
5542 }
5543 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5544 return 1;
5545}
Larry Hastings2f936352014-08-05 14:04:04 +10005546#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005547
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005548
5549#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005550/*[clinic input]
5551os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005552
Larry Hastings2f936352014-08-05 14:04:04 +10005553 pid: pid_t
5554 policy: int
5555 param: sched_param
5556 /
5557
5558Set the scheduling policy for the process identified by pid.
5559
5560If pid is 0, the calling process is changed.
5561param is an instance of sched_param.
5562[clinic start generated code]*/
5563
Larry Hastings2f936352014-08-05 14:04:04 +10005564static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005565os_sched_setscheduler_impl(PyObject *module, pid_t pid, int policy,
Larry Hastings89964c42015-04-14 18:07:59 -04005566 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005567/*[clinic end generated code: output=b0ac0a70d3b1d705 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005568{
Jesus Cea9c822272011-09-10 01:40:52 +02005569 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005570 ** sched_setscheduler() returns 0 in Linux, but the previous
5571 ** scheduling policy under Solaris/Illumos, and others.
5572 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005573 */
Larry Hastings2f936352014-08-05 14:04:04 +10005574 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005575 return posix_error();
5576 Py_RETURN_NONE;
5577}
Larry Hastings2f936352014-08-05 14:04:04 +10005578#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005580
5581#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005582/*[clinic input]
5583os.sched_getparam
5584 pid: pid_t
5585 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005586
Larry Hastings2f936352014-08-05 14:04:04 +10005587Returns scheduling parameters for the process identified by pid.
5588
5589If pid is 0, returns parameters for the calling process.
5590Return value is an instance of sched_param.
5591[clinic start generated code]*/
5592
Larry Hastings2f936352014-08-05 14:04:04 +10005593static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005594os_sched_getparam_impl(PyObject *module, pid_t pid)
5595/*[clinic end generated code: output=b194e8708dcf2db8 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005596{
5597 struct sched_param param;
5598 PyObject *result;
5599 PyObject *priority;
5600
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005601 if (sched_getparam(pid, &param))
5602 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005603 result = PyStructSequence_New(&SchedParamType);
5604 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005605 return NULL;
5606 priority = PyLong_FromLong(param.sched_priority);
5607 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005608 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005609 return NULL;
5610 }
Larry Hastings2f936352014-08-05 14:04:04 +10005611 PyStructSequence_SET_ITEM(result, 0, priority);
5612 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005613}
5614
Larry Hastings2f936352014-08-05 14:04:04 +10005615
5616/*[clinic input]
5617os.sched_setparam
5618 pid: pid_t
5619 param: sched_param
5620 /
5621
5622Set scheduling parameters for the process identified by pid.
5623
5624If pid is 0, sets parameters for the calling process.
5625param should be an instance of sched_param.
5626[clinic start generated code]*/
5627
Larry Hastings2f936352014-08-05 14:04:04 +10005628static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005629os_sched_setparam_impl(PyObject *module, pid_t pid,
Larry Hastings89964c42015-04-14 18:07:59 -04005630 struct sched_param *param)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005631/*[clinic end generated code: output=8af013f78a32b591 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005632{
5633 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005634 return posix_error();
5635 Py_RETURN_NONE;
5636}
Larry Hastings2f936352014-08-05 14:04:04 +10005637#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005638
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005639
5640#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005641/*[clinic input]
5642os.sched_rr_get_interval -> double
5643 pid: pid_t
5644 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005645
Larry Hastings2f936352014-08-05 14:04:04 +10005646Return the round-robin quantum for the process identified by pid, in seconds.
5647
5648Value returned is a float.
5649[clinic start generated code]*/
5650
Larry Hastings2f936352014-08-05 14:04:04 +10005651static double
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005652os_sched_rr_get_interval_impl(PyObject *module, pid_t pid)
5653/*[clinic end generated code: output=7e2d935833ab47dc input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005654{
5655 struct timespec interval;
5656 if (sched_rr_get_interval(pid, &interval)) {
5657 posix_error();
5658 return -1.0;
5659 }
5660 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5661}
5662#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005663
Larry Hastings2f936352014-08-05 14:04:04 +10005664
5665/*[clinic input]
5666os.sched_yield
5667
5668Voluntarily relinquish the CPU.
5669[clinic start generated code]*/
5670
Larry Hastings2f936352014-08-05 14:04:04 +10005671static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005672os_sched_yield_impl(PyObject *module)
5673/*[clinic end generated code: output=902323500f222cac input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005674{
5675 if (sched_yield())
5676 return posix_error();
5677 Py_RETURN_NONE;
5678}
5679
Benjamin Peterson2740af82011-08-02 17:41:34 -05005680#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005681/* The minimum number of CPUs allocated in a cpu_set_t */
5682static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005683
Larry Hastings2f936352014-08-05 14:04:04 +10005684/*[clinic input]
5685os.sched_setaffinity
5686 pid: pid_t
5687 mask : object
5688 /
5689
5690Set the CPU affinity of the process identified by pid to mask.
5691
5692mask should be an iterable of integers identifying CPUs.
5693[clinic start generated code]*/
5694
Larry Hastings2f936352014-08-05 14:04:04 +10005695static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005696os_sched_setaffinity_impl(PyObject *module, pid_t pid, PyObject *mask)
5697/*[clinic end generated code: output=882d7dd9a229335b input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005698{
Antoine Pitrou84869872012-08-04 16:16:35 +02005699 int ncpus;
5700 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005701 cpu_set_t *cpu_set = NULL;
5702 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005703
Larry Hastings2f936352014-08-05 14:04:04 +10005704 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005705 if (iterator == NULL)
5706 return NULL;
5707
5708 ncpus = NCPUS_START;
5709 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005710 cpu_set = CPU_ALLOC(ncpus);
5711 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005712 PyErr_NoMemory();
5713 goto error;
5714 }
Larry Hastings2f936352014-08-05 14:04:04 +10005715 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005716
5717 while ((item = PyIter_Next(iterator))) {
5718 long cpu;
5719 if (!PyLong_Check(item)) {
5720 PyErr_Format(PyExc_TypeError,
5721 "expected an iterator of ints, "
5722 "but iterator yielded %R",
5723 Py_TYPE(item));
5724 Py_DECREF(item);
5725 goto error;
5726 }
5727 cpu = PyLong_AsLong(item);
5728 Py_DECREF(item);
5729 if (cpu < 0) {
5730 if (!PyErr_Occurred())
5731 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5732 goto error;
5733 }
5734 if (cpu > INT_MAX - 1) {
5735 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5736 goto error;
5737 }
5738 if (cpu >= ncpus) {
5739 /* Grow CPU mask to fit the CPU number */
5740 int newncpus = ncpus;
5741 cpu_set_t *newmask;
5742 size_t newsetsize;
5743 while (newncpus <= cpu) {
5744 if (newncpus > INT_MAX / 2)
5745 newncpus = cpu + 1;
5746 else
5747 newncpus = newncpus * 2;
5748 }
5749 newmask = CPU_ALLOC(newncpus);
5750 if (newmask == NULL) {
5751 PyErr_NoMemory();
5752 goto error;
5753 }
5754 newsetsize = CPU_ALLOC_SIZE(newncpus);
5755 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005756 memcpy(newmask, cpu_set, setsize);
5757 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005758 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005759 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005760 ncpus = newncpus;
5761 }
Larry Hastings2f936352014-08-05 14:04:04 +10005762 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005763 }
5764 Py_CLEAR(iterator);
5765
Larry Hastings2f936352014-08-05 14:04:04 +10005766 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005767 posix_error();
5768 goto error;
5769 }
Larry Hastings2f936352014-08-05 14:04:04 +10005770 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005771 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005772
5773error:
Larry Hastings2f936352014-08-05 14:04:04 +10005774 if (cpu_set)
5775 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005776 Py_XDECREF(iterator);
5777 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005778}
5779
Larry Hastings2f936352014-08-05 14:04:04 +10005780
5781/*[clinic input]
5782os.sched_getaffinity
5783 pid: pid_t
5784 /
5785
5786Return the affinity of the process identified by pid.
5787
5788The affinity is returned as a set of CPU identifiers.
5789[clinic start generated code]*/
5790
Larry Hastings2f936352014-08-05 14:04:04 +10005791static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005792os_sched_getaffinity_impl(PyObject *module, pid_t pid)
5793/*[clinic end generated code: output=f726f2c193c17a4f input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005794{
Antoine Pitrou84869872012-08-04 16:16:35 +02005795 int cpu, ncpus, count;
5796 size_t setsize;
5797 cpu_set_t *mask = NULL;
5798 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005799
Antoine Pitrou84869872012-08-04 16:16:35 +02005800 ncpus = NCPUS_START;
5801 while (1) {
5802 setsize = CPU_ALLOC_SIZE(ncpus);
5803 mask = CPU_ALLOC(ncpus);
5804 if (mask == NULL)
5805 return PyErr_NoMemory();
5806 if (sched_getaffinity(pid, setsize, mask) == 0)
5807 break;
5808 CPU_FREE(mask);
5809 if (errno != EINVAL)
5810 return posix_error();
5811 if (ncpus > INT_MAX / 2) {
5812 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5813 "a large enough CPU set");
5814 return NULL;
5815 }
5816 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005817 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005818
5819 res = PySet_New(NULL);
5820 if (res == NULL)
5821 goto error;
5822 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5823 if (CPU_ISSET_S(cpu, setsize, mask)) {
5824 PyObject *cpu_num = PyLong_FromLong(cpu);
5825 --count;
5826 if (cpu_num == NULL)
5827 goto error;
5828 if (PySet_Add(res, cpu_num)) {
5829 Py_DECREF(cpu_num);
5830 goto error;
5831 }
5832 Py_DECREF(cpu_num);
5833 }
5834 }
5835 CPU_FREE(mask);
5836 return res;
5837
5838error:
5839 if (mask)
5840 CPU_FREE(mask);
5841 Py_XDECREF(res);
5842 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005843}
5844
Benjamin Peterson2740af82011-08-02 17:41:34 -05005845#endif /* HAVE_SCHED_SETAFFINITY */
5846
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005847#endif /* HAVE_SCHED_H */
5848
Larry Hastings2f936352014-08-05 14:04:04 +10005849
Neal Norwitzb59798b2003-03-21 01:43:31 +00005850/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005851/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5852#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005853#define DEV_PTY_FILE "/dev/ptc"
5854#define HAVE_DEV_PTMX
5855#else
5856#define DEV_PTY_FILE "/dev/ptmx"
5857#endif
5858
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005859#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005860#ifdef HAVE_PTY_H
5861#include <pty.h>
5862#else
5863#ifdef HAVE_LIBUTIL_H
5864#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005865#else
5866#ifdef HAVE_UTIL_H
5867#include <util.h>
5868#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005869#endif /* HAVE_LIBUTIL_H */
5870#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005871#ifdef HAVE_STROPTS_H
5872#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005873#endif
5874#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005875
Larry Hastings2f936352014-08-05 14:04:04 +10005876
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005877#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005878/*[clinic input]
5879os.openpty
5880
5881Open a pseudo-terminal.
5882
5883Return a tuple of (master_fd, slave_fd) containing open file descriptors
5884for both the master and slave ends.
5885[clinic start generated code]*/
5886
Larry Hastings2f936352014-08-05 14:04:04 +10005887static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005888os_openpty_impl(PyObject *module)
5889/*[clinic end generated code: output=98841ce5ec9cef3c input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005890{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005891 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005892#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005893 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005894#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005895#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005896 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005897#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005899#endif
5900#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005901
Thomas Wouters70c21a12000-07-14 14:28:33 +00005902#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005903 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005904 goto posix_error;
5905
5906 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5907 goto error;
5908 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5909 goto error;
5910
Neal Norwitzb59798b2003-03-21 01:43:31 +00005911#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5913 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005914 goto posix_error;
5915 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5916 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005917
Victor Stinnerdaf45552013-08-28 00:53:59 +02005918 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005920 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005921
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005922#else
Victor Stinner000de532013-11-25 23:19:58 +01005923 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005924 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005925 goto posix_error;
5926
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005928
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 /* change permission of slave */
5930 if (grantpt(master_fd) < 0) {
5931 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005932 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005934
Victor Stinner8c62be82010-05-06 00:08:46 +00005935 /* unlock slave */
5936 if (unlockpt(master_fd) < 0) {
5937 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005938 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005939 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005940
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005942
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 slave_name = ptsname(master_fd); /* get name of slave */
5944 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005945 goto posix_error;
5946
5947 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005948 if (slave_fd == -1)
5949 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005950
5951 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5952 goto posix_error;
5953
Neal Norwitzb59798b2003-03-21 01:43:31 +00005954#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005955 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5956 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005957#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005958 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005959#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005960#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005961#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005962
Victor Stinner8c62be82010-05-06 00:08:46 +00005963 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005964
Victor Stinnerdaf45552013-08-28 00:53:59 +02005965posix_error:
5966 posix_error();
5967error:
5968 if (master_fd != -1)
5969 close(master_fd);
5970 if (slave_fd != -1)
5971 close(slave_fd);
5972 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005973}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005974#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005975
Larry Hastings2f936352014-08-05 14:04:04 +10005976
Fred Drake8cef4cf2000-06-28 16:40:38 +00005977#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005978/*[clinic input]
5979os.forkpty
5980
5981Fork a new process with a new pseudo-terminal as controlling tty.
5982
5983Returns a tuple of (pid, master_fd).
5984Like fork(), return pid of 0 to the child process,
5985and pid of child to the parent process.
5986To both, return fd of newly opened pseudo-terminal.
5987[clinic start generated code]*/
5988
Larry Hastings2f936352014-08-05 14:04:04 +10005989static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03005990os_forkpty_impl(PyObject *module)
5991/*[clinic end generated code: output=60d0a5c7512e4087 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005992{
Victor Stinner8c62be82010-05-06 00:08:46 +00005993 int master_fd = -1, result = 0;
5994 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005995
Victor Stinner8c62be82010-05-06 00:08:46 +00005996 _PyImport_AcquireLock();
5997 pid = forkpty(&master_fd, NULL, NULL, NULL);
5998 if (pid == 0) {
5999 /* child: this clobbers and resets the import lock. */
6000 PyOS_AfterFork();
6001 } else {
6002 /* parent: release the import lock. */
6003 result = _PyImport_ReleaseLock();
6004 }
6005 if (pid == -1)
6006 return posix_error();
6007 if (result < 0) {
6008 /* Don't clobber the OSError if the fork failed. */
6009 PyErr_SetString(PyExc_RuntimeError,
6010 "not holding the import lock");
6011 return NULL;
6012 }
6013 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006014}
Larry Hastings2f936352014-08-05 14:04:04 +10006015#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006016
Ross Lagerwall7807c352011-03-17 20:20:30 +02006017
Guido van Rossumad0ee831995-03-01 10:34:45 +00006018#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006019/*[clinic input]
6020os.getegid
6021
6022Return the current process's effective group id.
6023[clinic start generated code]*/
6024
Larry Hastings2f936352014-08-05 14:04:04 +10006025static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006026os_getegid_impl(PyObject *module)
6027/*[clinic end generated code: output=67d9be7ac68898a2 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006028{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006029 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006030}
Larry Hastings2f936352014-08-05 14:04:04 +10006031#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006032
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006033
Guido van Rossumad0ee831995-03-01 10:34:45 +00006034#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006035/*[clinic input]
6036os.geteuid
6037
6038Return the current process's effective user id.
6039[clinic start generated code]*/
6040
Larry Hastings2f936352014-08-05 14:04:04 +10006041static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006042os_geteuid_impl(PyObject *module)
6043/*[clinic end generated code: output=ea1b60f0d6abb66e input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006044{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006045 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006046}
Larry Hastings2f936352014-08-05 14:04:04 +10006047#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006048
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006049
Guido van Rossumad0ee831995-03-01 10:34:45 +00006050#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006051/*[clinic input]
6052os.getgid
6053
6054Return the current process's group id.
6055[clinic start generated code]*/
6056
Larry Hastings2f936352014-08-05 14:04:04 +10006057static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006058os_getgid_impl(PyObject *module)
6059/*[clinic end generated code: output=4f28ebc9d3e5dfcf input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006060{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006061 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006062}
Larry Hastings2f936352014-08-05 14:04:04 +10006063#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006064
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006065
Larry Hastings2f936352014-08-05 14:04:04 +10006066/*[clinic input]
6067os.getpid
6068
6069Return the current process id.
6070[clinic start generated code]*/
6071
Larry Hastings2f936352014-08-05 14:04:04 +10006072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006073os_getpid_impl(PyObject *module)
6074/*[clinic end generated code: output=9ea6fdac01ed2b3c input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006075{
Victor Stinner8c62be82010-05-06 00:08:46 +00006076 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006077}
6078
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006079#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006080
6081/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006082PyDoc_STRVAR(posix_getgrouplist__doc__,
6083"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6084Returns a list of groups to which a user belongs.\n\n\
6085 user: username to lookup\n\
6086 group: base group id of the user");
6087
6088static PyObject *
6089posix_getgrouplist(PyObject *self, PyObject *args)
6090{
6091#ifdef NGROUPS_MAX
6092#define MAX_GROUPS NGROUPS_MAX
6093#else
6094 /* defined to be 16 on Solaris7, so this should be a small number */
6095#define MAX_GROUPS 64
6096#endif
6097
6098 const char *user;
6099 int i, ngroups;
6100 PyObject *list;
6101#ifdef __APPLE__
6102 int *groups, basegid;
6103#else
6104 gid_t *groups, basegid;
6105#endif
6106 ngroups = MAX_GROUPS;
6107
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006108#ifdef __APPLE__
6109 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006110 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006111#else
6112 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6113 _Py_Gid_Converter, &basegid))
6114 return NULL;
6115#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006116
6117#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006118 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006119#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006120 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006121#endif
6122 if (groups == NULL)
6123 return PyErr_NoMemory();
6124
6125 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6126 PyMem_Del(groups);
6127 return posix_error();
6128 }
6129
6130 list = PyList_New(ngroups);
6131 if (list == NULL) {
6132 PyMem_Del(groups);
6133 return NULL;
6134 }
6135
6136 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006137#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006138 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006139#else
6140 PyObject *o = _PyLong_FromGid(groups[i]);
6141#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006142 if (o == NULL) {
6143 Py_DECREF(list);
6144 PyMem_Del(groups);
6145 return NULL;
6146 }
6147 PyList_SET_ITEM(list, i, o);
6148 }
6149
6150 PyMem_Del(groups);
6151
6152 return list;
6153}
Larry Hastings2f936352014-08-05 14:04:04 +10006154#endif /* HAVE_GETGROUPLIST */
6155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006156
Fred Drakec9680921999-12-13 16:37:25 +00006157#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006158/*[clinic input]
6159os.getgroups
6160
6161Return list of supplemental group IDs for the process.
6162[clinic start generated code]*/
6163
Larry Hastings2f936352014-08-05 14:04:04 +10006164static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006165os_getgroups_impl(PyObject *module)
6166/*[clinic end generated code: output=42b0c17758561b56 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006167{
6168 PyObject *result = NULL;
6169
Fred Drakec9680921999-12-13 16:37:25 +00006170#ifdef NGROUPS_MAX
6171#define MAX_GROUPS NGROUPS_MAX
6172#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006173 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006174#define MAX_GROUPS 64
6175#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006176 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006177
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006178 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006179 * This is a helper variable to store the intermediate result when
6180 * that happens.
6181 *
6182 * To keep the code readable the OSX behaviour is unconditional,
6183 * according to the POSIX spec this should be safe on all unix-y
6184 * systems.
6185 */
6186 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006187 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006188
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006189#ifdef __APPLE__
6190 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6191 * there are more groups than can fit in grouplist. Therefore, on OS X
6192 * always first call getgroups with length 0 to get the actual number
6193 * of groups.
6194 */
6195 n = getgroups(0, NULL);
6196 if (n < 0) {
6197 return posix_error();
6198 } else if (n <= MAX_GROUPS) {
6199 /* groups will fit in existing array */
6200 alt_grouplist = grouplist;
6201 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006202 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006203 if (alt_grouplist == NULL) {
6204 errno = EINVAL;
6205 return posix_error();
6206 }
6207 }
6208
6209 n = getgroups(n, alt_grouplist);
6210 if (n == -1) {
6211 if (alt_grouplist != grouplist) {
6212 PyMem_Free(alt_grouplist);
6213 }
6214 return posix_error();
6215 }
6216#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006217 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006218 if (n < 0) {
6219 if (errno == EINVAL) {
6220 n = getgroups(0, NULL);
6221 if (n == -1) {
6222 return posix_error();
6223 }
6224 if (n == 0) {
6225 /* Avoid malloc(0) */
6226 alt_grouplist = grouplist;
6227 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006228 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006229 if (alt_grouplist == NULL) {
6230 errno = EINVAL;
6231 return posix_error();
6232 }
6233 n = getgroups(n, alt_grouplist);
6234 if (n == -1) {
6235 PyMem_Free(alt_grouplist);
6236 return posix_error();
6237 }
6238 }
6239 } else {
6240 return posix_error();
6241 }
6242 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006243#endif
6244
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006245 result = PyList_New(n);
6246 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006247 int i;
6248 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006249 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006251 Py_DECREF(result);
6252 result = NULL;
6253 break;
Fred Drakec9680921999-12-13 16:37:25 +00006254 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006255 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006256 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006257 }
6258
6259 if (alt_grouplist != grouplist) {
6260 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006262
Fred Drakec9680921999-12-13 16:37:25 +00006263 return result;
6264}
Larry Hastings2f936352014-08-05 14:04:04 +10006265#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006266
Antoine Pitroub7572f02009-12-02 20:46:48 +00006267#ifdef HAVE_INITGROUPS
6268PyDoc_STRVAR(posix_initgroups__doc__,
6269"initgroups(username, gid) -> None\n\n\
6270Call the system initgroups() to initialize the group access list with all of\n\
6271the groups of which the specified username is a member, plus the specified\n\
6272group id.");
6273
Larry Hastings2f936352014-08-05 14:04:04 +10006274/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006275static PyObject *
6276posix_initgroups(PyObject *self, PyObject *args)
6277{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006278 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006279 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006280 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006281#ifdef __APPLE__
6282 int gid;
6283#else
6284 gid_t gid;
6285#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006286
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006287#ifdef __APPLE__
6288 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6289 PyUnicode_FSConverter, &oname,
6290 &gid))
6291#else
6292 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6293 PyUnicode_FSConverter, &oname,
6294 _Py_Gid_Converter, &gid))
6295#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006296 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006297 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006298
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006299 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006300 Py_DECREF(oname);
6301 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006303
Victor Stinner8c62be82010-05-06 00:08:46 +00006304 Py_INCREF(Py_None);
6305 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006306}
Larry Hastings2f936352014-08-05 14:04:04 +10006307#endif /* HAVE_INITGROUPS */
6308
Antoine Pitroub7572f02009-12-02 20:46:48 +00006309
Martin v. Löwis606edc12002-06-13 21:09:11 +00006310#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006311/*[clinic input]
6312os.getpgid
6313
6314 pid: pid_t
6315
6316Call the system call getpgid(), and return the result.
6317[clinic start generated code]*/
6318
Larry Hastings2f936352014-08-05 14:04:04 +10006319static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006320os_getpgid_impl(PyObject *module, pid_t pid)
6321/*[clinic end generated code: output=1db95a97be205d18 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006322{
6323 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 if (pgid < 0)
6325 return posix_error();
6326 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006327}
6328#endif /* HAVE_GETPGID */
6329
6330
Guido van Rossumb6775db1994-08-01 11:34:53 +00006331#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006332/*[clinic input]
6333os.getpgrp
6334
6335Return the current process group id.
6336[clinic start generated code]*/
6337
Larry Hastings2f936352014-08-05 14:04:04 +10006338static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006339os_getpgrp_impl(PyObject *module)
6340/*[clinic end generated code: output=c4fc381e51103cf3 input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006341{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006342#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006344#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006346#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006347}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006348#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006349
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006350
Guido van Rossumb6775db1994-08-01 11:34:53 +00006351#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006352/*[clinic input]
6353os.setpgrp
6354
6355Make the current process the leader of its process group.
6356[clinic start generated code]*/
6357
Larry Hastings2f936352014-08-05 14:04:04 +10006358static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006359os_setpgrp_impl(PyObject *module)
6360/*[clinic end generated code: output=2554735b0a60f0a0 input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006361{
Guido van Rossum64933891994-10-20 21:56:42 +00006362#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006363 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006364#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006365 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006366#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006367 return posix_error();
6368 Py_INCREF(Py_None);
6369 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006370}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006371#endif /* HAVE_SETPGRP */
6372
Guido van Rossumad0ee831995-03-01 10:34:45 +00006373#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006374
6375#ifdef MS_WINDOWS
6376#include <tlhelp32.h>
6377
6378static PyObject*
6379win32_getppid()
6380{
6381 HANDLE snapshot;
6382 pid_t mypid;
6383 PyObject* result = NULL;
6384 BOOL have_record;
6385 PROCESSENTRY32 pe;
6386
6387 mypid = getpid(); /* This function never fails */
6388
6389 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6390 if (snapshot == INVALID_HANDLE_VALUE)
6391 return PyErr_SetFromWindowsErr(GetLastError());
6392
6393 pe.dwSize = sizeof(pe);
6394 have_record = Process32First(snapshot, &pe);
6395 while (have_record) {
6396 if (mypid == (pid_t)pe.th32ProcessID) {
6397 /* We could cache the ulong value in a static variable. */
6398 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6399 break;
6400 }
6401
6402 have_record = Process32Next(snapshot, &pe);
6403 }
6404
6405 /* If our loop exits and our pid was not found (result will be NULL)
6406 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6407 * error anyway, so let's raise it. */
6408 if (!result)
6409 result = PyErr_SetFromWindowsErr(GetLastError());
6410
6411 CloseHandle(snapshot);
6412
6413 return result;
6414}
6415#endif /*MS_WINDOWS*/
6416
Larry Hastings2f936352014-08-05 14:04:04 +10006417
6418/*[clinic input]
6419os.getppid
6420
6421Return the parent's process id.
6422
6423If the parent process has already exited, Windows machines will still
6424return its id; others systems will return the id of the 'init' process (1).
6425[clinic start generated code]*/
6426
Larry Hastings2f936352014-08-05 14:04:04 +10006427static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006428os_getppid_impl(PyObject *module)
6429/*[clinic end generated code: output=43b2a946a8c603b4 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006430{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006431#ifdef MS_WINDOWS
6432 return win32_getppid();
6433#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006435#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006436}
6437#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006438
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006439
Fred Drake12c6e2d1999-12-14 21:25:03 +00006440#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006441/*[clinic input]
6442os.getlogin
6443
6444Return the actual login name.
6445[clinic start generated code]*/
6446
Larry Hastings2f936352014-08-05 14:04:04 +10006447static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006448os_getlogin_impl(PyObject *module)
6449/*[clinic end generated code: output=a32e66a7e5715dac input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006450{
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006452#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006453 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006454 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006455
6456 if (GetUserNameW(user_name, &num_chars)) {
6457 /* num_chars is the number of unicode chars plus null terminator */
6458 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006459 }
6460 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006461 result = PyErr_SetFromWindowsErr(GetLastError());
6462#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006463 char *name;
6464 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006465
Victor Stinner8c62be82010-05-06 00:08:46 +00006466 errno = 0;
6467 name = getlogin();
6468 if (name == NULL) {
6469 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006470 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006471 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006472 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006473 }
6474 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006475 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006476 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006477#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006478 return result;
6479}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006480#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006481
Larry Hastings2f936352014-08-05 14:04:04 +10006482
Guido van Rossumad0ee831995-03-01 10:34:45 +00006483#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006484/*[clinic input]
6485os.getuid
6486
6487Return the current process's user id.
6488[clinic start generated code]*/
6489
Larry Hastings2f936352014-08-05 14:04:04 +10006490static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006491os_getuid_impl(PyObject *module)
6492/*[clinic end generated code: output=415c0b401ebed11a input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006493{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006494 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006495}
Larry Hastings2f936352014-08-05 14:04:04 +10006496#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006497
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006498
Brian Curtineb24d742010-04-12 17:16:38 +00006499#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006500#define HAVE_KILL
6501#endif /* MS_WINDOWS */
6502
6503#ifdef HAVE_KILL
6504/*[clinic input]
6505os.kill
6506
6507 pid: pid_t
6508 signal: Py_ssize_t
6509 /
6510
6511Kill a process with a signal.
6512[clinic start generated code]*/
6513
Larry Hastings2f936352014-08-05 14:04:04 +10006514static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006515os_kill_impl(PyObject *module, pid_t pid, Py_ssize_t signal)
6516/*[clinic end generated code: output=8e346a6701c88568 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006517#ifndef MS_WINDOWS
6518{
6519 if (kill(pid, (int)signal) == -1)
6520 return posix_error();
6521 Py_RETURN_NONE;
6522}
6523#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006524{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006525 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006526 DWORD sig = (DWORD)signal;
6527 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006529
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 /* Console processes which share a common console can be sent CTRL+C or
6531 CTRL+BREAK events, provided they handle said events. */
6532 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006533 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006534 err = GetLastError();
6535 PyErr_SetFromWindowsErr(err);
6536 }
6537 else
6538 Py_RETURN_NONE;
6539 }
Brian Curtineb24d742010-04-12 17:16:38 +00006540
Victor Stinner8c62be82010-05-06 00:08:46 +00006541 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6542 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006543 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006544 if (handle == NULL) {
6545 err = GetLastError();
6546 return PyErr_SetFromWindowsErr(err);
6547 }
Brian Curtineb24d742010-04-12 17:16:38 +00006548
Victor Stinner8c62be82010-05-06 00:08:46 +00006549 if (TerminateProcess(handle, sig) == 0) {
6550 err = GetLastError();
6551 result = PyErr_SetFromWindowsErr(err);
6552 } else {
6553 Py_INCREF(Py_None);
6554 result = Py_None;
6555 }
Brian Curtineb24d742010-04-12 17:16:38 +00006556
Victor Stinner8c62be82010-05-06 00:08:46 +00006557 CloseHandle(handle);
6558 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006559}
Larry Hastings2f936352014-08-05 14:04:04 +10006560#endif /* !MS_WINDOWS */
6561#endif /* HAVE_KILL */
6562
6563
6564#ifdef HAVE_KILLPG
6565/*[clinic input]
6566os.killpg
6567
6568 pgid: pid_t
6569 signal: int
6570 /
6571
6572Kill a process group with a signal.
6573[clinic start generated code]*/
6574
Larry Hastings2f936352014-08-05 14:04:04 +10006575static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006576os_killpg_impl(PyObject *module, pid_t pgid, int signal)
6577/*[clinic end generated code: output=6dbcd2f1fdf5fdba input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006578{
6579 /* XXX some man pages make the `pgid` parameter an int, others
6580 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6581 take the same type. Moreover, pid_t is always at least as wide as
6582 int (else compilation of this module fails), which is safe. */
6583 if (killpg(pgid, signal) == -1)
6584 return posix_error();
6585 Py_RETURN_NONE;
6586}
6587#endif /* HAVE_KILLPG */
6588
Brian Curtineb24d742010-04-12 17:16:38 +00006589
Guido van Rossumc0125471996-06-28 18:55:32 +00006590#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006591#ifdef HAVE_SYS_LOCK_H
6592#include <sys/lock.h>
6593#endif
6594
Larry Hastings2f936352014-08-05 14:04:04 +10006595/*[clinic input]
6596os.plock
6597 op: int
6598 /
6599
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006600Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006601[clinic start generated code]*/
6602
Larry Hastings2f936352014-08-05 14:04:04 +10006603static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006604os_plock_impl(PyObject *module, int op)
6605/*[clinic end generated code: output=81424167033b168e input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006606{
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 if (plock(op) == -1)
6608 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006609 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006610}
Larry Hastings2f936352014-08-05 14:04:04 +10006611#endif /* HAVE_PLOCK */
6612
Guido van Rossumc0125471996-06-28 18:55:32 +00006613
Guido van Rossumb6775db1994-08-01 11:34:53 +00006614#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006615/*[clinic input]
6616os.setuid
6617
6618 uid: uid_t
6619 /
6620
6621Set the current process's user id.
6622[clinic start generated code]*/
6623
Larry Hastings2f936352014-08-05 14:04:04 +10006624static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006625os_setuid_impl(PyObject *module, uid_t uid)
6626/*[clinic end generated code: output=a0a41fd0d1ec555f input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006627{
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 if (setuid(uid) < 0)
6629 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006630 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006631}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006632#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006633
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006634
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006635#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006636/*[clinic input]
6637os.seteuid
6638
6639 euid: uid_t
6640 /
6641
6642Set the current process's effective user id.
6643[clinic start generated code]*/
6644
Larry Hastings2f936352014-08-05 14:04:04 +10006645static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006646os_seteuid_impl(PyObject *module, uid_t euid)
6647/*[clinic end generated code: output=102e3ad98361519a input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006648{
6649 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006650 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006651 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006652}
6653#endif /* HAVE_SETEUID */
6654
Larry Hastings2f936352014-08-05 14:04:04 +10006655
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006656#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006657/*[clinic input]
6658os.setegid
6659
6660 egid: gid_t
6661 /
6662
6663Set the current process's effective group id.
6664[clinic start generated code]*/
6665
Larry Hastings2f936352014-08-05 14:04:04 +10006666static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006667os_setegid_impl(PyObject *module, gid_t egid)
6668/*[clinic end generated code: output=4e4b825a6a10258d input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006669{
6670 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006671 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006672 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006673}
6674#endif /* HAVE_SETEGID */
6675
Larry Hastings2f936352014-08-05 14:04:04 +10006676
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006677#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006678/*[clinic input]
6679os.setreuid
6680
6681 ruid: uid_t
6682 euid: uid_t
6683 /
6684
6685Set the current process's real and effective user ids.
6686[clinic start generated code]*/
6687
Larry Hastings2f936352014-08-05 14:04:04 +10006688static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006689os_setreuid_impl(PyObject *module, uid_t ruid, uid_t euid)
6690/*[clinic end generated code: output=62d991210006530a input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006691{
Victor Stinner8c62be82010-05-06 00:08:46 +00006692 if (setreuid(ruid, euid) < 0) {
6693 return posix_error();
6694 } else {
6695 Py_INCREF(Py_None);
6696 return Py_None;
6697 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006698}
6699#endif /* HAVE_SETREUID */
6700
Larry Hastings2f936352014-08-05 14:04:04 +10006701
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006702#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006703/*[clinic input]
6704os.setregid
6705
6706 rgid: gid_t
6707 egid: gid_t
6708 /
6709
6710Set the current process's real and effective group ids.
6711[clinic start generated code]*/
6712
Larry Hastings2f936352014-08-05 14:04:04 +10006713static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006714os_setregid_impl(PyObject *module, gid_t rgid, gid_t egid)
6715/*[clinic end generated code: output=aa803835cf5342f3 input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006716{
6717 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006719 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006720}
6721#endif /* HAVE_SETREGID */
6722
Larry Hastings2f936352014-08-05 14:04:04 +10006723
Guido van Rossumb6775db1994-08-01 11:34:53 +00006724#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006725/*[clinic input]
6726os.setgid
6727 gid: gid_t
6728 /
6729
6730Set the current process's group id.
6731[clinic start generated code]*/
6732
Larry Hastings2f936352014-08-05 14:04:04 +10006733static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006734os_setgid_impl(PyObject *module, gid_t gid)
6735/*[clinic end generated code: output=bdccd7403f6ad8c3 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006736{
Victor Stinner8c62be82010-05-06 00:08:46 +00006737 if (setgid(gid) < 0)
6738 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006739 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006740}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006741#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006742
Larry Hastings2f936352014-08-05 14:04:04 +10006743
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006744#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006745/*[clinic input]
6746os.setgroups
6747
6748 groups: object
6749 /
6750
6751Set the groups of the current process to list.
6752[clinic start generated code]*/
6753
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006754static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006755os_setgroups(PyObject *module, PyObject *groups)
6756/*[clinic end generated code: output=3fcb32aad58c5ecd input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006757{
Victor Stinner8c62be82010-05-06 00:08:46 +00006758 int i, len;
6759 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006760
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (!PySequence_Check(groups)) {
6762 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6763 return NULL;
6764 }
6765 len = PySequence_Size(groups);
6766 if (len > MAX_GROUPS) {
6767 PyErr_SetString(PyExc_ValueError, "too many groups");
6768 return NULL;
6769 }
6770 for(i = 0; i < len; i++) {
6771 PyObject *elem;
6772 elem = PySequence_GetItem(groups, i);
6773 if (!elem)
6774 return NULL;
6775 if (!PyLong_Check(elem)) {
6776 PyErr_SetString(PyExc_TypeError,
6777 "groups must be integers");
6778 Py_DECREF(elem);
6779 return NULL;
6780 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006781 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 Py_DECREF(elem);
6783 return NULL;
6784 }
6785 }
6786 Py_DECREF(elem);
6787 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006788
Victor Stinner8c62be82010-05-06 00:08:46 +00006789 if (setgroups(len, grouplist) < 0)
6790 return posix_error();
6791 Py_INCREF(Py_None);
6792 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006793}
6794#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006795
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006796#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6797static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006798wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006799{
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 PyObject *result;
6801 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006802 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006803
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 if (pid == -1)
6805 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006806
Victor Stinner8c62be82010-05-06 00:08:46 +00006807 if (struct_rusage == NULL) {
6808 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6809 if (m == NULL)
6810 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006811 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006812 Py_DECREF(m);
6813 if (struct_rusage == NULL)
6814 return NULL;
6815 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006816
Victor Stinner8c62be82010-05-06 00:08:46 +00006817 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6818 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6819 if (!result)
6820 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006821
6822#ifndef doubletime
6823#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6824#endif
6825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006827 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006828 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006829 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006830#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6832 SET_INT(result, 2, ru->ru_maxrss);
6833 SET_INT(result, 3, ru->ru_ixrss);
6834 SET_INT(result, 4, ru->ru_idrss);
6835 SET_INT(result, 5, ru->ru_isrss);
6836 SET_INT(result, 6, ru->ru_minflt);
6837 SET_INT(result, 7, ru->ru_majflt);
6838 SET_INT(result, 8, ru->ru_nswap);
6839 SET_INT(result, 9, ru->ru_inblock);
6840 SET_INT(result, 10, ru->ru_oublock);
6841 SET_INT(result, 11, ru->ru_msgsnd);
6842 SET_INT(result, 12, ru->ru_msgrcv);
6843 SET_INT(result, 13, ru->ru_nsignals);
6844 SET_INT(result, 14, ru->ru_nvcsw);
6845 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846#undef SET_INT
6847
Victor Stinner8c62be82010-05-06 00:08:46 +00006848 if (PyErr_Occurred()) {
6849 Py_DECREF(result);
6850 return NULL;
6851 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006852
Victor Stinner8c62be82010-05-06 00:08:46 +00006853 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006854}
6855#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6856
Larry Hastings2f936352014-08-05 14:04:04 +10006857
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006858#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006859/*[clinic input]
6860os.wait3
6861
6862 options: int
6863Wait for completion of a child process.
6864
6865Returns a tuple of information about the child process:
6866 (pid, status, rusage)
6867[clinic start generated code]*/
6868
Larry Hastings2f936352014-08-05 14:04:04 +10006869static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006870os_wait3_impl(PyObject *module, int options)
6871/*[clinic end generated code: output=92c3224e6f28217a input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872{
Victor Stinner8c62be82010-05-06 00:08:46 +00006873 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006874 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006875 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006876 WAIT_TYPE status;
6877 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006878
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006879 do {
6880 Py_BEGIN_ALLOW_THREADS
6881 pid = wait3(&status, options, &ru);
6882 Py_END_ALLOW_THREADS
6883 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6884 if (pid < 0)
6885 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Victor Stinner4195b5c2012-02-08 23:03:19 +01006887 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888}
6889#endif /* HAVE_WAIT3 */
6890
Larry Hastings2f936352014-08-05 14:04:04 +10006891
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006892#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006893/*[clinic input]
6894
6895os.wait4
6896
6897 pid: pid_t
6898 options: int
6899
6900Wait for completion of a specific child process.
6901
6902Returns a tuple of information about the child process:
6903 (pid, status, rusage)
6904[clinic start generated code]*/
6905
Larry Hastings2f936352014-08-05 14:04:04 +10006906static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006907os_wait4_impl(PyObject *module, pid_t pid, int options)
6908/*[clinic end generated code: output=66195aa507b35f70 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006909{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006910 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006911 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006913 WAIT_TYPE status;
6914 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006915
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006916 do {
6917 Py_BEGIN_ALLOW_THREADS
6918 res = wait4(pid, &status, options, &ru);
6919 Py_END_ALLOW_THREADS
6920 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6921 if (res < 0)
6922 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006923
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006924 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006925}
6926#endif /* HAVE_WAIT4 */
6927
Larry Hastings2f936352014-08-05 14:04:04 +10006928
Ross Lagerwall7807c352011-03-17 20:20:30 +02006929#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006930/*[clinic input]
6931os.waitid
6932
6933 idtype: idtype_t
6934 Must be one of be P_PID, P_PGID or P_ALL.
6935 id: id_t
6936 The id to wait on.
6937 options: int
6938 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6939 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6940 /
6941
6942Returns the result of waiting for a process or processes.
6943
6944Returns either waitid_result or None if WNOHANG is specified and there are
6945no children in a waitable state.
6946[clinic start generated code]*/
6947
Larry Hastings2f936352014-08-05 14:04:04 +10006948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03006949os_waitid_impl(PyObject *module, idtype_t idtype, id_t id, int options)
6950/*[clinic end generated code: output=5d2e1c0bde61f4d8 input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006951{
6952 PyObject *result;
6953 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006954 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006955 siginfo_t si;
6956 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006957
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006958 do {
6959 Py_BEGIN_ALLOW_THREADS
6960 res = waitid(idtype, id, &si, options);
6961 Py_END_ALLOW_THREADS
6962 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6963 if (res < 0)
6964 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006965
6966 if (si.si_pid == 0)
6967 Py_RETURN_NONE;
6968
6969 result = PyStructSequence_New(&WaitidResultType);
6970 if (!result)
6971 return NULL;
6972
6973 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006974 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006975 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6976 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6977 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6978 if (PyErr_Occurred()) {
6979 Py_DECREF(result);
6980 return NULL;
6981 }
6982
6983 return result;
6984}
Larry Hastings2f936352014-08-05 14:04:04 +10006985#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006986
Larry Hastings2f936352014-08-05 14:04:04 +10006987
6988#if defined(HAVE_WAITPID)
6989/*[clinic input]
6990os.waitpid
6991 pid: pid_t
6992 options: int
6993 /
6994
6995Wait for completion of a given child process.
6996
6997Returns a tuple of information regarding the child process:
6998 (pid, status)
6999
7000The options argument is ignored on Windows.
7001[clinic start generated code]*/
7002
Larry Hastings2f936352014-08-05 14:04:04 +10007003static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007004os_waitpid_impl(PyObject *module, pid_t pid, int options)
7005/*[clinic end generated code: output=5c37c06887a20270 input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007006{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007007 pid_t res;
7008 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007009 WAIT_TYPE status;
7010 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00007011
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007012 do {
7013 Py_BEGIN_ALLOW_THREADS
7014 res = waitpid(pid, &status, options);
7015 Py_END_ALLOW_THREADS
7016 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7017 if (res < 0)
7018 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007019
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007020 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007021}
Tim Petersab034fa2002-02-01 11:27:43 +00007022#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007023/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007024/*[clinic input]
7025os.waitpid
7026 pid: Py_intptr_t
7027 options: int
7028 /
7029
7030Wait for completion of a given process.
7031
7032Returns a tuple of information regarding the process:
7033 (pid, status << 8)
7034
7035The options argument is ignored on Windows.
7036[clinic start generated code]*/
7037
Larry Hastings2f936352014-08-05 14:04:04 +10007038static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007039os_waitpid_impl(PyObject *module, Py_intptr_t pid, int options)
7040/*[clinic end generated code: output=15f1ce005a346b09 input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007041{
7042 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007043 Py_intptr_t res;
7044 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007045
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007046 do {
7047 Py_BEGIN_ALLOW_THREADS
Steve Dower11f43262016-11-19 18:33:39 -08007048 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007049 res = _cwait(&status, pid, options);
Steve Dower11f43262016-11-19 18:33:39 -08007050 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007051 Py_END_ALLOW_THREADS
7052 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007053 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007054 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007055
Victor Stinner8c62be82010-05-06 00:08:46 +00007056 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007057 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007058}
Larry Hastings2f936352014-08-05 14:04:04 +10007059#endif
7060
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Guido van Rossumad0ee831995-03-01 10:34:45 +00007062#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007063/*[clinic input]
7064os.wait
7065
7066Wait for completion of a child process.
7067
7068Returns a tuple of information about the child process:
7069 (pid, status)
7070[clinic start generated code]*/
7071
Larry Hastings2f936352014-08-05 14:04:04 +10007072static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007073os_wait_impl(PyObject *module)
7074/*[clinic end generated code: output=6bc419ac32fb364b input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007075{
Victor Stinner8c62be82010-05-06 00:08:46 +00007076 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007077 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 WAIT_TYPE status;
7079 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007080
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007081 do {
7082 Py_BEGIN_ALLOW_THREADS
7083 pid = wait(&status);
7084 Py_END_ALLOW_THREADS
7085 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7086 if (pid < 0)
7087 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007088
Victor Stinner8c62be82010-05-06 00:08:46 +00007089 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007090}
Larry Hastings2f936352014-08-05 14:04:04 +10007091#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007092
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007093
Larry Hastings9cf065c2012-06-22 16:30:09 -07007094#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7095PyDoc_STRVAR(readlink__doc__,
7096"readlink(path, *, dir_fd=None) -> path\n\n\
7097Return a string representing the path to which the symbolic link points.\n\
7098\n\
7099If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7100 and path should be relative; path will then be relative to that directory.\n\
7101dir_fd may not be implemented on your platform.\n\
7102 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007103#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007104
Guido van Rossumb6775db1994-08-01 11:34:53 +00007105#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007106
Larry Hastings2f936352014-08-05 14:04:04 +10007107/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007108static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007109posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007110{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007111 path_t path;
7112 int dir_fd = DEFAULT_DIR_FD;
Christian Heimes3cb091e2016-09-23 20:24:28 +02007113 char buffer[MAXPATHLEN+1];
Larry Hastings9cf065c2012-06-22 16:30:09 -07007114 ssize_t length;
7115 PyObject *return_value = NULL;
7116 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007117
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007119 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007120 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7121 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007122 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007123 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007124
Victor Stinner8c62be82010-05-06 00:08:46 +00007125 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007126#ifdef HAVE_READLINKAT
7127 if (dir_fd != DEFAULT_DIR_FD)
Christian Heimes3cb091e2016-09-23 20:24:28 +02007128 length = readlinkat(dir_fd, path.narrow, buffer, MAXPATHLEN);
Victor Stinnera45598a2010-05-14 16:35:39 +00007129 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007130#endif
Christian Heimes3cb091e2016-09-23 20:24:28 +02007131 length = readlink(path.narrow, buffer, MAXPATHLEN);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007132 Py_END_ALLOW_THREADS
7133
7134 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007135 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007136 goto exit;
7137 }
Christian Heimes3cb091e2016-09-23 20:24:28 +02007138 buffer[length] = '\0';
Larry Hastings9cf065c2012-06-22 16:30:09 -07007139
7140 if (PyUnicode_Check(path.object))
7141 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7142 else
7143 return_value = PyBytes_FromStringAndSize(buffer, length);
7144exit:
7145 path_cleanup(&path);
7146 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007147}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007148
Guido van Rossumb6775db1994-08-01 11:34:53 +00007149#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007150
Larry Hastings2f936352014-08-05 14:04:04 +10007151#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7152
7153static PyObject *
7154win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7155{
7156 wchar_t *path;
7157 DWORD n_bytes_returned;
7158 DWORD io_result;
7159 PyObject *po, *result;
7160 int dir_fd;
7161 HANDLE reparse_point_handle;
7162
7163 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7164 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7165 wchar_t *print_name;
7166
7167 static char *keywords[] = {"path", "dir_fd", NULL};
7168
7169 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7170 &po,
7171 dir_fd_unavailable, &dir_fd
7172 ))
7173 return NULL;
7174
7175 path = PyUnicode_AsUnicode(po);
7176 if (path == NULL)
7177 return NULL;
7178
7179 /* First get a handle to the reparse point */
7180 Py_BEGIN_ALLOW_THREADS
7181 reparse_point_handle = CreateFileW(
7182 path,
7183 0,
7184 0,
7185 0,
7186 OPEN_EXISTING,
7187 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7188 0);
7189 Py_END_ALLOW_THREADS
7190
7191 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7192 return win32_error_object("readlink", po);
7193
7194 Py_BEGIN_ALLOW_THREADS
7195 /* New call DeviceIoControl to read the reparse point */
7196 io_result = DeviceIoControl(
7197 reparse_point_handle,
7198 FSCTL_GET_REPARSE_POINT,
7199 0, 0, /* in buffer */
7200 target_buffer, sizeof(target_buffer),
7201 &n_bytes_returned,
7202 0 /* we're not using OVERLAPPED_IO */
7203 );
7204 CloseHandle(reparse_point_handle);
7205 Py_END_ALLOW_THREADS
7206
7207 if (io_result==0)
7208 return win32_error_object("readlink", po);
7209
7210 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7211 {
7212 PyErr_SetString(PyExc_ValueError,
7213 "not a symbolic link");
7214 return NULL;
7215 }
7216 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7217 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7218
7219 result = PyUnicode_FromWideChar(print_name,
7220 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7221 return result;
7222}
7223
7224#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7225
7226
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007227
Larry Hastings9cf065c2012-06-22 16:30:09 -07007228#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007229
7230#if defined(MS_WINDOWS)
7231
7232/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7233static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7234static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007235
Larry Hastings9cf065c2012-06-22 16:30:09 -07007236static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007237check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007238{
7239 HINSTANCE hKernel32;
7240 /* only recheck */
7241 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7242 return 1;
7243 hKernel32 = GetModuleHandleW(L"KERNEL32");
7244 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7245 "CreateSymbolicLinkW");
7246 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7247 "CreateSymbolicLinkA");
7248 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7249}
7250
Victor Stinner31b3b922013-06-05 01:49:17 +02007251/* Remove the last portion of the path */
7252static void
7253_dirnameW(WCHAR *path)
7254{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007255 WCHAR *ptr;
7256
7257 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007258 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007259 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007260 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007261 }
7262 *ptr = 0;
7263}
7264
Victor Stinner31b3b922013-06-05 01:49:17 +02007265/* Remove the last portion of the path */
7266static void
7267_dirnameA(char *path)
7268{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007269 char *ptr;
7270
7271 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007272 for(ptr = path + strlen(path); ptr != path; ptr--) {
7273 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007274 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007275 }
7276 *ptr = 0;
7277}
7278
Victor Stinner31b3b922013-06-05 01:49:17 +02007279/* Is this path absolute? */
7280static int
7281_is_absW(const WCHAR *path)
7282{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007283 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7284
7285}
7286
Victor Stinner31b3b922013-06-05 01:49:17 +02007287/* Is this path absolute? */
7288static int
7289_is_absA(const char *path)
7290{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7292
7293}
7294
Victor Stinner31b3b922013-06-05 01:49:17 +02007295/* join root and rest with a backslash */
7296static void
7297_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7298{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007299 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007300
Victor Stinner31b3b922013-06-05 01:49:17 +02007301 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007302 wcscpy(dest_path, rest);
7303 return;
7304 }
7305
7306 root_len = wcslen(root);
7307
7308 wcscpy(dest_path, root);
7309 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007310 dest_path[root_len] = L'\\';
7311 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007312 }
7313 wcscpy(dest_path+root_len, rest);
7314}
7315
Victor Stinner31b3b922013-06-05 01:49:17 +02007316/* join root and rest with a backslash */
7317static void
7318_joinA(char *dest_path, const char *root, const char *rest)
7319{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007320 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007321
Victor Stinner31b3b922013-06-05 01:49:17 +02007322 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007323 strcpy(dest_path, rest);
7324 return;
7325 }
7326
7327 root_len = strlen(root);
7328
7329 strcpy(dest_path, root);
7330 if(root_len) {
7331 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007332 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007333 }
7334 strcpy(dest_path+root_len, rest);
7335}
7336
Victor Stinner31b3b922013-06-05 01:49:17 +02007337/* Return True if the path at src relative to dest is a directory */
7338static int
7339_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007340{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007341 WIN32_FILE_ATTRIBUTE_DATA src_info;
7342 WCHAR dest_parent[MAX_PATH];
7343 WCHAR src_resolved[MAX_PATH] = L"";
7344
7345 /* dest_parent = os.path.dirname(dest) */
7346 wcscpy(dest_parent, dest);
7347 _dirnameW(dest_parent);
7348 /* src_resolved = os.path.join(dest_parent, src) */
7349 _joinW(src_resolved, dest_parent, src);
7350 return (
7351 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7352 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7353 );
7354}
7355
Victor Stinner31b3b922013-06-05 01:49:17 +02007356/* Return True if the path at src relative to dest is a directory */
7357static int
7358_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007359{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007360 WIN32_FILE_ATTRIBUTE_DATA src_info;
7361 char dest_parent[MAX_PATH];
7362 char src_resolved[MAX_PATH] = "";
7363
7364 /* dest_parent = os.path.dirname(dest) */
7365 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007366 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007367 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007368 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007369 return (
7370 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7371 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7372 );
7373}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007375
Larry Hastings2f936352014-08-05 14:04:04 +10007376
7377/*[clinic input]
7378os.symlink
7379 src: path_t
7380 dst: path_t
7381 target_is_directory: bool = False
7382 *
7383 dir_fd: dir_fd(requires='symlinkat')=None
7384
7385# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7386
7387Create a symbolic link pointing to src named dst.
7388
7389target_is_directory is required on Windows if the target is to be
7390 interpreted as a directory. (On Windows, symlink requires
7391 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7392 target_is_directory is ignored on non-Windows platforms.
7393
7394If dir_fd is not None, it should be a file descriptor open to a directory,
7395 and path should be relative; path will then be relative to that directory.
7396dir_fd may not be implemented on your platform.
7397 If it is unavailable, using it will raise a NotImplementedError.
7398
7399[clinic start generated code]*/
7400
Larry Hastings2f936352014-08-05 14:04:04 +10007401static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007402os_symlink_impl(PyObject *module, path_t *src, path_t *dst,
Larry Hastings89964c42015-04-14 18:07:59 -04007403 int target_is_directory, int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007404/*[clinic end generated code: output=08ca9f3f3cf960f6 input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007405{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007406#ifdef MS_WINDOWS
7407 DWORD result;
7408#else
7409 int result;
7410#endif
7411
Larry Hastings9cf065c2012-06-22 16:30:09 -07007412#ifdef MS_WINDOWS
7413 if (!check_CreateSymbolicLink()) {
7414 PyErr_SetString(PyExc_NotImplementedError,
7415 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007416 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007417 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418 if (!win32_can_symlink) {
7419 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007420 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007421 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422#endif
7423
Larry Hastings2f936352014-08-05 14:04:04 +10007424 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007425 PyErr_SetString(PyExc_ValueError,
7426 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007427 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007428 }
7429
7430#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007431
Larry Hastings9cf065c2012-06-22 16:30:09 -07007432 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007433 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007434 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007435 target_is_directory |= _check_dirW(src->wide, dst->wide);
7436 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007437 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007438 }
7439 else {
7440 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007441 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7442 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007443 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007444 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007445 Py_END_ALLOW_THREADS
7446
Larry Hastings2f936352014-08-05 14:04:04 +10007447 if (!result)
7448 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007449
7450#else
7451
7452 Py_BEGIN_ALLOW_THREADS
7453#if HAVE_SYMLINKAT
7454 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007455 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007456 else
7457#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007458 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007459 Py_END_ALLOW_THREADS
7460
Larry Hastings2f936352014-08-05 14:04:04 +10007461 if (result)
7462 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007463#endif
7464
Larry Hastings2f936352014-08-05 14:04:04 +10007465 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007466}
7467#endif /* HAVE_SYMLINK */
7468
Larry Hastings9cf065c2012-06-22 16:30:09 -07007469
Brian Curtind40e6f72010-07-08 21:39:08 +00007470
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007471
Larry Hastings605a62d2012-06-24 04:33:36 -07007472static PyStructSequence_Field times_result_fields[] = {
7473 {"user", "user time"},
7474 {"system", "system time"},
7475 {"children_user", "user time of children"},
7476 {"children_system", "system time of children"},
7477 {"elapsed", "elapsed time since an arbitrary point in the past"},
7478 {NULL}
7479};
7480
7481PyDoc_STRVAR(times_result__doc__,
7482"times_result: Result from os.times().\n\n\
7483This object may be accessed either as a tuple of\n\
7484 (user, system, children_user, children_system, elapsed),\n\
7485or via the attributes user, system, children_user, children_system,\n\
7486and elapsed.\n\
7487\n\
7488See os.times for more information.");
7489
7490static PyStructSequence_Desc times_result_desc = {
7491 "times_result", /* name */
7492 times_result__doc__, /* doc */
7493 times_result_fields,
7494 5
7495};
7496
7497static PyTypeObject TimesResultType;
7498
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007499#ifdef MS_WINDOWS
7500#define HAVE_TIMES /* mandatory, for the method table */
7501#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007502
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007503#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007504
7505static PyObject *
7506build_times_result(double user, double system,
7507 double children_user, double children_system,
7508 double elapsed)
7509{
7510 PyObject *value = PyStructSequence_New(&TimesResultType);
7511 if (value == NULL)
7512 return NULL;
7513
7514#define SET(i, field) \
7515 { \
7516 PyObject *o = PyFloat_FromDouble(field); \
7517 if (!o) { \
7518 Py_DECREF(value); \
7519 return NULL; \
7520 } \
7521 PyStructSequence_SET_ITEM(value, i, o); \
7522 } \
7523
7524 SET(0, user);
7525 SET(1, system);
7526 SET(2, children_user);
7527 SET(3, children_system);
7528 SET(4, elapsed);
7529
7530#undef SET
7531
7532 return value;
7533}
7534
Larry Hastings605a62d2012-06-24 04:33:36 -07007535
Larry Hastings2f936352014-08-05 14:04:04 +10007536#ifndef MS_WINDOWS
7537#define NEED_TICKS_PER_SECOND
7538static long ticks_per_second = -1;
7539#endif /* MS_WINDOWS */
7540
7541/*[clinic input]
7542os.times
7543
7544Return a collection containing process timing information.
7545
7546The object returned behaves like a named tuple with these fields:
7547 (utime, stime, cutime, cstime, elapsed_time)
7548All fields are floating point numbers.
7549[clinic start generated code]*/
7550
Larry Hastings2f936352014-08-05 14:04:04 +10007551static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007552os_times_impl(PyObject *module)
7553/*[clinic end generated code: output=35f640503557d32a input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007554#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007555{
Victor Stinner8c62be82010-05-06 00:08:46 +00007556 FILETIME create, exit, kernel, user;
7557 HANDLE hProc;
7558 hProc = GetCurrentProcess();
7559 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7560 /* The fields of a FILETIME structure are the hi and lo part
7561 of a 64-bit value expressed in 100 nanosecond units.
7562 1e7 is one second in such units; 1e-7 the inverse.
7563 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7564 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007565 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007566 (double)(user.dwHighDateTime*429.4967296 +
7567 user.dwLowDateTime*1e-7),
7568 (double)(kernel.dwHighDateTime*429.4967296 +
7569 kernel.dwLowDateTime*1e-7),
7570 (double)0,
7571 (double)0,
7572 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007573}
Larry Hastings2f936352014-08-05 14:04:04 +10007574#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007575{
Larry Hastings2f936352014-08-05 14:04:04 +10007576
7577
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007578 struct tms t;
7579 clock_t c;
7580 errno = 0;
7581 c = times(&t);
7582 if (c == (clock_t) -1)
7583 return posix_error();
7584 return build_times_result(
7585 (double)t.tms_utime / ticks_per_second,
7586 (double)t.tms_stime / ticks_per_second,
7587 (double)t.tms_cutime / ticks_per_second,
7588 (double)t.tms_cstime / ticks_per_second,
7589 (double)c / ticks_per_second);
7590}
Larry Hastings2f936352014-08-05 14:04:04 +10007591#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007592#endif /* HAVE_TIMES */
7593
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007594
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007595#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007596/*[clinic input]
7597os.getsid
7598
7599 pid: pid_t
7600 /
7601
7602Call the system call getsid(pid) and return the result.
7603[clinic start generated code]*/
7604
Larry Hastings2f936352014-08-05 14:04:04 +10007605static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007606os_getsid_impl(PyObject *module, pid_t pid)
7607/*[clinic end generated code: output=112deae56b306460 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007608{
Victor Stinner8c62be82010-05-06 00:08:46 +00007609 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007610 sid = getsid(pid);
7611 if (sid < 0)
7612 return posix_error();
7613 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007614}
7615#endif /* HAVE_GETSID */
7616
7617
Guido van Rossumb6775db1994-08-01 11:34:53 +00007618#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007619/*[clinic input]
7620os.setsid
7621
7622Call the system call setsid().
7623[clinic start generated code]*/
7624
Larry Hastings2f936352014-08-05 14:04:04 +10007625static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007626os_setsid_impl(PyObject *module)
7627/*[clinic end generated code: output=e2ddedd517086d77 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007628{
Victor Stinner8c62be82010-05-06 00:08:46 +00007629 if (setsid() < 0)
7630 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007631 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007632}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007634
Larry Hastings2f936352014-08-05 14:04:04 +10007635
Guido van Rossumb6775db1994-08-01 11:34:53 +00007636#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007637/*[clinic input]
7638os.setpgid
7639
7640 pid: pid_t
7641 pgrp: pid_t
7642 /
7643
7644Call the system call setpgid(pid, pgrp).
7645[clinic start generated code]*/
7646
Larry Hastings2f936352014-08-05 14:04:04 +10007647static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007648os_setpgid_impl(PyObject *module, pid_t pid, pid_t pgrp)
7649/*[clinic end generated code: output=6461160319a43d6a input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007650{
Victor Stinner8c62be82010-05-06 00:08:46 +00007651 if (setpgid(pid, pgrp) < 0)
7652 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007653 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007654}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007655#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007656
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007657
Guido van Rossumb6775db1994-08-01 11:34:53 +00007658#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007659/*[clinic input]
7660os.tcgetpgrp
7661
7662 fd: int
7663 /
7664
7665Return the process group associated with the terminal specified by fd.
7666[clinic start generated code]*/
7667
Larry Hastings2f936352014-08-05 14:04:04 +10007668static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007669os_tcgetpgrp_impl(PyObject *module, int fd)
7670/*[clinic end generated code: output=f865e88be86c272b input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007671{
7672 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007673 if (pgid < 0)
7674 return posix_error();
7675 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007676}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007677#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007678
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007679
Guido van Rossumb6775db1994-08-01 11:34:53 +00007680#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007681/*[clinic input]
7682os.tcsetpgrp
7683
7684 fd: int
7685 pgid: pid_t
7686 /
7687
7688Set the process group associated with the terminal specified by fd.
7689[clinic start generated code]*/
7690
Larry Hastings2f936352014-08-05 14:04:04 +10007691static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007692os_tcsetpgrp_impl(PyObject *module, int fd, pid_t pgid)
7693/*[clinic end generated code: output=f1821a381b9daa39 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007694{
Victor Stinner8c62be82010-05-06 00:08:46 +00007695 if (tcsetpgrp(fd, pgid) < 0)
7696 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007697 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007698}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007699#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007700
Guido van Rossum687dd131993-05-17 08:34:16 +00007701/* Functions acting on file descriptors */
7702
Victor Stinnerdaf45552013-08-28 00:53:59 +02007703#ifdef O_CLOEXEC
7704extern int _Py_open_cloexec_works;
7705#endif
7706
Larry Hastings2f936352014-08-05 14:04:04 +10007707
7708/*[clinic input]
7709os.open -> int
7710 path: path_t
7711 flags: int
7712 mode: int = 0o777
7713 *
7714 dir_fd: dir_fd(requires='openat') = None
7715
7716# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7717
7718Open a file for low level IO. Returns a file descriptor (integer).
7719
7720If dir_fd is not None, it should be a file descriptor open to a directory,
7721 and path should be relative; path will then be relative to that directory.
7722dir_fd may not be implemented on your platform.
7723 If it is unavailable, using it will raise a NotImplementedError.
7724[clinic start generated code]*/
7725
Larry Hastings2f936352014-08-05 14:04:04 +10007726static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007727os_open_impl(PyObject *module, path_t *path, int flags, int mode, int dir_fd)
7728/*[clinic end generated code: output=abc7227888c8bc73 input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007729{
7730 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007731 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007732
Victor Stinnerdaf45552013-08-28 00:53:59 +02007733#ifdef O_CLOEXEC
7734 int *atomic_flag_works = &_Py_open_cloexec_works;
7735#elif !defined(MS_WINDOWS)
7736 int *atomic_flag_works = NULL;
7737#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007738
Victor Stinnerdaf45552013-08-28 00:53:59 +02007739#ifdef MS_WINDOWS
7740 flags |= O_NOINHERIT;
7741#elif defined(O_CLOEXEC)
7742 flags |= O_CLOEXEC;
7743#endif
7744
Steve Dower8fc89802015-04-12 00:26:27 -04007745 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007746 do {
7747 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007748#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007749 if (path->wide)
7750 fd = _wopen(path->wide, flags, mode);
7751 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007752#endif
7753#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007754 if (dir_fd != DEFAULT_DIR_FD)
7755 fd = openat(dir_fd, path->narrow, flags, mode);
7756 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007757#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007758 fd = open(path->narrow, flags, mode);
7759 Py_END_ALLOW_THREADS
7760 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007761 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007762
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007763 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007764 if (!async_err)
7765 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007766 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007767 }
7768
Victor Stinnerdaf45552013-08-28 00:53:59 +02007769#ifndef MS_WINDOWS
7770 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7771 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007772 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007773 }
7774#endif
7775
Larry Hastings2f936352014-08-05 14:04:04 +10007776 return fd;
7777}
7778
7779
7780/*[clinic input]
7781os.close
7782
7783 fd: int
7784
7785Close a file descriptor.
7786[clinic start generated code]*/
7787
Barry Warsaw53699e91996-12-10 23:23:01 +00007788static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007789os_close_impl(PyObject *module, int fd)
7790/*[clinic end generated code: output=2fe4e93602822c14 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007791{
Larry Hastings2f936352014-08-05 14:04:04 +10007792 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007793 if (!_PyVerify_fd(fd))
7794 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007795 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7796 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7797 * for more details.
7798 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007800 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007802 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007803 Py_END_ALLOW_THREADS
7804 if (res < 0)
7805 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007806 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007807}
7808
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007809
Larry Hastings2f936352014-08-05 14:04:04 +10007810/*[clinic input]
7811os.closerange
7812
7813 fd_low: int
7814 fd_high: int
7815 /
7816
7817Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7818[clinic start generated code]*/
7819
Larry Hastings2f936352014-08-05 14:04:04 +10007820static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007821os_closerange_impl(PyObject *module, int fd_low, int fd_high)
7822/*[clinic end generated code: output=0ce5c20fcda681c2 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007823{
7824 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007825 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007826 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007827 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007828 if (_PyVerify_fd(i))
7829 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007830 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007831 Py_END_ALLOW_THREADS
7832 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007833}
7834
7835
Larry Hastings2f936352014-08-05 14:04:04 +10007836/*[clinic input]
7837os.dup -> int
7838
7839 fd: int
7840 /
7841
7842Return a duplicate of a file descriptor.
7843[clinic start generated code]*/
7844
Larry Hastings2f936352014-08-05 14:04:04 +10007845static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007846os_dup_impl(PyObject *module, int fd)
7847/*[clinic end generated code: output=486f4860636b2a9f input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007848{
7849 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007850}
7851
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007852
Larry Hastings2f936352014-08-05 14:04:04 +10007853/*[clinic input]
7854os.dup2
7855 fd: int
7856 fd2: int
7857 inheritable: bool=True
7858
7859Duplicate file descriptor.
7860[clinic start generated code]*/
7861
Larry Hastings2f936352014-08-05 14:04:04 +10007862static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007863os_dup2_impl(PyObject *module, int fd, int fd2, int inheritable)
7864/*[clinic end generated code: output=db832a2d872ccc5f input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007865{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007866 int res;
7867#if defined(HAVE_DUP3) && \
7868 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7869 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7870 int dup3_works = -1;
7871#endif
7872
Victor Stinner8c62be82010-05-06 00:08:46 +00007873 if (!_PyVerify_fd_dup2(fd, fd2))
7874 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007875
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007876 /* dup2() can fail with EINTR if the target FD is already open, because it
7877 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7878 * upon close(), and therefore below.
7879 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007880#ifdef MS_WINDOWS
7881 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007882 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007883 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007884 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007885 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007886 if (res < 0)
7887 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007888
7889 /* Character files like console cannot be make non-inheritable */
7890 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7891 close(fd2);
7892 return NULL;
7893 }
7894
7895#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7896 Py_BEGIN_ALLOW_THREADS
7897 if (!inheritable)
7898 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7899 else
7900 res = dup2(fd, fd2);
7901 Py_END_ALLOW_THREADS
7902 if (res < 0)
7903 return posix_error();
7904
7905#else
7906
7907#ifdef HAVE_DUP3
7908 if (!inheritable && dup3_works != 0) {
7909 Py_BEGIN_ALLOW_THREADS
7910 res = dup3(fd, fd2, O_CLOEXEC);
7911 Py_END_ALLOW_THREADS
7912 if (res < 0) {
7913 if (dup3_works == -1)
7914 dup3_works = (errno != ENOSYS);
7915 if (dup3_works)
7916 return posix_error();
7917 }
7918 }
7919
7920 if (inheritable || dup3_works == 0)
7921 {
7922#endif
7923 Py_BEGIN_ALLOW_THREADS
7924 res = dup2(fd, fd2);
7925 Py_END_ALLOW_THREADS
7926 if (res < 0)
7927 return posix_error();
7928
7929 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7930 close(fd2);
7931 return NULL;
7932 }
7933#ifdef HAVE_DUP3
7934 }
7935#endif
7936
7937#endif
7938
Larry Hastings2f936352014-08-05 14:04:04 +10007939 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007940}
7941
Larry Hastings2f936352014-08-05 14:04:04 +10007942
Ross Lagerwall7807c352011-03-17 20:20:30 +02007943#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007944/*[clinic input]
7945os.lockf
7946
7947 fd: int
7948 An open file descriptor.
7949 command: int
7950 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7951 length: Py_off_t
7952 The number of bytes to lock, starting at the current position.
7953 /
7954
7955Apply, test or remove a POSIX lock on an open file descriptor.
7956
7957[clinic start generated code]*/
7958
Larry Hastings2f936352014-08-05 14:04:04 +10007959static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007960os_lockf_impl(PyObject *module, int fd, int command, Py_off_t length)
7961/*[clinic end generated code: output=af7051f3e7c29651 input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007962{
7963 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007964
7965 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007966 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007967 Py_END_ALLOW_THREADS
7968
7969 if (res < 0)
7970 return posix_error();
7971
7972 Py_RETURN_NONE;
7973}
Larry Hastings2f936352014-08-05 14:04:04 +10007974#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007975
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007976
Larry Hastings2f936352014-08-05 14:04:04 +10007977/*[clinic input]
7978os.lseek -> Py_off_t
7979
7980 fd: int
7981 position: Py_off_t
7982 how: int
7983 /
7984
7985Set the position of a file descriptor. Return the new position.
7986
7987Return the new cursor position in number of bytes
7988relative to the beginning of the file.
7989[clinic start generated code]*/
7990
Larry Hastings2f936352014-08-05 14:04:04 +10007991static Py_off_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03007992os_lseek_impl(PyObject *module, int fd, Py_off_t position, int how)
7993/*[clinic end generated code: output=971e1efb6b30bd2f input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007994{
7995 Py_off_t result;
7996
7997 if (!_PyVerify_fd(fd)) {
7998 posix_error();
7999 return -1;
8000 }
Guido van Rossum687dd131993-05-17 08:34:16 +00008001#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00008002 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
8003 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10008004 case 0: how = SEEK_SET; break;
8005 case 1: how = SEEK_CUR; break;
8006 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00008007 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00008008#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00008009
Victor Stinner8c62be82010-05-06 00:08:46 +00008010 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10008011 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00008012
Larry Hastings2f936352014-08-05 14:04:04 +10008013 if (!_PyVerify_fd(fd)) {
8014 posix_error();
8015 return -1;
8016 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008018 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008019#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008020 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008021#else
Larry Hastings2f936352014-08-05 14:04:04 +10008022 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008023#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008024 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008025 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008026 if (result < 0)
8027 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008028
Larry Hastings2f936352014-08-05 14:04:04 +10008029 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008030}
8031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008032
Larry Hastings2f936352014-08-05 14:04:04 +10008033/*[clinic input]
8034os.read
8035 fd: int
8036 length: Py_ssize_t
8037 /
8038
8039Read from a file descriptor. Returns a bytes object.
8040[clinic start generated code]*/
8041
Larry Hastings2f936352014-08-05 14:04:04 +10008042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008043os_read_impl(PyObject *module, int fd, Py_ssize_t length)
8044/*[clinic end generated code: output=dafbe9a5cddb987b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008045{
Victor Stinner8c62be82010-05-06 00:08:46 +00008046 Py_ssize_t n;
8047 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008048
8049 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008050 errno = EINVAL;
8051 return posix_error();
8052 }
Larry Hastings2f936352014-08-05 14:04:04 +10008053
8054#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008055 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008056 if (length > INT_MAX)
8057 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008058#endif
8059
8060 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008061 if (buffer == NULL)
8062 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008063
Victor Stinner66aab0c2015-03-19 22:53:20 +01008064 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8065 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008066 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008067 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008068 }
Larry Hastings2f936352014-08-05 14:04:04 +10008069
8070 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008071 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008072
Victor Stinner8c62be82010-05-06 00:08:46 +00008073 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008074}
8075
Ross Lagerwall7807c352011-03-17 20:20:30 +02008076#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8077 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8080{
8081 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008082 Py_ssize_t blen, total = 0;
8083
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008084 *iov = PyMem_New(struct iovec, cnt);
8085 if (*iov == NULL) {
8086 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008087 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008088 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008089
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 *buf = PyMem_New(Py_buffer, cnt);
8091 if (*buf == NULL) {
8092 PyMem_Del(*iov);
8093 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008094 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008095 }
8096
8097 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008098 PyObject *item = PySequence_GetItem(seq, i);
8099 if (item == NULL)
8100 goto fail;
8101 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8102 Py_DECREF(item);
8103 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008104 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008105 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008107 blen = (*buf)[i].len;
8108 (*iov)[i].iov_len = blen;
8109 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008110 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008111 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008112
8113fail:
8114 PyMem_Del(*iov);
8115 for (j = 0; j < i; j++) {
8116 PyBuffer_Release(&(*buf)[j]);
8117 }
8118 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008119 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008120}
8121
8122static void
8123iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8124{
8125 int i;
8126 PyMem_Del(iov);
8127 for (i = 0; i < cnt; i++) {
8128 PyBuffer_Release(&buf[i]);
8129 }
8130 PyMem_Del(buf);
8131}
8132#endif
8133
Larry Hastings2f936352014-08-05 14:04:04 +10008134
Ross Lagerwall7807c352011-03-17 20:20:30 +02008135#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008136/*[clinic input]
8137os.readv -> Py_ssize_t
8138
8139 fd: int
8140 buffers: object
8141 /
8142
8143Read from a file descriptor fd into an iterable of buffers.
8144
8145The buffers should be mutable buffers accepting bytes.
8146readv will transfer data into each buffer until it is full
8147and then move on to the next buffer in the sequence to hold
8148the rest of the data.
8149
8150readv returns the total number of bytes read,
8151which may be less than the total capacity of all the buffers.
8152[clinic start generated code]*/
8153
Larry Hastings2f936352014-08-05 14:04:04 +10008154static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008155os_readv_impl(PyObject *module, int fd, PyObject *buffers)
8156/*[clinic end generated code: output=792da062d3fcebdb input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008157{
8158 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008159 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008160 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008161 struct iovec *iov;
8162 Py_buffer *buf;
8163
Larry Hastings2f936352014-08-05 14:04:04 +10008164 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008165 PyErr_SetString(PyExc_TypeError,
8166 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008167 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169
Larry Hastings2f936352014-08-05 14:04:04 +10008170 cnt = PySequence_Size(buffers);
8171
8172 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8173 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008174
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008175 do {
8176 Py_BEGIN_ALLOW_THREADS
8177 n = readv(fd, iov, cnt);
8178 Py_END_ALLOW_THREADS
8179 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008180
8181 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008182 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008183 if (!async_err)
8184 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008185 return -1;
8186 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008187
Larry Hastings2f936352014-08-05 14:04:04 +10008188 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189}
Larry Hastings2f936352014-08-05 14:04:04 +10008190#endif /* HAVE_READV */
8191
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192
8193#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008194/*[clinic input]
8195# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8196os.pread
8197
8198 fd: int
8199 length: int
8200 offset: Py_off_t
8201 /
8202
8203Read a number of bytes from a file descriptor starting at a particular offset.
8204
8205Read length bytes from file descriptor fd, starting at offset bytes from
8206the beginning of the file. The file offset remains unchanged.
8207[clinic start generated code]*/
8208
Larry Hastings2f936352014-08-05 14:04:04 +10008209static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008210os_pread_impl(PyObject *module, int fd, int length, Py_off_t offset)
8211/*[clinic end generated code: output=435b29ee32b54a78 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008212{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008213 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008214 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008215 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216
Larry Hastings2f936352014-08-05 14:04:04 +10008217 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008218 errno = EINVAL;
8219 return posix_error();
8220 }
Larry Hastings2f936352014-08-05 14:04:04 +10008221 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008222 if (buffer == NULL)
8223 return NULL;
8224 if (!_PyVerify_fd(fd)) {
8225 Py_DECREF(buffer);
8226 return posix_error();
8227 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008228
8229 do {
8230 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008231 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008232 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008233 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008234 Py_END_ALLOW_THREADS
8235 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8236
Ross Lagerwall7807c352011-03-17 20:20:30 +02008237 if (n < 0) {
8238 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008239 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008240 }
Larry Hastings2f936352014-08-05 14:04:04 +10008241 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008242 _PyBytes_Resize(&buffer, n);
8243 return buffer;
8244}
Larry Hastings2f936352014-08-05 14:04:04 +10008245#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008246
Larry Hastings2f936352014-08-05 14:04:04 +10008247
8248/*[clinic input]
8249os.write -> Py_ssize_t
8250
8251 fd: int
8252 data: Py_buffer
8253 /
8254
8255Write a bytes object to a file descriptor.
8256[clinic start generated code]*/
8257
Larry Hastings2f936352014-08-05 14:04:04 +10008258static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008259os_write_impl(PyObject *module, int fd, Py_buffer *data)
8260/*[clinic end generated code: output=e4ef5bc904b58ef9 input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008261{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008262 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008263}
8264
8265#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008266PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008267"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008268sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008269 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008270Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008271
Larry Hastings2f936352014-08-05 14:04:04 +10008272/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008273static PyObject *
8274posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8275{
8276 int in, out;
8277 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008278 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008279 off_t offset;
8280
8281#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8282#ifndef __APPLE__
8283 Py_ssize_t len;
8284#endif
8285 PyObject *headers = NULL, *trailers = NULL;
8286 Py_buffer *hbuf, *tbuf;
8287 off_t sbytes;
8288 struct sf_hdtr sf;
8289 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008290 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008291 static char *keywords[] = {"out", "in",
8292 "offset", "count",
8293 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008294
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008295 sf.headers = NULL;
8296 sf.trailers = NULL;
8297
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008298#ifdef __APPLE__
8299 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008300 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008301#else
8302 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008303 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304#endif
8305 &headers, &trailers, &flags))
8306 return NULL;
8307 if (headers != NULL) {
8308 if (!PySequence_Check(headers)) {
8309 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008310 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 return NULL;
8312 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008313 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008315 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008316 (i = iov_setup(&(sf.headers), &hbuf,
8317 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008319#ifdef __APPLE__
8320 sbytes += i;
8321#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322 }
8323 }
8324 if (trailers != NULL) {
8325 if (!PySequence_Check(trailers)) {
8326 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008327 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008328 return NULL;
8329 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008330 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008332 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008333 (i = iov_setup(&(sf.trailers), &tbuf,
8334 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008336#ifdef __APPLE__
8337 sbytes += i;
8338#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008339 }
8340 }
8341
Steve Dower8fc89802015-04-12 00:26:27 -04008342 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008343 do {
8344 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008345#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008346 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008347#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008348 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008349#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008350 Py_END_ALLOW_THREADS
8351 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008352 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008353
8354 if (sf.headers != NULL)
8355 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8356 if (sf.trailers != NULL)
8357 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8358
8359 if (ret < 0) {
8360 if ((errno == EAGAIN) || (errno == EBUSY)) {
8361 if (sbytes != 0) {
8362 // some data has been sent
8363 goto done;
8364 }
8365 else {
8366 // no data has been sent; upper application is supposed
8367 // to retry on EAGAIN or EBUSY
8368 return posix_error();
8369 }
8370 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008371 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008372 }
8373 goto done;
8374
8375done:
8376 #if !defined(HAVE_LARGEFILE_SUPPORT)
8377 return Py_BuildValue("l", sbytes);
8378 #else
8379 return Py_BuildValue("L", sbytes);
8380 #endif
8381
8382#else
8383 Py_ssize_t count;
8384 PyObject *offobj;
8385 static char *keywords[] = {"out", "in",
8386 "offset", "count", NULL};
8387 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8388 keywords, &out, &in, &offobj, &count))
8389 return NULL;
8390#ifdef linux
8391 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008392 do {
8393 Py_BEGIN_ALLOW_THREADS
8394 ret = sendfile(out, in, NULL, count);
8395 Py_END_ALLOW_THREADS
8396 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008397 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008398 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008399 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008400 }
8401#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008402 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008403 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008404
8405 do {
8406 Py_BEGIN_ALLOW_THREADS
8407 ret = sendfile(out, in, &offset, count);
8408 Py_END_ALLOW_THREADS
8409 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008410 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008412 return Py_BuildValue("n", ret);
8413#endif
8414}
Larry Hastings2f936352014-08-05 14:04:04 +10008415#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008416
Larry Hastings2f936352014-08-05 14:04:04 +10008417
8418/*[clinic input]
8419os.fstat
8420
8421 fd : int
8422
8423Perform a stat system call on the given file descriptor.
8424
8425Like stat(), but for an open file descriptor.
8426Equivalent to os.stat(fd).
8427[clinic start generated code]*/
8428
Larry Hastings2f936352014-08-05 14:04:04 +10008429static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008430os_fstat_impl(PyObject *module, int fd)
8431/*[clinic end generated code: output=efc038cb5f654492 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008432{
Victor Stinner8c62be82010-05-06 00:08:46 +00008433 STRUCT_STAT st;
8434 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008435 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008436
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008437 do {
8438 Py_BEGIN_ALLOW_THREADS
8439 res = FSTAT(fd, &st);
8440 Py_END_ALLOW_THREADS
8441 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008442 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008443#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008444 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008445#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008446 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008447#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008448 }
Tim Peters5aa91602002-01-30 05:46:57 +00008449
Victor Stinner4195b5c2012-02-08 23:03:19 +01008450 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008451}
8452
Larry Hastings2f936352014-08-05 14:04:04 +10008453
8454/*[clinic input]
8455os.isatty -> bool
8456 fd: int
8457 /
8458
8459Return True if the fd is connected to a terminal.
8460
8461Return True if the file descriptor is an open file descriptor
8462connected to the slave end of a terminal.
8463[clinic start generated code]*/
8464
Larry Hastings2f936352014-08-05 14:04:04 +10008465static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008466os_isatty_impl(PyObject *module, int fd)
8467/*[clinic end generated code: output=6a48c8b4e644ca00 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008468{
Steve Dower8fc89802015-04-12 00:26:27 -04008469 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008470 if (!_PyVerify_fd(fd))
8471 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008472 _Py_BEGIN_SUPPRESS_IPH
8473 return_value = isatty(fd);
8474 _Py_END_SUPPRESS_IPH
8475 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008476}
8477
8478
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008479#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008480/*[clinic input]
8481os.pipe
8482
8483Create a pipe.
8484
8485Returns a tuple of two file descriptors:
8486 (read_fd, write_fd)
8487[clinic start generated code]*/
8488
Larry Hastings2f936352014-08-05 14:04:04 +10008489static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008490os_pipe_impl(PyObject *module)
8491/*[clinic end generated code: output=ff9b76255793b440 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008492{
Victor Stinner8c62be82010-05-06 00:08:46 +00008493 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008494#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008495 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008496 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008497 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008498#else
8499 int res;
8500#endif
8501
8502#ifdef MS_WINDOWS
8503 attr.nLength = sizeof(attr);
8504 attr.lpSecurityDescriptor = NULL;
8505 attr.bInheritHandle = FALSE;
8506
8507 Py_BEGIN_ALLOW_THREADS
8508 ok = CreatePipe(&read, &write, &attr, 0);
8509 if (ok) {
8510 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8511 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8512 if (fds[0] == -1 || fds[1] == -1) {
8513 CloseHandle(read);
8514 CloseHandle(write);
8515 ok = 0;
8516 }
8517 }
8518 Py_END_ALLOW_THREADS
8519
Victor Stinner8c62be82010-05-06 00:08:46 +00008520 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008521 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008522#else
8523
8524#ifdef HAVE_PIPE2
8525 Py_BEGIN_ALLOW_THREADS
8526 res = pipe2(fds, O_CLOEXEC);
8527 Py_END_ALLOW_THREADS
8528
8529 if (res != 0 && errno == ENOSYS)
8530 {
8531#endif
8532 Py_BEGIN_ALLOW_THREADS
8533 res = pipe(fds);
8534 Py_END_ALLOW_THREADS
8535
8536 if (res == 0) {
8537 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8538 close(fds[0]);
8539 close(fds[1]);
8540 return NULL;
8541 }
8542 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8543 close(fds[0]);
8544 close(fds[1]);
8545 return NULL;
8546 }
8547 }
8548#ifdef HAVE_PIPE2
8549 }
8550#endif
8551
8552 if (res != 0)
8553 return PyErr_SetFromErrno(PyExc_OSError);
8554#endif /* !MS_WINDOWS */
8555 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008556}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008557#endif /* HAVE_PIPE */
8558
Larry Hastings2f936352014-08-05 14:04:04 +10008559
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008560#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008561/*[clinic input]
8562os.pipe2
8563
8564 flags: int
8565 /
8566
8567Create a pipe with flags set atomically.
8568
8569Returns a tuple of two file descriptors:
8570 (read_fd, write_fd)
8571
8572flags can be constructed by ORing together one or more of these values:
8573O_NONBLOCK, O_CLOEXEC.
8574[clinic start generated code]*/
8575
Larry Hastings2f936352014-08-05 14:04:04 +10008576static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008577os_pipe2_impl(PyObject *module, int flags)
8578/*[clinic end generated code: output=25751fb43a45540f input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008579{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008580 int fds[2];
8581 int res;
8582
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008583 res = pipe2(fds, flags);
8584 if (res != 0)
8585 return posix_error();
8586 return Py_BuildValue("(ii)", fds[0], fds[1]);
8587}
8588#endif /* HAVE_PIPE2 */
8589
Larry Hastings2f936352014-08-05 14:04:04 +10008590
Ross Lagerwall7807c352011-03-17 20:20:30 +02008591#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008592/*[clinic input]
8593os.writev -> Py_ssize_t
8594 fd: int
8595 buffers: object
8596 /
8597
8598Iterate over buffers, and write the contents of each to a file descriptor.
8599
8600Returns the total number of bytes written.
8601buffers must be a sequence of bytes-like objects.
8602[clinic start generated code]*/
8603
Larry Hastings2f936352014-08-05 14:04:04 +10008604static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008605os_writev_impl(PyObject *module, int fd, PyObject *buffers)
8606/*[clinic end generated code: output=56565cfac3aac15b input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008607{
8608 int cnt;
8609 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008610 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008611 struct iovec *iov;
8612 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008613
8614 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008615 PyErr_SetString(PyExc_TypeError,
8616 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008617 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008618 }
Larry Hastings2f936352014-08-05 14:04:04 +10008619 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008620
Larry Hastings2f936352014-08-05 14:04:04 +10008621 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8622 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008623 }
8624
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008625 do {
8626 Py_BEGIN_ALLOW_THREADS
8627 result = writev(fd, iov, cnt);
8628 Py_END_ALLOW_THREADS
8629 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008630
8631 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008632 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008633 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008634
Georg Brandl306336b2012-06-24 12:55:33 +02008635 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008636}
Larry Hastings2f936352014-08-05 14:04:04 +10008637#endif /* HAVE_WRITEV */
8638
8639
8640#ifdef HAVE_PWRITE
8641/*[clinic input]
8642os.pwrite -> Py_ssize_t
8643
8644 fd: int
8645 buffer: Py_buffer
8646 offset: Py_off_t
8647 /
8648
8649Write bytes to a file descriptor starting at a particular offset.
8650
8651Write buffer to fd, starting at offset bytes from the beginning of
8652the file. Returns the number of bytes writte. Does not change the
8653current file offset.
8654[clinic start generated code]*/
8655
Larry Hastings2f936352014-08-05 14:04:04 +10008656static Py_ssize_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008657os_pwrite_impl(PyObject *module, int fd, Py_buffer *buffer, Py_off_t offset)
8658/*[clinic end generated code: output=c74da630758ee925 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008659{
8660 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008661 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008662
8663 if (!_PyVerify_fd(fd)) {
8664 posix_error();
8665 return -1;
8666 }
8667
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008668 do {
8669 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008670 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008671 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008672 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008673 Py_END_ALLOW_THREADS
8674 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008675
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008676 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008677 posix_error();
8678 return size;
8679}
8680#endif /* HAVE_PWRITE */
8681
8682
8683#ifdef HAVE_MKFIFO
8684/*[clinic input]
8685os.mkfifo
8686
8687 path: path_t
8688 mode: int=0o666
8689 *
8690 dir_fd: dir_fd(requires='mkfifoat')=None
8691
8692Create a "fifo" (a POSIX named pipe).
8693
8694If dir_fd is not None, it should be a file descriptor open to a directory,
8695 and path should be relative; path will then be relative to that directory.
8696dir_fd may not be implemented on your platform.
8697 If it is unavailable, using it will raise a NotImplementedError.
8698[clinic start generated code]*/
8699
Larry Hastings2f936352014-08-05 14:04:04 +10008700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008701os_mkfifo_impl(PyObject *module, path_t *path, int mode, int dir_fd)
8702/*[clinic end generated code: output=ce41cfad0e68c940 input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008703{
8704 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008705 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008706
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008707 do {
8708 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008709#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008710 if (dir_fd != DEFAULT_DIR_FD)
8711 result = mkfifoat(dir_fd, path->narrow, mode);
8712 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008713#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008714 result = mkfifo(path->narrow, mode);
8715 Py_END_ALLOW_THREADS
8716 } while (result != 0 && errno == EINTR &&
8717 !(async_err = PyErr_CheckSignals()));
8718 if (result != 0)
8719 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008720
8721 Py_RETURN_NONE;
8722}
8723#endif /* HAVE_MKFIFO */
8724
8725
8726#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8727/*[clinic input]
8728os.mknod
8729
8730 path: path_t
8731 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008732 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008733 *
8734 dir_fd: dir_fd(requires='mknodat')=None
8735
8736Create a node in the file system.
8737
8738Create a node in the file system (file, device special file or named pipe)
8739at path. mode specifies both the permissions to use and the
8740type of node to be created, being combined (bitwise OR) with one of
8741S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8742device defines the newly created device special file (probably using
8743os.makedev()). Otherwise device is ignored.
8744
8745If dir_fd is not None, it should be a file descriptor open to a directory,
8746 and path should be relative; path will then be relative to that directory.
8747dir_fd may not be implemented on your platform.
8748 If it is unavailable, using it will raise a NotImplementedError.
8749[clinic start generated code]*/
8750
Larry Hastings2f936352014-08-05 14:04:04 +10008751static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008752os_mknod_impl(PyObject *module, path_t *path, int mode, dev_t device,
Larry Hastings89964c42015-04-14 18:07:59 -04008753 int dir_fd)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008754/*[clinic end generated code: output=92e55d3ca8917461 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008755{
8756 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008757 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008758
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008759 do {
8760 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008761#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008762 if (dir_fd != DEFAULT_DIR_FD)
8763 result = mknodat(dir_fd, path->narrow, mode, device);
8764 else
Larry Hastings2f936352014-08-05 14:04:04 +10008765#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008766 result = mknod(path->narrow, mode, device);
8767 Py_END_ALLOW_THREADS
8768 } while (result != 0 && errno == EINTR &&
8769 !(async_err = PyErr_CheckSignals()));
8770 if (result != 0)
8771 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008772
8773 Py_RETURN_NONE;
8774}
8775#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8776
8777
8778#ifdef HAVE_DEVICE_MACROS
8779/*[clinic input]
8780os.major -> unsigned_int
8781
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008782 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008783 /
8784
8785Extracts a device major number from a raw device number.
8786[clinic start generated code]*/
8787
Larry Hastings2f936352014-08-05 14:04:04 +10008788static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008789os_major_impl(PyObject *module, dev_t device)
8790/*[clinic end generated code: output=5b3b2589bafb498e input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008791{
8792 return major(device);
8793}
8794
8795
8796/*[clinic input]
8797os.minor -> unsigned_int
8798
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008799 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008800 /
8801
8802Extracts a device minor number from a raw device number.
8803[clinic start generated code]*/
8804
Larry Hastings2f936352014-08-05 14:04:04 +10008805static unsigned int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008806os_minor_impl(PyObject *module, dev_t device)
8807/*[clinic end generated code: output=5e1a25e630b0157d input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008808{
8809 return minor(device);
8810}
8811
8812
8813/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008814os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008815
8816 major: int
8817 minor: int
8818 /
8819
8820Composes a raw device number from the major and minor device numbers.
8821[clinic start generated code]*/
8822
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008823static dev_t
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008824os_makedev_impl(PyObject *module, int major, int minor)
8825/*[clinic end generated code: output=881aaa4aba6f6a52 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008826{
8827 return makedev(major, minor);
8828}
8829#endif /* HAVE_DEVICE_MACROS */
8830
8831
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008832#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008833/*[clinic input]
8834os.ftruncate
8835
8836 fd: int
8837 length: Py_off_t
8838 /
8839
8840Truncate a file, specified by file descriptor, to a specific length.
8841[clinic start generated code]*/
8842
Larry Hastings2f936352014-08-05 14:04:04 +10008843static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008844os_ftruncate_impl(PyObject *module, int fd, Py_off_t length)
8845/*[clinic end generated code: output=fba15523721be7e4 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008846{
8847 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008848 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008849
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008850 if (!_PyVerify_fd(fd))
8851 return posix_error();
8852
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008853 do {
8854 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008855 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008856#ifdef MS_WINDOWS
8857 result = _chsize_s(fd, length);
8858#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008859 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008860#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008861 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008862 Py_END_ALLOW_THREADS
8863 } while (result != 0 && errno == EINTR &&
8864 !(async_err = PyErr_CheckSignals()));
8865 if (result != 0)
8866 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008867 Py_RETURN_NONE;
8868}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008869#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008870
8871
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008872#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008873/*[clinic input]
8874os.truncate
8875 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8876 length: Py_off_t
8877
8878Truncate a file, specified by path, to a specific length.
8879
8880On some platforms, path may also be specified as an open file descriptor.
8881 If this functionality is unavailable, using it raises an exception.
8882[clinic start generated code]*/
8883
Larry Hastings2f936352014-08-05 14:04:04 +10008884static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008885os_truncate_impl(PyObject *module, path_t *path, Py_off_t length)
8886/*[clinic end generated code: output=43009c8df5c0a12b input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008887{
8888 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008889#ifdef MS_WINDOWS
8890 int fd;
8891#endif
8892
8893 if (path->fd != -1)
8894 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008895
8896 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008897 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008898#ifdef MS_WINDOWS
8899 if (path->wide)
8900 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008901 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008902 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008903 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008904 result = -1;
8905 else {
8906 result = _chsize_s(fd, length);
8907 close(fd);
8908 if (result < 0)
8909 errno = result;
8910 }
8911#else
8912 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008913#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008914 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008915 Py_END_ALLOW_THREADS
8916 if (result < 0)
8917 return path_error(path);
8918
8919 Py_RETURN_NONE;
8920}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008921#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008922
Ross Lagerwall7807c352011-03-17 20:20:30 +02008923
Victor Stinnerd6b17692014-09-30 12:20:05 +02008924/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8925 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8926 defined, which is the case in Python on AIX. AIX bug report:
8927 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8928#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8929# define POSIX_FADVISE_AIX_BUG
8930#endif
8931
Victor Stinnerec39e262014-09-30 12:35:58 +02008932
Victor Stinnerd6b17692014-09-30 12:20:05 +02008933#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008934/*[clinic input]
8935os.posix_fallocate
8936
8937 fd: int
8938 offset: Py_off_t
8939 length: Py_off_t
8940 /
8941
8942Ensure a file has allocated at least a particular number of bytes on disk.
8943
8944Ensure that the file specified by fd encompasses a range of bytes
8945starting at offset bytes from the beginning and continuing for length bytes.
8946[clinic start generated code]*/
8947
Larry Hastings2f936352014-08-05 14:04:04 +10008948static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008949os_posix_fallocate_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008950 Py_off_t length)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008951/*[clinic end generated code: output=73f107139564aa9d input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008952{
8953 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008954 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008956 do {
8957 Py_BEGIN_ALLOW_THREADS
8958 result = posix_fallocate(fd, offset, length);
8959 Py_END_ALLOW_THREADS
8960 } while (result != 0 && errno == EINTR &&
8961 !(async_err = PyErr_CheckSignals()));
8962 if (result != 0)
8963 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008964 Py_RETURN_NONE;
8965}
Victor Stinnerec39e262014-09-30 12:35:58 +02008966#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008967
Ross Lagerwall7807c352011-03-17 20:20:30 +02008968
Victor Stinnerd6b17692014-09-30 12:20:05 +02008969#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008970/*[clinic input]
8971os.posix_fadvise
8972
8973 fd: int
8974 offset: Py_off_t
8975 length: Py_off_t
8976 advice: int
8977 /
8978
8979Announce an intention to access data in a specific pattern.
8980
8981Announce an intention to access data in a specific pattern, thus allowing
8982the kernel to make optimizations.
8983The advice applies to the region of the file specified by fd starting at
8984offset and continuing for length bytes.
8985advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8986POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8987POSIX_FADV_DONTNEED.
8988[clinic start generated code]*/
8989
Larry Hastings2f936352014-08-05 14:04:04 +10008990static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008991os_posix_fadvise_impl(PyObject *module, int fd, Py_off_t offset,
Larry Hastings89964c42015-04-14 18:07:59 -04008992 Py_off_t length, int advice)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03008993/*[clinic end generated code: output=412ef4aa70c98642 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008994{
8995 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008996 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008997
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008998 do {
8999 Py_BEGIN_ALLOW_THREADS
9000 result = posix_fadvise(fd, offset, length, advice);
9001 Py_END_ALLOW_THREADS
9002 } while (result != 0 && errno == EINTR &&
9003 !(async_err = PyErr_CheckSignals()));
9004 if (result != 0)
9005 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02009006 Py_RETURN_NONE;
9007}
Victor Stinnerec39e262014-09-30 12:35:58 +02009008#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02009009
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009010#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00009011
Fred Drake762e2061999-08-26 17:23:54 +00009012/* Save putenv() parameters as values here, so we can collect them when they
9013 * get re-set with another call for the same key. */
9014static PyObject *posix_putenv_garbage;
9015
Larry Hastings2f936352014-08-05 14:04:04 +10009016static void
9017posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009018{
Larry Hastings2f936352014-08-05 14:04:04 +10009019 /* Install the first arg and newstr in posix_putenv_garbage;
9020 * this will cause previous value to be collected. This has to
9021 * happen after the real putenv() call because the old value
9022 * was still accessible until then. */
9023 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9024 /* really not much we can do; just leak */
9025 PyErr_Clear();
9026 else
9027 Py_DECREF(value);
9028}
9029
9030
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009031#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009032/*[clinic input]
9033os.putenv
9034
9035 name: unicode
9036 value: unicode
9037 /
9038
9039Change or add an environment variable.
9040[clinic start generated code]*/
9041
Larry Hastings2f936352014-08-05 14:04:04 +10009042static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009043os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9044/*[clinic end generated code: output=d29a567d6b2327d2 input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009045{
9046 wchar_t *env;
9047
9048 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9049 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009050 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009051 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009052 }
Larry Hastings2f936352014-08-05 14:04:04 +10009053 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009054 PyErr_Format(PyExc_ValueError,
9055 "the environment variable is longer than %u characters",
9056 _MAX_ENV);
9057 goto error;
9058 }
9059
Larry Hastings2f936352014-08-05 14:04:04 +10009060 env = PyUnicode_AsUnicode(unicode);
9061 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009062 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009063 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009064 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009065 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009066 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009067
Larry Hastings2f936352014-08-05 14:04:04 +10009068 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009069 Py_RETURN_NONE;
9070
9071error:
Larry Hastings2f936352014-08-05 14:04:04 +10009072 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009073 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009074}
Larry Hastings2f936352014-08-05 14:04:04 +10009075#else /* MS_WINDOWS */
9076/*[clinic input]
9077os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009078
Larry Hastings2f936352014-08-05 14:04:04 +10009079 name: FSConverter
9080 value: FSConverter
9081 /
9082
9083Change or add an environment variable.
9084[clinic start generated code]*/
9085
Larry Hastings2f936352014-08-05 14:04:04 +10009086static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009087os_putenv_impl(PyObject *module, PyObject *name, PyObject *value)
9088/*[clinic end generated code: output=d29a567d6b2327d2 input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009089{
9090 PyObject *bytes = NULL;
9091 char *env;
9092 char *name_string = PyBytes_AsString(name);
9093 char *value_string = PyBytes_AsString(value);
9094
9095 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9096 if (bytes == NULL) {
9097 PyErr_NoMemory();
9098 return NULL;
9099 }
9100
9101 env = PyBytes_AS_STRING(bytes);
9102 if (putenv(env)) {
9103 Py_DECREF(bytes);
9104 return posix_error();
9105 }
9106
9107 posix_putenv_garbage_setitem(name, bytes);
9108 Py_RETURN_NONE;
9109}
9110#endif /* MS_WINDOWS */
9111#endif /* HAVE_PUTENV */
9112
9113
9114#ifdef HAVE_UNSETENV
9115/*[clinic input]
9116os.unsetenv
9117 name: FSConverter
9118 /
9119
9120Delete an environment variable.
9121[clinic start generated code]*/
9122
Larry Hastings2f936352014-08-05 14:04:04 +10009123static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009124os_unsetenv_impl(PyObject *module, PyObject *name)
9125/*[clinic end generated code: output=54c4137ab1834f02 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009126{
Victor Stinner984890f2011-11-24 13:53:38 +01009127#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009128 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009129#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009130
Victor Stinner984890f2011-11-24 13:53:38 +01009131#ifdef HAVE_BROKEN_UNSETENV
9132 unsetenv(PyBytes_AS_STRING(name));
9133#else
Victor Stinner65170952011-11-22 22:16:17 +01009134 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009135 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009136 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009137#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009138
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 /* Remove the key from posix_putenv_garbage;
9140 * this will cause it to be collected. This has to
9141 * happen after the real unsetenv() call because the
9142 * old value was still accessible until then.
9143 */
Victor Stinner65170952011-11-22 22:16:17 +01009144 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009145 /* really not much we can do; just leak */
9146 PyErr_Clear();
9147 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009148 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009149}
Larry Hastings2f936352014-08-05 14:04:04 +10009150#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009151
Larry Hastings2f936352014-08-05 14:04:04 +10009152
9153/*[clinic input]
9154os.strerror
9155
9156 code: int
9157 /
9158
9159Translate an error code to a message string.
9160[clinic start generated code]*/
9161
Larry Hastings2f936352014-08-05 14:04:04 +10009162static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009163os_strerror_impl(PyObject *module, int code)
9164/*[clinic end generated code: output=baebf09fa02a78f2 input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009165{
9166 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009167 if (message == NULL) {
9168 PyErr_SetString(PyExc_ValueError,
9169 "strerror() argument out of range");
9170 return NULL;
9171 }
Victor Stinner1b579672011-12-17 05:47:23 +01009172 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009173}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009174
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009175
Guido van Rossumc9641791998-08-04 15:26:23 +00009176#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009177#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009178/*[clinic input]
9179os.WCOREDUMP -> bool
9180
9181 status: int
9182 /
9183
9184Return True if the process returning status was dumped to a core file.
9185[clinic start generated code]*/
9186
Larry Hastings2f936352014-08-05 14:04:04 +10009187static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009188os_WCOREDUMP_impl(PyObject *module, int status)
9189/*[clinic end generated code: output=1a584b147b16bd18 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009190{
9191 WAIT_TYPE wait_status;
9192 WAIT_STATUS_INT(wait_status) = status;
9193 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009194}
9195#endif /* WCOREDUMP */
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197
Fred Drake106c1a02002-04-23 15:58:02 +00009198#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009199/*[clinic input]
9200os.WIFCONTINUED -> bool
9201
9202 status: int
9203
9204Return True if a particular process was continued from a job control stop.
9205
9206Return True if the process returning status was continued from a
9207job control stop.
9208[clinic start generated code]*/
9209
Larry Hastings2f936352014-08-05 14:04:04 +10009210static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009211os_WIFCONTINUED_impl(PyObject *module, int status)
9212/*[clinic end generated code: output=1e35295d844364bd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009213{
9214 WAIT_TYPE wait_status;
9215 WAIT_STATUS_INT(wait_status) = status;
9216 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009217}
9218#endif /* WIFCONTINUED */
9219
Larry Hastings2f936352014-08-05 14:04:04 +10009220
Guido van Rossumc9641791998-08-04 15:26:23 +00009221#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009222/*[clinic input]
9223os.WIFSTOPPED -> bool
9224
9225 status: int
9226
9227Return True if the process returning status was stopped.
9228[clinic start generated code]*/
9229
Larry Hastings2f936352014-08-05 14:04:04 +10009230static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009231os_WIFSTOPPED_impl(PyObject *module, int status)
9232/*[clinic end generated code: output=fdb57122a5c9b4cb input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009233{
9234 WAIT_TYPE wait_status;
9235 WAIT_STATUS_INT(wait_status) = status;
9236 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009237}
9238#endif /* WIFSTOPPED */
9239
Larry Hastings2f936352014-08-05 14:04:04 +10009240
Guido van Rossumc9641791998-08-04 15:26:23 +00009241#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009242/*[clinic input]
9243os.WIFSIGNALED -> bool
9244
9245 status: int
9246
9247Return True if the process returning status was terminated by a signal.
9248[clinic start generated code]*/
9249
Larry Hastings2f936352014-08-05 14:04:04 +10009250static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009251os_WIFSIGNALED_impl(PyObject *module, int status)
9252/*[clinic end generated code: output=d1dde4dcc819a5f5 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009253{
9254 WAIT_TYPE wait_status;
9255 WAIT_STATUS_INT(wait_status) = status;
9256 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009257}
9258#endif /* WIFSIGNALED */
9259
Larry Hastings2f936352014-08-05 14:04:04 +10009260
Guido van Rossumc9641791998-08-04 15:26:23 +00009261#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009262/*[clinic input]
9263os.WIFEXITED -> bool
9264
9265 status: int
9266
9267Return True if the process returning status exited via the exit() system call.
9268[clinic start generated code]*/
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009271os_WIFEXITED_impl(PyObject *module, int status)
9272/*[clinic end generated code: output=01c09d6ebfeea397 input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009273{
9274 WAIT_TYPE wait_status;
9275 WAIT_STATUS_INT(wait_status) = status;
9276 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009277}
9278#endif /* WIFEXITED */
9279
Larry Hastings2f936352014-08-05 14:04:04 +10009280
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009281#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009282/*[clinic input]
9283os.WEXITSTATUS -> int
9284
9285 status: int
9286
9287Return the process return code from status.
9288[clinic start generated code]*/
9289
Larry Hastings2f936352014-08-05 14:04:04 +10009290static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009291os_WEXITSTATUS_impl(PyObject *module, int status)
9292/*[clinic end generated code: output=6e3efbba11f6488d input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009293{
9294 WAIT_TYPE wait_status;
9295 WAIT_STATUS_INT(wait_status) = status;
9296 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009297}
9298#endif /* WEXITSTATUS */
9299
Larry Hastings2f936352014-08-05 14:04:04 +10009300
Guido van Rossumc9641791998-08-04 15:26:23 +00009301#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009302/*[clinic input]
9303os.WTERMSIG -> int
9304
9305 status: int
9306
9307Return the signal that terminated the process that provided the status value.
9308[clinic start generated code]*/
9309
Larry Hastings2f936352014-08-05 14:04:04 +10009310static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009311os_WTERMSIG_impl(PyObject *module, int status)
9312/*[clinic end generated code: output=172f7dfc8dcfc3ad input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009313{
9314 WAIT_TYPE wait_status;
9315 WAIT_STATUS_INT(wait_status) = status;
9316 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009317}
9318#endif /* WTERMSIG */
9319
Larry Hastings2f936352014-08-05 14:04:04 +10009320
Guido van Rossumc9641791998-08-04 15:26:23 +00009321#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009322/*[clinic input]
9323os.WSTOPSIG -> int
9324
9325 status: int
9326
9327Return the signal that stopped the process that provided the status value.
9328[clinic start generated code]*/
9329
Larry Hastings2f936352014-08-05 14:04:04 +10009330static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009331os_WSTOPSIG_impl(PyObject *module, int status)
9332/*[clinic end generated code: output=0ab7586396f5d82b input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009333{
9334 WAIT_TYPE wait_status;
9335 WAIT_STATUS_INT(wait_status) = status;
9336 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009337}
9338#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009339#endif /* HAVE_SYS_WAIT_H */
9340
9341
Thomas Wouters477c8d52006-05-27 19:21:47 +00009342#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009343#ifdef _SCO_DS
9344/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9345 needed definitions in sys/statvfs.h */
9346#define _SVID3
9347#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009348#include <sys/statvfs.h>
9349
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009350static PyObject*
9351_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009352 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9353 if (v == NULL)
9354 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009355
9356#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009357 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9358 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9359 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9360 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9361 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9362 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9363 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9364 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9365 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9366 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009367#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009368 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9369 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9370 PyStructSequence_SET_ITEM(v, 2,
9371 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9372 PyStructSequence_SET_ITEM(v, 3,
9373 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9374 PyStructSequence_SET_ITEM(v, 4,
9375 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9376 PyStructSequence_SET_ITEM(v, 5,
9377 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9378 PyStructSequence_SET_ITEM(v, 6,
9379 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9380 PyStructSequence_SET_ITEM(v, 7,
9381 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9382 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9383 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009384#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009385 if (PyErr_Occurred()) {
9386 Py_DECREF(v);
9387 return NULL;
9388 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009389
Victor Stinner8c62be82010-05-06 00:08:46 +00009390 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009391}
9392
Larry Hastings2f936352014-08-05 14:04:04 +10009393
9394/*[clinic input]
9395os.fstatvfs
9396 fd: int
9397 /
9398
9399Perform an fstatvfs system call on the given fd.
9400
9401Equivalent to statvfs(fd).
9402[clinic start generated code]*/
9403
Larry Hastings2f936352014-08-05 14:04:04 +10009404static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009405os_fstatvfs_impl(PyObject *module, int fd)
9406/*[clinic end generated code: output=53547cf0cc55e6c5 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009407{
9408 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009409 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009410 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009411
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009412 do {
9413 Py_BEGIN_ALLOW_THREADS
9414 result = fstatvfs(fd, &st);
9415 Py_END_ALLOW_THREADS
9416 } while (result != 0 && errno == EINTR &&
9417 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009418 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009419 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009420
Victor Stinner8c62be82010-05-06 00:08:46 +00009421 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009422}
Larry Hastings2f936352014-08-05 14:04:04 +10009423#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009424
9425
Thomas Wouters477c8d52006-05-27 19:21:47 +00009426#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009427#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009428/*[clinic input]
9429os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009430
Larry Hastings2f936352014-08-05 14:04:04 +10009431 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9432
9433Perform a statvfs system call on the given path.
9434
9435path may always be specified as a string.
9436On some platforms, path may also be specified as an open file descriptor.
9437 If this functionality is unavailable, using it raises an exception.
9438[clinic start generated code]*/
9439
Larry Hastings2f936352014-08-05 14:04:04 +10009440static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009441os_statvfs_impl(PyObject *module, path_t *path)
9442/*[clinic end generated code: output=87106dd1beb8556e input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009443{
9444 int result;
9445 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009446
9447 Py_BEGIN_ALLOW_THREADS
9448#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009449 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009450#ifdef __APPLE__
9451 /* handle weak-linking on Mac OS X 10.3 */
9452 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009453 fd_specified("statvfs", path->fd);
9454 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009455 }
9456#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009457 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009458 }
9459 else
9460#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009461 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009462 Py_END_ALLOW_THREADS
9463
9464 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009465 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009466 }
9467
Larry Hastings2f936352014-08-05 14:04:04 +10009468 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009469}
Larry Hastings2f936352014-08-05 14:04:04 +10009470#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9471
Guido van Rossum94f6f721999-01-06 18:42:14 +00009472
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009473#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009474/*[clinic input]
9475os._getdiskusage
9476
9477 path: Py_UNICODE
9478
9479Return disk usage statistics about the given path as a (total, free) tuple.
9480[clinic start generated code]*/
9481
Larry Hastings2f936352014-08-05 14:04:04 +10009482static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009483os__getdiskusage_impl(PyObject *module, Py_UNICODE *path)
9484/*[clinic end generated code: output=76d6adcd86b1db0b input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009485{
9486 BOOL retval;
9487 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009488
9489 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009490 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009491 Py_END_ALLOW_THREADS
9492 if (retval == 0)
9493 return PyErr_SetFromWindowsErr(0);
9494
9495 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9496}
Larry Hastings2f936352014-08-05 14:04:04 +10009497#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009498
9499
Fred Drakec9680921999-12-13 16:37:25 +00009500/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9501 * It maps strings representing configuration variable names to
9502 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009503 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009504 * rarely-used constants. There are three separate tables that use
9505 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009506 *
9507 * This code is always included, even if none of the interfaces that
9508 * need it are included. The #if hackery needed to avoid it would be
9509 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009510 */
9511struct constdef {
9512 char *name;
9513 long value;
9514};
9515
Fred Drake12c6e2d1999-12-14 21:25:03 +00009516static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009517conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009518 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009519{
Christian Heimes217cfd12007-12-02 14:31:20 +00009520 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009521 *valuep = PyLong_AS_LONG(arg);
9522 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009523 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009524 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009525 /* look up the value in the table using a binary search */
9526 size_t lo = 0;
9527 size_t mid;
9528 size_t hi = tablesize;
9529 int cmp;
9530 const char *confname;
9531 if (!PyUnicode_Check(arg)) {
9532 PyErr_SetString(PyExc_TypeError,
9533 "configuration names must be strings or integers");
9534 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009536 confname = _PyUnicode_AsString(arg);
9537 if (confname == NULL)
9538 return 0;
9539 while (lo < hi) {
9540 mid = (lo + hi) / 2;
9541 cmp = strcmp(confname, table[mid].name);
9542 if (cmp < 0)
9543 hi = mid;
9544 else if (cmp > 0)
9545 lo = mid + 1;
9546 else {
9547 *valuep = table[mid].value;
9548 return 1;
9549 }
9550 }
9551 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9552 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009554}
9555
9556
9557#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9558static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009559#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009561#endif
9562#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009564#endif
Fred Drakec9680921999-12-13 16:37:25 +00009565#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
9583#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009584 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009585#endif
9586#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009587 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009588#endif
9589#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009590 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009591#endif
9592#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009593 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009594#endif
9595#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009596 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009597#endif
9598#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009599 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009600#endif
9601#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009602 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009603#endif
9604#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009605 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009606#endif
9607#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009608 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009609#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009610#ifdef _PC_ACL_ENABLED
9611 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9612#endif
9613#ifdef _PC_MIN_HOLE_SIZE
9614 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9615#endif
9616#ifdef _PC_ALLOC_SIZE_MIN
9617 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9618#endif
9619#ifdef _PC_REC_INCR_XFER_SIZE
9620 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9621#endif
9622#ifdef _PC_REC_MAX_XFER_SIZE
9623 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9624#endif
9625#ifdef _PC_REC_MIN_XFER_SIZE
9626 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9627#endif
9628#ifdef _PC_REC_XFER_ALIGN
9629 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9630#endif
9631#ifdef _PC_SYMLINK_MAX
9632 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9633#endif
9634#ifdef _PC_XATTR_ENABLED
9635 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9636#endif
9637#ifdef _PC_XATTR_EXISTS
9638 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9639#endif
9640#ifdef _PC_TIMESTAMP_RESOLUTION
9641 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9642#endif
Fred Drakec9680921999-12-13 16:37:25 +00009643};
9644
Fred Drakec9680921999-12-13 16:37:25 +00009645static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009646conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009647{
9648 return conv_confname(arg, valuep, posix_constants_pathconf,
9649 sizeof(posix_constants_pathconf)
9650 / sizeof(struct constdef));
9651}
9652#endif
9653
Larry Hastings2f936352014-08-05 14:04:04 +10009654
Fred Drakec9680921999-12-13 16:37:25 +00009655#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009656/*[clinic input]
9657os.fpathconf -> long
9658
9659 fd: int
9660 name: path_confname
9661 /
9662
9663Return the configuration limit name for the file descriptor fd.
9664
9665If there is no limit, return -1.
9666[clinic start generated code]*/
9667
Larry Hastings2f936352014-08-05 14:04:04 +10009668static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009669os_fpathconf_impl(PyObject *module, int fd, int name)
9670/*[clinic end generated code: output=d5b7042425fc3e21 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009671{
9672 long limit;
9673
9674 errno = 0;
9675 limit = fpathconf(fd, name);
9676 if (limit == -1 && errno != 0)
9677 posix_error();
9678
9679 return limit;
9680}
9681#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009682
9683
9684#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009685/*[clinic input]
9686os.pathconf -> long
9687 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9688 name: path_confname
9689
9690Return the configuration limit name for the file or directory path.
9691
9692If there is no limit, return -1.
9693On some platforms, path may also be specified as an open file descriptor.
9694 If this functionality is unavailable, using it raises an exception.
9695[clinic start generated code]*/
9696
Larry Hastings2f936352014-08-05 14:04:04 +10009697static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009698os_pathconf_impl(PyObject *module, path_t *path, int name)
9699/*[clinic end generated code: output=5bedee35b293a089 input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009700{
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009702
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009704#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009705 if (path->fd != -1)
9706 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009707 else
9708#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009709 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 if (limit == -1 && errno != 0) {
9711 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009712 /* could be a path or name problem */
9713 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009714 else
Larry Hastings2f936352014-08-05 14:04:04 +10009715 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 }
Larry Hastings2f936352014-08-05 14:04:04 +10009717
9718 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009719}
Larry Hastings2f936352014-08-05 14:04:04 +10009720#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009721
9722#ifdef HAVE_CONFSTR
9723static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009724#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009726#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009727#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009729#endif
9730#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009732#endif
Fred Draked86ed291999-12-15 15:34:33 +00009733#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009735#endif
9736#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009738#endif
9739#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009741#endif
9742#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009744#endif
Fred Drakec9680921999-12-13 16:37:25 +00009745#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
Fred Draked86ed291999-12-15 15:34:33 +00009769#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009771#endif
Fred Drakec9680921999-12-13 16:37:25 +00009772#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
Fred Draked86ed291999-12-15 15:34:33 +00009775#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009777#endif
9778#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009780#endif
9781#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009783#endif
9784#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009786#endif
Fred Drakec9680921999-12-13 16:37:25 +00009787#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
9808#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009810#endif
9811#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009813#endif
9814#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009816#endif
9817#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009819#endif
9820#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009822#endif
9823#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009825#endif
9826#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009828#endif
9829#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009831#endif
9832#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009834#endif
Fred Draked86ed291999-12-15 15:34:33 +00009835#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009837#endif
9838#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
9841#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
9844#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009846#endif
9847#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009848 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009849#endif
9850#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009851 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009852#endif
9853#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009854 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009855#endif
9856#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009857 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009858#endif
9859#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009860 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009861#endif
9862#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009863 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009864#endif
9865#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009866 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009867#endif
9868#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009869 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009870#endif
9871#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009872 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009873#endif
Fred Drakec9680921999-12-13 16:37:25 +00009874};
9875
9876static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009877conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009878{
9879 return conv_confname(arg, valuep, posix_constants_confstr,
9880 sizeof(posix_constants_confstr)
9881 / sizeof(struct constdef));
9882}
9883
Larry Hastings2f936352014-08-05 14:04:04 +10009884
9885/*[clinic input]
9886os.confstr
9887
9888 name: confstr_confname
9889 /
9890
9891Return a string-valued system configuration variable.
9892[clinic start generated code]*/
9893
Larry Hastings2f936352014-08-05 14:04:04 +10009894static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +03009895os_confstr_impl(PyObject *module, int name)
9896/*[clinic end generated code: output=bfb0b1b1e49b9383 input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009897{
9898 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009899 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009900 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009901
Victor Stinnercb043522010-09-10 23:49:04 +00009902 errno = 0;
9903 len = confstr(name, buffer, sizeof(buffer));
9904 if (len == 0) {
9905 if (errno) {
9906 posix_error();
9907 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009908 }
9909 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009910 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009911 }
9912 }
Victor Stinnercb043522010-09-10 23:49:04 +00009913
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009914 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009915 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009916 char *buf = PyMem_Malloc(len);
9917 if (buf == NULL)
9918 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009919 len2 = confstr(name, buf, len);
9920 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009921 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009922 PyMem_Free(buf);
9923 }
9924 else
9925 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009926 return result;
9927}
Larry Hastings2f936352014-08-05 14:04:04 +10009928#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009929
9930
9931#ifdef HAVE_SYSCONF
9932static struct constdef posix_constants_sysconf[] = {
9933#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
9936#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009938#endif
9939#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
Fred Draked86ed291999-12-15 15:34:33 +00009963#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009965#endif
9966#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009968#endif
Fred Drakec9680921999-12-13 16:37:25 +00009969#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
Fred Drakec9680921999-12-13 16:37:25 +00009972#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
Fred Draked86ed291999-12-15 15:34:33 +00009987#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009989#endif
Fred Drakec9680921999-12-13 16:37:25 +00009990#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
Fred Draked86ed291999-12-15 15:34:33 +000010005#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +000010007#endif
Fred Drakec9680921999-12-13 16:37:25 +000010008#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
10050#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
10062#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010064#endif
10065#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
Fred Draked86ed291999-12-15 15:34:33 +000010077#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010079#endif
Fred Drakec9680921999-12-13 16:37:25 +000010080#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
10086#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010088#endif
Fred Draked86ed291999-12-15 15:34:33 +000010089#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010091#endif
Fred Drakec9680921999-12-13 16:37:25 +000010092#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
Fred Draked86ed291999-12-15 15:34:33 +000010095#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010097#endif
10098#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010100#endif
Fred Drakec9680921999-12-13 16:37:25 +000010101#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
Fred Draked86ed291999-12-15 15:34:33 +000010113#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010115#endif
Fred Drakec9680921999-12-13 16:37:25 +000010116#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
Fred Draked86ed291999-12-15 15:34:33 +000010137#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010139#endif
Fred Drakec9680921999-12-13 16:37:25 +000010140#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
Fred Draked86ed291999-12-15 15:34:33 +000010146#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010148#endif
Fred Drakec9680921999-12-13 16:37:25 +000010149#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
Fred Draked86ed291999-12-15 15:34:33 +000010176#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010178#endif
10179#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010181#endif
Fred Drakec9680921999-12-13 16:37:25 +000010182#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
Fred Draked86ed291999-12-15 15:34:33 +000010287#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010289#endif
Fred Drakec9680921999-12-13 16:37:25 +000010290#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010399 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010400#endif
10401#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010402 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010403#endif
10404#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010405 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010406#endif
10407#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010408 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010409#endif
10410#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010411 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010412#endif
10413#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010414 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010415#endif
10416#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010417 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010418#endif
10419#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010420 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010421#endif
10422#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010423 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010424#endif
10425};
10426
10427static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010428conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010429{
10430 return conv_confname(arg, valuep, posix_constants_sysconf,
10431 sizeof(posix_constants_sysconf)
10432 / sizeof(struct constdef));
10433}
10434
Larry Hastings2f936352014-08-05 14:04:04 +100010435
10436/*[clinic input]
10437os.sysconf -> long
10438 name: sysconf_confname
10439 /
10440
10441Return an integer-valued system configuration variable.
10442[clinic start generated code]*/
10443
Larry Hastings2f936352014-08-05 14:04:04 +100010444static long
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010445os_sysconf_impl(PyObject *module, int name)
10446/*[clinic end generated code: output=3662f945fc0cc756 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010447{
10448 long value;
10449
10450 errno = 0;
10451 value = sysconf(name);
10452 if (value == -1 && errno != 0)
10453 posix_error();
10454 return value;
10455}
10456#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010457
10458
Fred Drakebec628d1999-12-15 18:31:10 +000010459/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010460 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010461 * the exported dictionaries that are used to publish information about the
10462 * names available on the host platform.
10463 *
10464 * Sorting the table at runtime ensures that the table is properly ordered
10465 * when used, even for platforms we're not able to test on. It also makes
10466 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010467 */
Fred Drakebec628d1999-12-15 18:31:10 +000010468
10469static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010470cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010471{
10472 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010474 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010475 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010476
10477 return strcmp(c1->name, c2->name);
10478}
10479
10480static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010481setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010482 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010483{
Fred Drakebec628d1999-12-15 18:31:10 +000010484 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010485 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010486
10487 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10488 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010489 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010490 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010491
Barry Warsaw3155db32000-04-13 15:20:40 +000010492 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010493 PyObject *o = PyLong_FromLong(table[i].value);
10494 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10495 Py_XDECREF(o);
10496 Py_DECREF(d);
10497 return -1;
10498 }
10499 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010500 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010501 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010502}
10503
Fred Drakebec628d1999-12-15 18:31:10 +000010504/* Return -1 on failure, 0 on success. */
10505static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010506setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010507{
10508#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010509 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010510 sizeof(posix_constants_pathconf)
10511 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010512 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010513 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010514#endif
10515#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010516 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010517 sizeof(posix_constants_confstr)
10518 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010519 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010520 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010521#endif
10522#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010523 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010524 sizeof(posix_constants_sysconf)
10525 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010526 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010527 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010528#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010529 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010530}
Fred Draked86ed291999-12-15 15:34:33 +000010531
10532
Larry Hastings2f936352014-08-05 14:04:04 +100010533/*[clinic input]
10534os.abort
10535
10536Abort the interpreter immediately.
10537
10538This function 'dumps core' or otherwise fails in the hardest way possible
10539on the hosting operating system. This function never returns.
10540[clinic start generated code]*/
10541
Larry Hastings2f936352014-08-05 14:04:04 +100010542static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010543os_abort_impl(PyObject *module)
10544/*[clinic end generated code: output=dcf52586dad2467c input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010545{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010546 abort();
10547 /*NOTREACHED*/
10548 Py_FatalError("abort() called from Python code didn't abort!");
10549 return NULL;
10550}
Fred Drakebec628d1999-12-15 18:31:10 +000010551
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010552#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010553/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010554PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010555"startfile(filepath [, operation])\n\
10556\n\
10557Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010558\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010559When \"operation\" is not specified or \"open\", this acts like\n\
10560double-clicking the file in Explorer, or giving the file name as an\n\
10561argument to the DOS \"start\" command: the file is opened with whatever\n\
10562application (if any) its extension is associated.\n\
10563When another \"operation\" is given, it specifies what should be done with\n\
10564the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010565\n\
10566startfile returns as soon as the associated application is launched.\n\
10567There is no option to wait for the application to close, and no way\n\
10568to retrieve the application's exit status.\n\
10569\n\
10570The filepath is relative to the current directory. If you want to use\n\
10571an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010572the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010573
Steve Dower7d0e0c92015-01-24 08:18:24 -080010574/* Grab ShellExecute dynamically from shell32 */
10575static int has_ShellExecute = -1;
10576static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10577 LPCSTR, INT);
10578static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10579 LPCWSTR, INT);
10580static int
10581check_ShellExecute()
10582{
10583 HINSTANCE hShell32;
10584
10585 /* only recheck */
10586 if (-1 == has_ShellExecute) {
10587 Py_BEGIN_ALLOW_THREADS
10588 hShell32 = LoadLibraryW(L"SHELL32");
10589 Py_END_ALLOW_THREADS
10590 if (hShell32) {
10591 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10592 "ShellExecuteA");
10593 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10594 "ShellExecuteW");
10595 has_ShellExecute = Py_ShellExecuteA &&
10596 Py_ShellExecuteW;
10597 } else {
10598 has_ShellExecute = 0;
10599 }
10600 }
10601 return has_ShellExecute;
10602}
10603
10604
Tim Petersf58a7aa2000-09-22 10:05:54 +000010605static PyObject *
10606win32_startfile(PyObject *self, PyObject *args)
10607{
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 PyObject *ofilepath;
10609 char *filepath;
10610 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010611 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010612 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010613
Victor Stinnereb5657a2011-09-30 01:44:27 +020010614 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010615
10616 if(!check_ShellExecute()) {
10617 /* If the OS doesn't have ShellExecute, return a
10618 NotImplementedError. */
10619 return PyErr_Format(PyExc_NotImplementedError,
10620 "startfile not available on this platform");
10621 }
10622
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 if (!PyArg_ParseTuple(args, "U|s:startfile",
10624 &unipath, &operation)) {
10625 PyErr_Clear();
10626 goto normal;
10627 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010628
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010630 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010632 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 PyErr_Clear();
10634 operation = NULL;
10635 goto normal;
10636 }
10637 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010638
Victor Stinnereb5657a2011-09-30 01:44:27 +020010639 wpath = PyUnicode_AsUnicode(unipath);
10640 if (wpath == NULL)
10641 goto normal;
10642 if (uoperation) {
10643 woperation = PyUnicode_AsUnicode(uoperation);
10644 if (woperation == NULL)
10645 goto normal;
10646 }
10647 else
10648 woperation = NULL;
10649
Victor Stinner8c62be82010-05-06 00:08:46 +000010650 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010651 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10652 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010653 Py_END_ALLOW_THREADS
10654
Victor Stinnereb5657a2011-09-30 01:44:27 +020010655 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010657 win32_error_object("startfile", unipath);
10658 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010659 }
10660 Py_INCREF(Py_None);
10661 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010662
10663normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010664 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10665 PyUnicode_FSConverter, &ofilepath,
10666 &operation))
10667 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010668 if (win32_warn_bytes_api()) {
10669 Py_DECREF(ofilepath);
10670 return NULL;
10671 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010672 filepath = PyBytes_AsString(ofilepath);
10673 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010674 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10675 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010676 Py_END_ALLOW_THREADS
10677 if (rc <= (HINSTANCE)32) {
10678 PyObject *errval = win32_error("startfile", filepath);
10679 Py_DECREF(ofilepath);
10680 return errval;
10681 }
10682 Py_DECREF(ofilepath);
10683 Py_INCREF(Py_None);
10684 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010685}
Larry Hastings2f936352014-08-05 14:04:04 +100010686#endif /* MS_WINDOWS */
10687
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010688
Martin v. Löwis438b5342002-12-27 10:16:42 +000010689#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010690/*[clinic input]
10691os.getloadavg
10692
10693Return average recent system load information.
10694
10695Return the number of processes in the system run queue averaged over
10696the last 1, 5, and 15 minutes as a tuple of three floats.
10697Raises OSError if the load average was unobtainable.
10698[clinic start generated code]*/
10699
Larry Hastings2f936352014-08-05 14:04:04 +100010700static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010701os_getloadavg_impl(PyObject *module)
10702/*[clinic end generated code: output=9ad3a11bfb4f4bd2 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010703{
10704 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010705 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010706 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10707 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010708 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010709 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010710}
Larry Hastings2f936352014-08-05 14:04:04 +100010711#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010712
Larry Hastings2f936352014-08-05 14:04:04 +100010713
10714/*[clinic input]
10715os.device_encoding
10716 fd: int
10717
10718Return a string describing the encoding of a terminal's file descriptor.
10719
10720The file descriptor must be attached to a terminal.
10721If the device is not a terminal, return None.
10722[clinic start generated code]*/
10723
Larry Hastings2f936352014-08-05 14:04:04 +100010724static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010725os_device_encoding_impl(PyObject *module, int fd)
10726/*[clinic end generated code: output=e0d294bbab7e8c2b input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010727{
Brett Cannonefb00c02012-02-29 18:31:31 -050010728 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010729}
10730
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010731
Larry Hastings2f936352014-08-05 14:04:04 +100010732#ifdef HAVE_SETRESUID
10733/*[clinic input]
10734os.setresuid
10735
10736 ruid: uid_t
10737 euid: uid_t
10738 suid: uid_t
10739 /
10740
10741Set the current process's real, effective, and saved user ids.
10742[clinic start generated code]*/
10743
Larry Hastings2f936352014-08-05 14:04:04 +100010744static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010745os_setresuid_impl(PyObject *module, uid_t ruid, uid_t euid, uid_t suid)
10746/*[clinic end generated code: output=834a641e15373e97 input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010747{
Victor Stinner8c62be82010-05-06 00:08:46 +000010748 if (setresuid(ruid, euid, suid) < 0)
10749 return posix_error();
10750 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010751}
Larry Hastings2f936352014-08-05 14:04:04 +100010752#endif /* HAVE_SETRESUID */
10753
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010754
10755#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010756/*[clinic input]
10757os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010758
Larry Hastings2f936352014-08-05 14:04:04 +100010759 rgid: gid_t
10760 egid: gid_t
10761 sgid: gid_t
10762 /
10763
10764Set the current process's real, effective, and saved group ids.
10765[clinic start generated code]*/
10766
Larry Hastings2f936352014-08-05 14:04:04 +100010767static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010768os_setresgid_impl(PyObject *module, gid_t rgid, gid_t egid, gid_t sgid)
10769/*[clinic end generated code: output=6aa402f3d2e514a9 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010770{
Victor Stinner8c62be82010-05-06 00:08:46 +000010771 if (setresgid(rgid, egid, sgid) < 0)
10772 return posix_error();
10773 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010774}
Larry Hastings2f936352014-08-05 14:04:04 +100010775#endif /* HAVE_SETRESGID */
10776
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010777
10778#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010779/*[clinic input]
10780os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010781
Larry Hastings2f936352014-08-05 14:04:04 +100010782Return a tuple of the current process's real, effective, and saved user ids.
10783[clinic start generated code]*/
10784
Larry Hastings2f936352014-08-05 14:04:04 +100010785static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010786os_getresuid_impl(PyObject *module)
10787/*[clinic end generated code: output=8e0becff5dece5bf input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010788{
Victor Stinner8c62be82010-05-06 00:08:46 +000010789 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010790 if (getresuid(&ruid, &euid, &suid) < 0)
10791 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010792 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10793 _PyLong_FromUid(euid),
10794 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010795}
Larry Hastings2f936352014-08-05 14:04:04 +100010796#endif /* HAVE_GETRESUID */
10797
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010798
10799#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010800/*[clinic input]
10801os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010802
Larry Hastings2f936352014-08-05 14:04:04 +100010803Return a tuple of the current process's real, effective, and saved group ids.
10804[clinic start generated code]*/
10805
Larry Hastings2f936352014-08-05 14:04:04 +100010806static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010807os_getresgid_impl(PyObject *module)
10808/*[clinic end generated code: output=2719c4bfcf27fb9f input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010809{
10810 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010811 if (getresgid(&rgid, &egid, &sgid) < 0)
10812 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010813 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10814 _PyLong_FromGid(egid),
10815 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010816}
Larry Hastings2f936352014-08-05 14:04:04 +100010817#endif /* HAVE_GETRESGID */
10818
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010819
Benjamin Peterson9428d532011-09-14 11:45:52 -040010820#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010821/*[clinic input]
10822os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010823
Larry Hastings2f936352014-08-05 14:04:04 +100010824 path: path_t(allow_fd=True)
10825 attribute: path_t
10826 *
10827 follow_symlinks: bool = True
10828
10829Return the value of extended attribute attribute on path.
10830
10831path may be either a string or an open file descriptor.
10832If follow_symlinks is False, and the last element of the path is a symbolic
10833 link, getxattr will examine the symbolic link itself instead of the file
10834 the link points to.
10835
10836[clinic start generated code]*/
10837
Larry Hastings2f936352014-08-05 14:04:04 +100010838static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010839os_getxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010840 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010841/*[clinic end generated code: output=5f2f44200a43cff2 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010842{
10843 Py_ssize_t i;
10844 PyObject *buffer = NULL;
10845
10846 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10847 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010848
Larry Hastings9cf065c2012-06-22 16:30:09 -070010849 for (i = 0; ; i++) {
10850 void *ptr;
10851 ssize_t result;
10852 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10853 Py_ssize_t buffer_size = buffer_sizes[i];
10854 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010855 path_error(path);
10856 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010857 }
10858 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10859 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010860 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010861 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010862
Larry Hastings9cf065c2012-06-22 16:30:09 -070010863 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010864 if (path->fd >= 0)
10865 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010866 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010867 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010868 else
Larry Hastings2f936352014-08-05 14:04:04 +100010869 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010871
Larry Hastings9cf065c2012-06-22 16:30:09 -070010872 if (result < 0) {
10873 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010874 if (errno == ERANGE)
10875 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010876 path_error(path);
10877 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010878 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010879
Larry Hastings9cf065c2012-06-22 16:30:09 -070010880 if (result != buffer_size) {
10881 /* Can only shrink. */
10882 _PyBytes_Resize(&buffer, result);
10883 }
10884 break;
10885 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010886
Larry Hastings9cf065c2012-06-22 16:30:09 -070010887 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010888}
10889
Larry Hastings2f936352014-08-05 14:04:04 +100010890
10891/*[clinic input]
10892os.setxattr
10893
10894 path: path_t(allow_fd=True)
10895 attribute: path_t
10896 value: Py_buffer
10897 flags: int = 0
10898 *
10899 follow_symlinks: bool = True
10900
10901Set extended attribute attribute on path to value.
10902
10903path may be either a string or an open file descriptor.
10904If follow_symlinks is False, and the last element of the path is a symbolic
10905 link, setxattr will modify the symbolic link itself instead of the file
10906 the link points to.
10907
10908[clinic start generated code]*/
10909
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010911os_setxattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010912 Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010913/*[clinic end generated code: output=98b83f63fdde26bb input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010914{
Larry Hastings2f936352014-08-05 14:04:04 +100010915 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010916
Larry Hastings2f936352014-08-05 14:04:04 +100010917 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010918 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010919
Benjamin Peterson799bd802011-08-31 22:15:17 -040010920 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010921 if (path->fd > -1)
10922 result = fsetxattr(path->fd, attribute->narrow,
10923 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010924 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010925 result = setxattr(path->narrow, attribute->narrow,
10926 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010927 else
Larry Hastings2f936352014-08-05 14:04:04 +100010928 result = lsetxattr(path->narrow, attribute->narrow,
10929 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010930 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010931
Larry Hastings9cf065c2012-06-22 16:30:09 -070010932 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010933 path_error(path);
10934 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010935 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010936
Larry Hastings2f936352014-08-05 14:04:04 +100010937 Py_RETURN_NONE;
10938}
10939
10940
10941/*[clinic input]
10942os.removexattr
10943
10944 path: path_t(allow_fd=True)
10945 attribute: path_t
10946 *
10947 follow_symlinks: bool = True
10948
10949Remove extended attribute attribute on path.
10950
10951path may be either a string or an open file descriptor.
10952If follow_symlinks is False, and the last element of the path is a symbolic
10953 link, removexattr will modify the symbolic link itself instead of the file
10954 the link points to.
10955
10956[clinic start generated code]*/
10957
Larry Hastings2f936352014-08-05 14:04:04 +100010958static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010959os_removexattr_impl(PyObject *module, path_t *path, path_t *attribute,
Larry Hastings89964c42015-04-14 18:07:59 -040010960 int follow_symlinks)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030010961/*[clinic end generated code: output=521a51817980cda6 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010962{
10963 ssize_t result;
10964
10965 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10966 return NULL;
10967
10968 Py_BEGIN_ALLOW_THREADS;
10969 if (path->fd > -1)
10970 result = fremovexattr(path->fd, attribute->narrow);
10971 else if (follow_symlinks)
10972 result = removexattr(path->narrow, attribute->narrow);
10973 else
10974 result = lremovexattr(path->narrow, attribute->narrow);
10975 Py_END_ALLOW_THREADS;
10976
10977 if (result) {
10978 return path_error(path);
10979 }
10980
10981 Py_RETURN_NONE;
10982}
10983
10984
10985/*[clinic input]
10986os.listxattr
10987
10988 path: path_t(allow_fd=True, nullable=True) = None
10989 *
10990 follow_symlinks: bool = True
10991
10992Return a list of extended attributes on path.
10993
10994path may be either None, a string, or an open file descriptor.
10995if path is None, listxattr will examine the current directory.
10996If follow_symlinks is False, and the last element of the path is a symbolic
10997 link, listxattr will examine the symbolic link itself instead of the file
10998 the link points to.
10999[clinic start generated code]*/
11000
Larry Hastings2f936352014-08-05 14:04:04 +100011001static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011002os_listxattr_impl(PyObject *module, path_t *path, int follow_symlinks)
11003/*[clinic end generated code: output=bebdb4e2ad0ce435 input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011004{
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 Py_ssize_t i;
11006 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100011007 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011008 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011009
Larry Hastings2f936352014-08-05 14:04:04 +100011010 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012
Larry Hastings2f936352014-08-05 14:04:04 +100011013 name = path->narrow ? path->narrow : ".";
11014
Larry Hastings9cf065c2012-06-22 16:30:09 -070011015 for (i = 0; ; i++) {
11016 char *start, *trace, *end;
11017 ssize_t length;
11018 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
11019 Py_ssize_t buffer_size = buffer_sizes[i];
11020 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011021 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011022 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011023 break;
11024 }
11025 buffer = PyMem_MALLOC(buffer_size);
11026 if (!buffer) {
11027 PyErr_NoMemory();
11028 break;
11029 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011030
Larry Hastings9cf065c2012-06-22 16:30:09 -070011031 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011032 if (path->fd > -1)
11033 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011034 else if (follow_symlinks)
11035 length = listxattr(name, buffer, buffer_size);
11036 else
11037 length = llistxattr(name, buffer, buffer_size);
11038 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011039
Larry Hastings9cf065c2012-06-22 16:30:09 -070011040 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011041 if (errno == ERANGE) {
11042 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011043 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011044 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011045 }
Larry Hastings2f936352014-08-05 14:04:04 +100011046 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011047 break;
11048 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011049
Larry Hastings9cf065c2012-06-22 16:30:09 -070011050 result = PyList_New(0);
11051 if (!result) {
11052 goto exit;
11053 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011054
Larry Hastings9cf065c2012-06-22 16:30:09 -070011055 end = buffer + length;
11056 for (trace = start = buffer; trace != end; trace++) {
11057 if (!*trace) {
11058 int error;
11059 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11060 trace - start);
11061 if (!attribute) {
11062 Py_DECREF(result);
11063 result = NULL;
11064 goto exit;
11065 }
11066 error = PyList_Append(result, attribute);
11067 Py_DECREF(attribute);
11068 if (error) {
11069 Py_DECREF(result);
11070 result = NULL;
11071 goto exit;
11072 }
11073 start = trace + 1;
11074 }
11075 }
11076 break;
11077 }
11078exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011079 if (buffer)
11080 PyMem_FREE(buffer);
11081 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011082}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011083#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011084
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011085
Larry Hastings2f936352014-08-05 14:04:04 +100011086/*[clinic input]
11087os.urandom
11088
11089 size: Py_ssize_t
11090 /
11091
11092Return a bytes object containing random bytes suitable for cryptographic use.
11093[clinic start generated code]*/
11094
Larry Hastings2f936352014-08-05 14:04:04 +100011095static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011096os_urandom_impl(PyObject *module, Py_ssize_t size)
11097/*[clinic end generated code: output=42c5cca9d18068e9 input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011098{
11099 PyObject *bytes;
11100 int result;
11101
Georg Brandl2fb477c2012-02-21 00:33:36 +010011102 if (size < 0)
11103 return PyErr_Format(PyExc_ValueError,
11104 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011105 bytes = PyBytes_FromStringAndSize(NULL, size);
11106 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011107 return NULL;
11108
Larry Hastings2f936352014-08-05 14:04:04 +100011109 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11110 PyBytes_GET_SIZE(bytes));
11111 if (result == -1) {
11112 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011113 return NULL;
11114 }
Larry Hastings2f936352014-08-05 14:04:04 +100011115 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011116}
11117
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011118/* Terminal size querying */
11119
11120static PyTypeObject TerminalSizeType;
11121
11122PyDoc_STRVAR(TerminalSize_docstring,
11123 "A tuple of (columns, lines) for holding terminal window size");
11124
11125static PyStructSequence_Field TerminalSize_fields[] = {
11126 {"columns", "width of the terminal window in characters"},
11127 {"lines", "height of the terminal window in characters"},
11128 {NULL, NULL}
11129};
11130
11131static PyStructSequence_Desc TerminalSize_desc = {
11132 "os.terminal_size",
11133 TerminalSize_docstring,
11134 TerminalSize_fields,
11135 2,
11136};
11137
11138#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011139/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011140PyDoc_STRVAR(termsize__doc__,
11141 "Return the size of the terminal window as (columns, lines).\n" \
11142 "\n" \
11143 "The optional argument fd (default standard output) specifies\n" \
11144 "which file descriptor should be queried.\n" \
11145 "\n" \
11146 "If the file descriptor is not connected to a terminal, an OSError\n" \
11147 "is thrown.\n" \
11148 "\n" \
11149 "This function will only be defined if an implementation is\n" \
11150 "available for this system.\n" \
11151 "\n" \
11152 "shutil.get_terminal_size is the high-level function which should \n" \
11153 "normally be used, os.get_terminal_size is the low-level implementation.");
11154
11155static PyObject*
11156get_terminal_size(PyObject *self, PyObject *args)
11157{
11158 int columns, lines;
11159 PyObject *termsize;
11160
11161 int fd = fileno(stdout);
11162 /* Under some conditions stdout may not be connected and
11163 * fileno(stdout) may point to an invalid file descriptor. For example
11164 * GUI apps don't have valid standard streams by default.
11165 *
11166 * If this happens, and the optional fd argument is not present,
11167 * the ioctl below will fail returning EBADF. This is what we want.
11168 */
11169
11170 if (!PyArg_ParseTuple(args, "|i", &fd))
11171 return NULL;
11172
11173#ifdef TERMSIZE_USE_IOCTL
11174 {
11175 struct winsize w;
11176 if (ioctl(fd, TIOCGWINSZ, &w))
11177 return PyErr_SetFromErrno(PyExc_OSError);
11178 columns = w.ws_col;
11179 lines = w.ws_row;
11180 }
11181#endif /* TERMSIZE_USE_IOCTL */
11182
11183#ifdef TERMSIZE_USE_CONIO
11184 {
11185 DWORD nhandle;
11186 HANDLE handle;
11187 CONSOLE_SCREEN_BUFFER_INFO csbi;
11188 switch (fd) {
11189 case 0: nhandle = STD_INPUT_HANDLE;
11190 break;
11191 case 1: nhandle = STD_OUTPUT_HANDLE;
11192 break;
11193 case 2: nhandle = STD_ERROR_HANDLE;
11194 break;
11195 default:
11196 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11197 }
11198 handle = GetStdHandle(nhandle);
11199 if (handle == NULL)
11200 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11201 if (handle == INVALID_HANDLE_VALUE)
11202 return PyErr_SetFromWindowsErr(0);
11203
11204 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11205 return PyErr_SetFromWindowsErr(0);
11206
11207 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11208 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11209 }
11210#endif /* TERMSIZE_USE_CONIO */
11211
11212 termsize = PyStructSequence_New(&TerminalSizeType);
11213 if (termsize == NULL)
11214 return NULL;
11215 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11216 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11217 if (PyErr_Occurred()) {
11218 Py_DECREF(termsize);
11219 return NULL;
11220 }
11221 return termsize;
11222}
11223#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11224
Larry Hastings2f936352014-08-05 14:04:04 +100011225
11226/*[clinic input]
11227os.cpu_count
11228
11229Return the number of CPUs in the system; return None if indeterminable.
11230[clinic start generated code]*/
11231
Larry Hastings2f936352014-08-05 14:04:04 +100011232static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011233os_cpu_count_impl(PyObject *module)
11234/*[clinic end generated code: output=5fc29463c3936a9c input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011235{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011236 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011237#ifdef MS_WINDOWS
11238 SYSTEM_INFO sysinfo;
11239 GetSystemInfo(&sysinfo);
11240 ncpu = sysinfo.dwNumberOfProcessors;
11241#elif defined(__hpux)
11242 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11243#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11244 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011245#elif defined(__DragonFly__) || \
11246 defined(__OpenBSD__) || \
11247 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011248 defined(__NetBSD__) || \
11249 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011250 int mib[2];
11251 size_t len = sizeof(ncpu);
11252 mib[0] = CTL_HW;
11253 mib[1] = HW_NCPU;
11254 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11255 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011256#endif
11257 if (ncpu >= 1)
11258 return PyLong_FromLong(ncpu);
11259 else
11260 Py_RETURN_NONE;
11261}
11262
Victor Stinnerdaf45552013-08-28 00:53:59 +020011263
Larry Hastings2f936352014-08-05 14:04:04 +100011264/*[clinic input]
11265os.get_inheritable -> bool
11266
11267 fd: int
11268 /
11269
11270Get the close-on-exe flag of the specified file descriptor.
11271[clinic start generated code]*/
11272
Larry Hastings2f936352014-08-05 14:04:04 +100011273static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011274os_get_inheritable_impl(PyObject *module, int fd)
11275/*[clinic end generated code: output=0445e20e149aa5b8 input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011276{
Steve Dower8fc89802015-04-12 00:26:27 -040011277 int return_value;
11278 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011279 posix_error();
11280 return -1;
11281 }
11282
Steve Dower8fc89802015-04-12 00:26:27 -040011283 _Py_BEGIN_SUPPRESS_IPH
11284 return_value = _Py_get_inheritable(fd);
11285 _Py_END_SUPPRESS_IPH
11286 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011287}
11288
11289
11290/*[clinic input]
11291os.set_inheritable
11292 fd: int
11293 inheritable: int
11294 /
11295
11296Set the inheritable flag of the specified file descriptor.
11297[clinic start generated code]*/
11298
Larry Hastings2f936352014-08-05 14:04:04 +100011299static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011300os_set_inheritable_impl(PyObject *module, int fd, int inheritable)
11301/*[clinic end generated code: output=f1b1918a2f3c38c2 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011302{
Steve Dower8fc89802015-04-12 00:26:27 -040011303 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011304 if (!_PyVerify_fd(fd))
11305 return posix_error();
11306
Steve Dower8fc89802015-04-12 00:26:27 -040011307 _Py_BEGIN_SUPPRESS_IPH
11308 result = _Py_set_inheritable(fd, inheritable, NULL);
11309 _Py_END_SUPPRESS_IPH
11310 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011311 return NULL;
11312 Py_RETURN_NONE;
11313}
11314
11315
11316#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011317/*[clinic input]
11318os.get_handle_inheritable -> bool
11319 handle: Py_intptr_t
11320 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011321
Larry Hastings2f936352014-08-05 14:04:04 +100011322Get the close-on-exe flag of the specified file descriptor.
11323[clinic start generated code]*/
11324
Larry Hastings2f936352014-08-05 14:04:04 +100011325static int
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011326os_get_handle_inheritable_impl(PyObject *module, Py_intptr_t handle)
11327/*[clinic end generated code: output=9e5389b0aa0916ce input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011328{
11329 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011330
11331 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11332 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011333 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011334 }
11335
Larry Hastings2f936352014-08-05 14:04:04 +100011336 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011337}
11338
Victor Stinnerdaf45552013-08-28 00:53:59 +020011339
Larry Hastings2f936352014-08-05 14:04:04 +100011340/*[clinic input]
11341os.set_handle_inheritable
11342 handle: Py_intptr_t
11343 inheritable: bool
11344 /
11345
11346Set the inheritable flag of the specified handle.
11347[clinic start generated code]*/
11348
Larry Hastings2f936352014-08-05 14:04:04 +100011349static PyObject *
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011350os_set_handle_inheritable_impl(PyObject *module, Py_intptr_t handle,
Larry Hastings89964c42015-04-14 18:07:59 -040011351 int inheritable)
Serhiy Storchaka1a2b24f2016-07-07 17:35:15 +030011352/*[clinic end generated code: output=b1e67bfa3213d745 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011353{
11354 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011355 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11356 PyErr_SetFromWindowsErr(0);
11357 return NULL;
11358 }
11359 Py_RETURN_NONE;
11360}
Larry Hastings2f936352014-08-05 14:04:04 +100011361#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011362
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011363#ifndef MS_WINDOWS
11364PyDoc_STRVAR(get_blocking__doc__,
11365 "get_blocking(fd) -> bool\n" \
11366 "\n" \
11367 "Get the blocking mode of the file descriptor:\n" \
11368 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11369
11370static PyObject*
11371posix_get_blocking(PyObject *self, PyObject *args)
11372{
11373 int fd;
11374 int blocking;
11375
11376 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
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
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011383 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011384 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011385 if (blocking < 0)
11386 return NULL;
11387 return PyBool_FromLong(blocking);
11388}
11389
11390PyDoc_STRVAR(set_blocking__doc__,
11391 "set_blocking(fd, blocking)\n" \
11392 "\n" \
11393 "Set the blocking mode of the specified file descriptor.\n" \
11394 "Set the O_NONBLOCK flag if blocking is False,\n" \
11395 "clear the O_NONBLOCK flag otherwise.");
11396
11397static PyObject*
11398posix_set_blocking(PyObject *self, PyObject *args)
11399{
Steve Dower8fc89802015-04-12 00:26:27 -040011400 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011401
11402 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11403 return NULL;
11404
11405 if (!_PyVerify_fd(fd))
11406 return posix_error();
11407
Steve Dower8fc89802015-04-12 00:26:27 -040011408 _Py_BEGIN_SUPPRESS_IPH
11409 result = _Py_set_blocking(fd, blocking);
11410 _Py_END_SUPPRESS_IPH
11411 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011412 return NULL;
11413 Py_RETURN_NONE;
11414}
11415#endif /* !MS_WINDOWS */
11416
11417
Victor Stinner6036e442015-03-08 01:58:04 +010011418PyDoc_STRVAR(posix_scandir__doc__,
11419"scandir(path='.') -> iterator of DirEntry objects for given path");
11420
11421static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11422
11423typedef struct {
11424 PyObject_HEAD
11425 PyObject *name;
11426 PyObject *path;
11427 PyObject *stat;
11428 PyObject *lstat;
11429#ifdef MS_WINDOWS
11430 struct _Py_stat_struct win32_lstat;
11431 __int64 win32_file_index;
11432 int got_file_index;
11433#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011434#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011435 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011436#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011437 ino_t d_ino;
11438#endif
11439} DirEntry;
11440
11441static void
11442DirEntry_dealloc(DirEntry *entry)
11443{
11444 Py_XDECREF(entry->name);
11445 Py_XDECREF(entry->path);
11446 Py_XDECREF(entry->stat);
11447 Py_XDECREF(entry->lstat);
11448 Py_TYPE(entry)->tp_free((PyObject *)entry);
11449}
11450
11451/* Forward reference */
11452static int
11453DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11454
11455/* Set exception and return -1 on error, 0 for False, 1 for True */
11456static int
11457DirEntry_is_symlink(DirEntry *self)
11458{
11459#ifdef MS_WINDOWS
11460 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011461#elif defined(HAVE_DIRENT_D_TYPE)
11462 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011463 if (self->d_type != DT_UNKNOWN)
11464 return self->d_type == DT_LNK;
11465 else
11466 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011467#else
11468 /* POSIX without d_type */
11469 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011470#endif
11471}
11472
11473static PyObject *
11474DirEntry_py_is_symlink(DirEntry *self)
11475{
11476 int result;
11477
11478 result = DirEntry_is_symlink(self);
11479 if (result == -1)
11480 return NULL;
11481 return PyBool_FromLong(result);
11482}
11483
11484static PyObject *
11485DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11486{
11487 int result;
11488 struct _Py_stat_struct st;
11489
11490#ifdef MS_WINDOWS
11491 wchar_t *path;
11492
11493 path = PyUnicode_AsUnicode(self->path);
11494 if (!path)
11495 return NULL;
11496
11497 if (follow_symlinks)
11498 result = win32_stat_w(path, &st);
11499 else
11500 result = win32_lstat_w(path, &st);
11501
11502 if (result != 0) {
11503 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11504 0, self->path);
11505 }
11506#else /* POSIX */
11507 PyObject *bytes;
11508 char *path;
11509
11510 if (!PyUnicode_FSConverter(self->path, &bytes))
11511 return NULL;
11512 path = PyBytes_AS_STRING(bytes);
11513
11514 if (follow_symlinks)
11515 result = STAT(path, &st);
11516 else
11517 result = LSTAT(path, &st);
11518 Py_DECREF(bytes);
11519
11520 if (result != 0)
11521 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11522#endif
11523
11524 return _pystat_fromstructstat(&st);
11525}
11526
11527static PyObject *
11528DirEntry_get_lstat(DirEntry *self)
11529{
11530 if (!self->lstat) {
11531#ifdef MS_WINDOWS
11532 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11533#else /* POSIX */
11534 self->lstat = DirEntry_fetch_stat(self, 0);
11535#endif
11536 }
11537 Py_XINCREF(self->lstat);
11538 return self->lstat;
11539}
11540
11541static PyObject *
11542DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11543{
11544 if (!follow_symlinks)
11545 return DirEntry_get_lstat(self);
11546
11547 if (!self->stat) {
11548 int result = DirEntry_is_symlink(self);
11549 if (result == -1)
11550 return NULL;
11551 else if (result)
11552 self->stat = DirEntry_fetch_stat(self, 1);
11553 else
11554 self->stat = DirEntry_get_lstat(self);
11555 }
11556
11557 Py_XINCREF(self->stat);
11558 return self->stat;
11559}
11560
11561static PyObject *
11562DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11563{
11564 int follow_symlinks = 1;
11565
11566 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11567 follow_symlinks_keywords, &follow_symlinks))
11568 return NULL;
11569
11570 return DirEntry_get_stat(self, follow_symlinks);
11571}
11572
11573/* Set exception and return -1 on error, 0 for False, 1 for True */
11574static int
11575DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11576{
11577 PyObject *stat = NULL;
11578 PyObject *st_mode = NULL;
11579 long mode;
11580 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011581#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011582 int is_symlink;
11583 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011584#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011585#ifdef MS_WINDOWS
11586 unsigned long dir_bits;
11587#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011588 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011589
11590#ifdef MS_WINDOWS
11591 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11592 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011593#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011594 is_symlink = self->d_type == DT_LNK;
11595 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11596#endif
11597
Victor Stinner35a97c02015-03-08 02:59:09 +010011598#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011599 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011600#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011601 stat = DirEntry_get_stat(self, follow_symlinks);
11602 if (!stat) {
11603 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11604 /* If file doesn't exist (anymore), then return False
11605 (i.e., say it's not a file/directory) */
11606 PyErr_Clear();
11607 return 0;
11608 }
11609 goto error;
11610 }
11611 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11612 if (!st_mode)
11613 goto error;
11614
11615 mode = PyLong_AsLong(st_mode);
11616 if (mode == -1 && PyErr_Occurred())
11617 goto error;
11618 Py_CLEAR(st_mode);
11619 Py_CLEAR(stat);
11620 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011621#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011622 }
11623 else if (is_symlink) {
11624 assert(mode_bits != S_IFLNK);
11625 result = 0;
11626 }
11627 else {
11628 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11629#ifdef MS_WINDOWS
11630 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11631 if (mode_bits == S_IFDIR)
11632 result = dir_bits != 0;
11633 else
11634 result = dir_bits == 0;
11635#else /* POSIX */
11636 if (mode_bits == S_IFDIR)
11637 result = self->d_type == DT_DIR;
11638 else
11639 result = self->d_type == DT_REG;
11640#endif
11641 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011642#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011643
11644 return result;
11645
11646error:
11647 Py_XDECREF(st_mode);
11648 Py_XDECREF(stat);
11649 return -1;
11650}
11651
11652static PyObject *
11653DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11654{
11655 int result;
11656
11657 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11658 if (result == -1)
11659 return NULL;
11660 return PyBool_FromLong(result);
11661}
11662
11663static PyObject *
11664DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11665{
11666 int follow_symlinks = 1;
11667
11668 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11669 follow_symlinks_keywords, &follow_symlinks))
11670 return NULL;
11671
11672 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11673}
11674
11675static PyObject *
11676DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11677{
11678 int follow_symlinks = 1;
11679
11680 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11681 follow_symlinks_keywords, &follow_symlinks))
11682 return NULL;
11683
11684 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11685}
11686
11687static PyObject *
11688DirEntry_inode(DirEntry *self)
11689{
11690#ifdef MS_WINDOWS
11691 if (!self->got_file_index) {
11692 wchar_t *path;
11693 struct _Py_stat_struct stat;
11694
11695 path = PyUnicode_AsUnicode(self->path);
11696 if (!path)
11697 return NULL;
11698
11699 if (win32_lstat_w(path, &stat) != 0) {
11700 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11701 0, self->path);
11702 }
11703
11704 self->win32_file_index = stat.st_ino;
11705 self->got_file_index = 1;
11706 }
11707 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11708#else /* POSIX */
11709#ifdef HAVE_LARGEFILE_SUPPORT
11710 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11711#else
11712 return PyLong_FromLong((long)self->d_ino);
11713#endif
11714#endif
11715}
11716
11717static PyObject *
11718DirEntry_repr(DirEntry *self)
11719{
11720 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11721}
11722
11723static PyMemberDef DirEntry_members[] = {
11724 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11725 "the entry's base filename, relative to scandir() \"path\" argument"},
11726 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11727 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11728 {NULL}
11729};
11730
11731static PyMethodDef DirEntry_methods[] = {
11732 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11733 "return True if the entry is a directory; cached per entry"
11734 },
11735 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11736 "return True if the entry is a file; cached per entry"
11737 },
11738 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11739 "return True if the entry is a symbolic link; cached per entry"
11740 },
11741 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11742 "return stat_result object for the entry; cached per entry"
11743 },
11744 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11745 "return inode of the entry; cached per entry",
11746 },
11747 {NULL}
11748};
11749
Benjamin Peterson5646de42015-04-12 17:56:34 -040011750static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011751 PyVarObject_HEAD_INIT(NULL, 0)
11752 MODNAME ".DirEntry", /* tp_name */
11753 sizeof(DirEntry), /* tp_basicsize */
11754 0, /* tp_itemsize */
11755 /* methods */
11756 (destructor)DirEntry_dealloc, /* tp_dealloc */
11757 0, /* tp_print */
11758 0, /* tp_getattr */
11759 0, /* tp_setattr */
11760 0, /* tp_compare */
11761 (reprfunc)DirEntry_repr, /* tp_repr */
11762 0, /* tp_as_number */
11763 0, /* tp_as_sequence */
11764 0, /* tp_as_mapping */
11765 0, /* tp_hash */
11766 0, /* tp_call */
11767 0, /* tp_str */
11768 0, /* tp_getattro */
11769 0, /* tp_setattro */
11770 0, /* tp_as_buffer */
11771 Py_TPFLAGS_DEFAULT, /* tp_flags */
11772 0, /* tp_doc */
11773 0, /* tp_traverse */
11774 0, /* tp_clear */
11775 0, /* tp_richcompare */
11776 0, /* tp_weaklistoffset */
11777 0, /* tp_iter */
11778 0, /* tp_iternext */
11779 DirEntry_methods, /* tp_methods */
11780 DirEntry_members, /* tp_members */
11781};
11782
11783#ifdef MS_WINDOWS
11784
11785static wchar_t *
11786join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11787{
11788 Py_ssize_t path_len;
11789 Py_ssize_t size;
11790 wchar_t *result;
11791 wchar_t ch;
11792
11793 if (!path_wide) { /* Default arg: "." */
11794 path_wide = L".";
11795 path_len = 1;
11796 }
11797 else {
11798 path_len = wcslen(path_wide);
11799 }
11800
11801 /* The +1's are for the path separator and the NUL */
11802 size = path_len + 1 + wcslen(filename) + 1;
11803 result = PyMem_New(wchar_t, size);
11804 if (!result) {
11805 PyErr_NoMemory();
11806 return NULL;
11807 }
11808 wcscpy(result, path_wide);
11809 if (path_len > 0) {
11810 ch = result[path_len - 1];
11811 if (ch != SEP && ch != ALTSEP && ch != L':')
11812 result[path_len++] = SEP;
11813 wcscpy(result + path_len, filename);
11814 }
11815 return result;
11816}
11817
11818static PyObject *
11819DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11820{
11821 DirEntry *entry;
11822 BY_HANDLE_FILE_INFORMATION file_info;
11823 ULONG reparse_tag;
11824 wchar_t *joined_path;
11825
11826 entry = PyObject_New(DirEntry, &DirEntryType);
11827 if (!entry)
11828 return NULL;
11829 entry->name = NULL;
11830 entry->path = NULL;
11831 entry->stat = NULL;
11832 entry->lstat = NULL;
11833 entry->got_file_index = 0;
11834
11835 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11836 if (!entry->name)
11837 goto error;
11838
11839 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11840 if (!joined_path)
11841 goto error;
11842
11843 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11844 PyMem_Free(joined_path);
11845 if (!entry->path)
11846 goto error;
11847
11848 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11849 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11850
11851 return (PyObject *)entry;
11852
11853error:
11854 Py_DECREF(entry);
11855 return NULL;
11856}
11857
11858#else /* POSIX */
11859
11860static char *
11861join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11862{
11863 Py_ssize_t path_len;
11864 Py_ssize_t size;
11865 char *result;
11866
11867 if (!path_narrow) { /* Default arg: "." */
11868 path_narrow = ".";
11869 path_len = 1;
11870 }
11871 else {
11872 path_len = strlen(path_narrow);
11873 }
11874
11875 if (filename_len == -1)
11876 filename_len = strlen(filename);
11877
11878 /* The +1's are for the path separator and the NUL */
11879 size = path_len + 1 + filename_len + 1;
11880 result = PyMem_New(char, size);
11881 if (!result) {
11882 PyErr_NoMemory();
11883 return NULL;
11884 }
11885 strcpy(result, path_narrow);
11886 if (path_len > 0 && result[path_len - 1] != '/')
11887 result[path_len++] = '/';
11888 strcpy(result + path_len, filename);
11889 return result;
11890}
11891
11892static PyObject *
11893DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011894 ino_t d_ino
11895#ifdef HAVE_DIRENT_D_TYPE
11896 , unsigned char d_type
11897#endif
11898 )
Victor Stinner6036e442015-03-08 01:58:04 +010011899{
11900 DirEntry *entry;
11901 char *joined_path;
11902
11903 entry = PyObject_New(DirEntry, &DirEntryType);
11904 if (!entry)
11905 return NULL;
11906 entry->name = NULL;
11907 entry->path = NULL;
11908 entry->stat = NULL;
11909 entry->lstat = NULL;
11910
11911 joined_path = join_path_filename(path->narrow, name, name_len);
11912 if (!joined_path)
11913 goto error;
11914
11915 if (!path->narrow || !PyBytes_Check(path->object)) {
11916 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11917 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11918 }
11919 else {
11920 entry->name = PyBytes_FromStringAndSize(name, name_len);
11921 entry->path = PyBytes_FromString(joined_path);
11922 }
11923 PyMem_Free(joined_path);
11924 if (!entry->name || !entry->path)
11925 goto error;
11926
Victor Stinner35a97c02015-03-08 02:59:09 +010011927#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011928 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011929#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011930 entry->d_ino = d_ino;
11931
11932 return (PyObject *)entry;
11933
11934error:
11935 Py_XDECREF(entry);
11936 return NULL;
11937}
11938
11939#endif
11940
11941
11942typedef struct {
11943 PyObject_HEAD
11944 path_t path;
11945#ifdef MS_WINDOWS
11946 HANDLE handle;
11947 WIN32_FIND_DATAW file_data;
11948 int first_time;
11949#else /* POSIX */
11950 DIR *dirp;
11951#endif
11952} ScandirIterator;
11953
11954#ifdef MS_WINDOWS
11955
11956static void
11957ScandirIterator_close(ScandirIterator *iterator)
11958{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011959 HANDLE handle = iterator->handle;
11960
11961 if (handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011962 return;
11963
Victor Stinner6036e442015-03-08 01:58:04 +010011964 iterator->handle = INVALID_HANDLE_VALUE;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030011965 Py_BEGIN_ALLOW_THREADS
11966 FindClose(handle);
11967 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010011968}
11969
11970static PyObject *
11971ScandirIterator_iternext(ScandirIterator *iterator)
11972{
11973 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11974 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011975 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011976
11977 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011978 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011979 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011980
11981 while (1) {
11982 if (!iterator->first_time) {
11983 Py_BEGIN_ALLOW_THREADS
11984 success = FindNextFileW(iterator->handle, file_data);
11985 Py_END_ALLOW_THREADS
11986 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011987 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011988 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011989 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011990 break;
11991 }
11992 }
11993 iterator->first_time = 0;
11994
11995 /* Skip over . and .. */
11996 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011997 wcscmp(file_data->cFileName, L"..") != 0) {
11998 entry = DirEntry_from_find_data(&iterator->path, file_data);
11999 if (!entry)
12000 break;
12001 return entry;
12002 }
Victor Stinner6036e442015-03-08 01:58:04 +010012003
12004 /* Loop till we get a non-dot directory or finish iterating */
12005 }
12006
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012007 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012008 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012009 return NULL;
12010}
12011
12012#else /* POSIX */
12013
12014static void
12015ScandirIterator_close(ScandirIterator *iterator)
12016{
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012017 DIR *dirp = iterator->dirp;
12018
12019 if (!dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012020 return;
12021
Victor Stinner6036e442015-03-08 01:58:04 +010012022 iterator->dirp = NULL;
Serhiy Storchakafbb1c5e2016-03-30 20:40:02 +030012023 Py_BEGIN_ALLOW_THREADS
12024 closedir(dirp);
12025 Py_END_ALLOW_THREADS
Victor Stinner6036e442015-03-08 01:58:04 +010012026 return;
12027}
12028
12029static PyObject *
12030ScandirIterator_iternext(ScandirIterator *iterator)
12031{
12032 struct dirent *direntp;
12033 Py_ssize_t name_len;
12034 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012035 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012036
12037 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012038 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012039 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012040
12041 while (1) {
12042 errno = 0;
12043 Py_BEGIN_ALLOW_THREADS
12044 direntp = readdir(iterator->dirp);
12045 Py_END_ALLOW_THREADS
12046
12047 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012048 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012049 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012050 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012051 break;
12052 }
12053
12054 /* Skip over . and .. */
12055 name_len = NAMLEN(direntp);
12056 is_dot = direntp->d_name[0] == '.' &&
12057 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12058 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012059 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012060 name_len, direntp->d_ino
12061#ifdef HAVE_DIRENT_D_TYPE
12062 , direntp->d_type
12063#endif
12064 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012065 if (!entry)
12066 break;
12067 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012068 }
12069
12070 /* Loop till we get a non-dot directory or finish iterating */
12071 }
12072
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012073 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012074 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012075 return NULL;
12076}
12077
12078#endif
12079
12080static void
12081ScandirIterator_dealloc(ScandirIterator *iterator)
12082{
12083 ScandirIterator_close(iterator);
12084 Py_XDECREF(iterator->path.object);
12085 path_cleanup(&iterator->path);
12086 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12087}
12088
Benjamin Peterson5646de42015-04-12 17:56:34 -040012089static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012090 PyVarObject_HEAD_INIT(NULL, 0)
12091 MODNAME ".ScandirIterator", /* tp_name */
12092 sizeof(ScandirIterator), /* tp_basicsize */
12093 0, /* tp_itemsize */
12094 /* methods */
12095 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12096 0, /* tp_print */
12097 0, /* tp_getattr */
12098 0, /* tp_setattr */
12099 0, /* tp_compare */
12100 0, /* tp_repr */
12101 0, /* tp_as_number */
12102 0, /* tp_as_sequence */
12103 0, /* tp_as_mapping */
12104 0, /* tp_hash */
12105 0, /* tp_call */
12106 0, /* tp_str */
12107 0, /* tp_getattro */
12108 0, /* tp_setattro */
12109 0, /* tp_as_buffer */
12110 Py_TPFLAGS_DEFAULT, /* tp_flags */
12111 0, /* tp_doc */
12112 0, /* tp_traverse */
12113 0, /* tp_clear */
12114 0, /* tp_richcompare */
12115 0, /* tp_weaklistoffset */
12116 PyObject_SelfIter, /* tp_iter */
12117 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12118};
12119
12120static PyObject *
12121posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12122{
12123 ScandirIterator *iterator;
12124 static char *keywords[] = {"path", NULL};
12125#ifdef MS_WINDOWS
12126 wchar_t *path_strW;
12127#else
12128 char *path;
12129#endif
12130
12131 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12132 if (!iterator)
12133 return NULL;
12134 memset(&iterator->path, 0, sizeof(path_t));
12135 iterator->path.function_name = "scandir";
12136 iterator->path.nullable = 1;
12137
12138#ifdef MS_WINDOWS
12139 iterator->handle = INVALID_HANDLE_VALUE;
12140#else
12141 iterator->dirp = NULL;
12142#endif
12143
12144 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12145 path_converter, &iterator->path))
12146 goto error;
12147
12148 /* path_converter doesn't keep path.object around, so do it
12149 manually for the lifetime of the iterator here (the refcount
12150 is decremented in ScandirIterator_dealloc)
12151 */
12152 Py_XINCREF(iterator->path.object);
12153
12154#ifdef MS_WINDOWS
12155 if (iterator->path.narrow) {
12156 PyErr_SetString(PyExc_TypeError,
12157 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12158 goto error;
12159 }
12160 iterator->first_time = 1;
12161
12162 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12163 if (!path_strW)
12164 goto error;
12165
12166 Py_BEGIN_ALLOW_THREADS
12167 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12168 Py_END_ALLOW_THREADS
12169
12170 PyMem_Free(path_strW);
12171
12172 if (iterator->handle == INVALID_HANDLE_VALUE) {
12173 path_error(&iterator->path);
12174 goto error;
12175 }
12176#else /* POSIX */
12177 if (iterator->path.narrow)
12178 path = iterator->path.narrow;
12179 else
12180 path = ".";
12181
12182 errno = 0;
12183 Py_BEGIN_ALLOW_THREADS
12184 iterator->dirp = opendir(path);
12185 Py_END_ALLOW_THREADS
12186
12187 if (!iterator->dirp) {
12188 path_error(&iterator->path);
12189 goto error;
12190 }
12191#endif
12192
12193 return (PyObject *)iterator;
12194
12195error:
12196 Py_DECREF(iterator);
12197 return NULL;
12198}
12199
12200
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012201#include "clinic/posixmodule.c.h"
12202
Larry Hastings7726ac92014-01-31 22:03:12 -080012203/*[clinic input]
12204dump buffer
12205[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012206/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012207
Larry Hastings31826802013-10-19 00:09:25 -070012208
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012209static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012210
12211 OS_STAT_METHODDEF
12212 OS_ACCESS_METHODDEF
12213 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012214 OS_CHDIR_METHODDEF
12215 OS_CHFLAGS_METHODDEF
12216 OS_CHMOD_METHODDEF
12217 OS_FCHMOD_METHODDEF
12218 OS_LCHMOD_METHODDEF
12219 OS_CHOWN_METHODDEF
12220 OS_FCHOWN_METHODDEF
12221 OS_LCHOWN_METHODDEF
12222 OS_LCHFLAGS_METHODDEF
12223 OS_CHROOT_METHODDEF
12224 OS_CTERMID_METHODDEF
12225 OS_GETCWD_METHODDEF
12226 OS_GETCWDB_METHODDEF
12227 OS_LINK_METHODDEF
12228 OS_LISTDIR_METHODDEF
12229 OS_LSTAT_METHODDEF
12230 OS_MKDIR_METHODDEF
12231 OS_NICE_METHODDEF
12232 OS_GETPRIORITY_METHODDEF
12233 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012234#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012235 {"readlink", (PyCFunction)posix_readlink,
12236 METH_VARARGS | METH_KEYWORDS,
12237 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012238#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012239#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012240 {"readlink", (PyCFunction)win_readlink,
12241 METH_VARARGS | METH_KEYWORDS,
12242 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012243#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012244 OS_RENAME_METHODDEF
12245 OS_REPLACE_METHODDEF
12246 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012247 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012248 OS_SYMLINK_METHODDEF
12249 OS_SYSTEM_METHODDEF
12250 OS_UMASK_METHODDEF
12251 OS_UNAME_METHODDEF
12252 OS_UNLINK_METHODDEF
12253 OS_REMOVE_METHODDEF
12254 OS_UTIME_METHODDEF
12255 OS_TIMES_METHODDEF
12256 OS__EXIT_METHODDEF
12257 OS_EXECV_METHODDEF
12258 OS_EXECVE_METHODDEF
12259 OS_SPAWNV_METHODDEF
12260 OS_SPAWNVE_METHODDEF
12261 OS_FORK1_METHODDEF
12262 OS_FORK_METHODDEF
12263 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12264 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12265 OS_SCHED_GETPARAM_METHODDEF
12266 OS_SCHED_GETSCHEDULER_METHODDEF
12267 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12268 OS_SCHED_SETPARAM_METHODDEF
12269 OS_SCHED_SETSCHEDULER_METHODDEF
12270 OS_SCHED_YIELD_METHODDEF
12271 OS_SCHED_SETAFFINITY_METHODDEF
12272 OS_SCHED_GETAFFINITY_METHODDEF
12273 OS_OPENPTY_METHODDEF
12274 OS_FORKPTY_METHODDEF
12275 OS_GETEGID_METHODDEF
12276 OS_GETEUID_METHODDEF
12277 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012278#ifdef HAVE_GETGROUPLIST
12279 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12280#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012281 OS_GETGROUPS_METHODDEF
12282 OS_GETPID_METHODDEF
12283 OS_GETPGRP_METHODDEF
12284 OS_GETPPID_METHODDEF
12285 OS_GETUID_METHODDEF
12286 OS_GETLOGIN_METHODDEF
12287 OS_KILL_METHODDEF
12288 OS_KILLPG_METHODDEF
12289 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012290#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012291 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012292#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012293 OS_SETUID_METHODDEF
12294 OS_SETEUID_METHODDEF
12295 OS_SETREUID_METHODDEF
12296 OS_SETGID_METHODDEF
12297 OS_SETEGID_METHODDEF
12298 OS_SETREGID_METHODDEF
12299 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012300#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012301 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012302#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012303 OS_GETPGID_METHODDEF
12304 OS_SETPGRP_METHODDEF
12305 OS_WAIT_METHODDEF
12306 OS_WAIT3_METHODDEF
12307 OS_WAIT4_METHODDEF
12308 OS_WAITID_METHODDEF
12309 OS_WAITPID_METHODDEF
12310 OS_GETSID_METHODDEF
12311 OS_SETSID_METHODDEF
12312 OS_SETPGID_METHODDEF
12313 OS_TCGETPGRP_METHODDEF
12314 OS_TCSETPGRP_METHODDEF
12315 OS_OPEN_METHODDEF
12316 OS_CLOSE_METHODDEF
12317 OS_CLOSERANGE_METHODDEF
12318 OS_DEVICE_ENCODING_METHODDEF
12319 OS_DUP_METHODDEF
12320 OS_DUP2_METHODDEF
12321 OS_LOCKF_METHODDEF
12322 OS_LSEEK_METHODDEF
12323 OS_READ_METHODDEF
12324 OS_READV_METHODDEF
12325 OS_PREAD_METHODDEF
12326 OS_WRITE_METHODDEF
12327 OS_WRITEV_METHODDEF
12328 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012329#ifdef HAVE_SENDFILE
12330 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12331 posix_sendfile__doc__},
12332#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012333 OS_FSTAT_METHODDEF
12334 OS_ISATTY_METHODDEF
12335 OS_PIPE_METHODDEF
12336 OS_PIPE2_METHODDEF
12337 OS_MKFIFO_METHODDEF
12338 OS_MKNOD_METHODDEF
12339 OS_MAJOR_METHODDEF
12340 OS_MINOR_METHODDEF
12341 OS_MAKEDEV_METHODDEF
12342 OS_FTRUNCATE_METHODDEF
12343 OS_TRUNCATE_METHODDEF
12344 OS_POSIX_FALLOCATE_METHODDEF
12345 OS_POSIX_FADVISE_METHODDEF
12346 OS_PUTENV_METHODDEF
12347 OS_UNSETENV_METHODDEF
12348 OS_STRERROR_METHODDEF
12349 OS_FCHDIR_METHODDEF
12350 OS_FSYNC_METHODDEF
12351 OS_SYNC_METHODDEF
12352 OS_FDATASYNC_METHODDEF
12353 OS_WCOREDUMP_METHODDEF
12354 OS_WIFCONTINUED_METHODDEF
12355 OS_WIFSTOPPED_METHODDEF
12356 OS_WIFSIGNALED_METHODDEF
12357 OS_WIFEXITED_METHODDEF
12358 OS_WEXITSTATUS_METHODDEF
12359 OS_WTERMSIG_METHODDEF
12360 OS_WSTOPSIG_METHODDEF
12361 OS_FSTATVFS_METHODDEF
12362 OS_STATVFS_METHODDEF
12363 OS_CONFSTR_METHODDEF
12364 OS_SYSCONF_METHODDEF
12365 OS_FPATHCONF_METHODDEF
12366 OS_PATHCONF_METHODDEF
12367 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012368 OS__GETFULLPATHNAME_METHODDEF
12369 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012370 OS__GETDISKUSAGE_METHODDEF
12371 OS__GETFINALPATHNAME_METHODDEF
12372 OS__GETVOLUMEPATHNAME_METHODDEF
12373 OS_GETLOADAVG_METHODDEF
12374 OS_URANDOM_METHODDEF
12375 OS_SETRESUID_METHODDEF
12376 OS_SETRESGID_METHODDEF
12377 OS_GETRESUID_METHODDEF
12378 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012379
Larry Hastings2f936352014-08-05 14:04:04 +100012380 OS_GETXATTR_METHODDEF
12381 OS_SETXATTR_METHODDEF
12382 OS_REMOVEXATTR_METHODDEF
12383 OS_LISTXATTR_METHODDEF
12384
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012385#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12386 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12387#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012388 OS_CPU_COUNT_METHODDEF
12389 OS_GET_INHERITABLE_METHODDEF
12390 OS_SET_INHERITABLE_METHODDEF
12391 OS_GET_HANDLE_INHERITABLE_METHODDEF
12392 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012393#ifndef MS_WINDOWS
12394 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12395 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12396#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012397 {"scandir", (PyCFunction)posix_scandir,
12398 METH_VARARGS | METH_KEYWORDS,
12399 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012400 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012401};
12402
12403
Brian Curtin52173d42010-12-02 18:29:18 +000012404#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012405static int
Brian Curtin52173d42010-12-02 18:29:18 +000012406enable_symlink()
12407{
12408 HANDLE tok;
12409 TOKEN_PRIVILEGES tok_priv;
12410 LUID luid;
12411 int meth_idx = 0;
12412
12413 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012414 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012415
12416 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012417 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012418
12419 tok_priv.PrivilegeCount = 1;
12420 tok_priv.Privileges[0].Luid = luid;
12421 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12422
12423 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12424 sizeof(TOKEN_PRIVILEGES),
12425 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012426 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012427
Brian Curtin3b4499c2010-12-28 14:31:47 +000012428 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12429 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012430}
12431#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12432
Barry Warsaw4a342091996-12-19 23:50:02 +000012433static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012434all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012435{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012436#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012437 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012438#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012439#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012441#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012442#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012443 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012444#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012445#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012446 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012447#endif
Fred Drakec9680921999-12-13 16:37:25 +000012448#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012449 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012450#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012451#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012453#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012454#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012456#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012457#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012459#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012460#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012462#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012463#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012464 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012465#endif
12466#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012468#endif
12469#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012471#endif
12472#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012473 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012474#endif
12475#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012477#endif
12478#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012480#endif
12481#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012483#endif
12484#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012486#endif
12487#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012489#endif
12490#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012492#endif
12493#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012494 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012495#endif
12496#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012498#endif
12499#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012501#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012502#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012503 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012504#endif
12505#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012507#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012508#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012509 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012510#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012511#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012512 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012513#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012514#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012516#endif
12517#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012518 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012519#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012520#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012522#endif
12523#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012525#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012526#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012527 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012528#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012529#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012531#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012532#ifdef O_TMPFILE
12533 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12534#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012535#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012537#endif
12538#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012539 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012540#endif
12541#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012542 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012543#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012544#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012545 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012546#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012547#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012548 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012549#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012550
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012551
Jesus Cea94363612012-06-22 18:32:07 +020012552#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012553 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012554#endif
12555#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012556 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012557#endif
12558
Tim Peters5aa91602002-01-30 05:46:57 +000012559/* MS Windows */
12560#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012561 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012563#endif
12564#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 /* Optimize for short life (keep in memory). */
12566 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012568#endif
12569#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012570 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012571 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012572#endif
12573#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012574 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012576#endif
12577#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012578 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012580#endif
12581
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012582/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012583#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012584 /* Send a SIGIO signal whenever input or output
12585 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012587#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012588#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012589 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012591#endif
12592#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012593 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012595#endif
12596#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012597 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012599#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012600#ifdef O_NOLINKS
12601 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012603#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012604#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012605 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012607#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012608
Victor Stinner8c62be82010-05-06 00:08:46 +000012609 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012610#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012612#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012613#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012615#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012616#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012618#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012619#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012621#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012622#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012624#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012625#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012626 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012627#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012628#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012629 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012630#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012631#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012633#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012634#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012636#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012637#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012639#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012640#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012642#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012643#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012645#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012646#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012648#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012649#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012651#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012652#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012653 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012654#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012655#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012656 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012657#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012658#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012660#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012661
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012662 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012663#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012665#endif /* ST_RDONLY */
12666#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012668#endif /* ST_NOSUID */
12669
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012670 /* GNU extensions */
12671#ifdef ST_NODEV
12672 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12673#endif /* ST_NODEV */
12674#ifdef ST_NOEXEC
12675 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12676#endif /* ST_NOEXEC */
12677#ifdef ST_SYNCHRONOUS
12678 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12679#endif /* ST_SYNCHRONOUS */
12680#ifdef ST_MANDLOCK
12681 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12682#endif /* ST_MANDLOCK */
12683#ifdef ST_WRITE
12684 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12685#endif /* ST_WRITE */
12686#ifdef ST_APPEND
12687 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12688#endif /* ST_APPEND */
12689#ifdef ST_NOATIME
12690 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12691#endif /* ST_NOATIME */
12692#ifdef ST_NODIRATIME
12693 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12694#endif /* ST_NODIRATIME */
12695#ifdef ST_RELATIME
12696 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12697#endif /* ST_RELATIME */
12698
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012699 /* FreeBSD sendfile() constants */
12700#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012702#endif
12703#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012705#endif
12706#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012708#endif
12709
Ross Lagerwall7807c352011-03-17 20:20:30 +020012710 /* constants for posix_fadvise */
12711#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012713#endif
12714#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012715 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012716#endif
12717#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012718 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012719#endif
12720#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012721 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012722#endif
12723#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012724 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012725#endif
12726#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012727 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012728#endif
12729
12730 /* constants for waitid */
12731#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12733 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12734 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012735#endif
12736#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012738#endif
12739#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012741#endif
12742#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012744#endif
12745#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012747#endif
12748#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012750#endif
12751#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012753#endif
12754#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012755 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012756#endif
12757
12758 /* constants for lockf */
12759#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012761#endif
12762#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012764#endif
12765#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012767#endif
12768#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012770#endif
12771
Guido van Rossum246bc171999-02-01 23:54:31 +000012772#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12774 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12775 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12776 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12777 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012778#endif
12779
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012780#ifdef HAVE_SCHED_H
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012781#ifdef SCHED_OTHER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012783#endif
12784#ifdef SCHED_FIFO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012786#endif
12787#ifdef SCHED_RR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Petersondbaa5592016-07-30 23:21:50 -070012789#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012790#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012792#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012793#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012795#endif
12796#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012798#endif
12799#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012801#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012802#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012804#endif
12805#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012806 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012807#endif
12808#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012809 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012810#endif
12811#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012812 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012813#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012814#endif
12815
Benjamin Peterson9428d532011-09-14 11:45:52 -040012816#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012817 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12818 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12819 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012820#endif
12821
Victor Stinner8b905bd2011-10-25 13:34:04 +020012822#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012823 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012824#endif
12825#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012826 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012827#endif
12828#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012829 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012830#endif
12831#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012832 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012833#endif
12834#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012835 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012836#endif
12837#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012838 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012839#endif
12840#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012841 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012842#endif
12843
Victor Stinner8c62be82010-05-06 00:08:46 +000012844 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012845}
12846
12847
Martin v. Löwis1a214512008-06-11 05:26:20 +000012848static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012849 PyModuleDef_HEAD_INIT,
12850 MODNAME,
12851 posix__doc__,
12852 -1,
12853 posix_methods,
12854 NULL,
12855 NULL,
12856 NULL,
12857 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012858};
12859
12860
Larry Hastings9cf065c2012-06-22 16:30:09 -070012861static char *have_functions[] = {
12862
12863#ifdef HAVE_FACCESSAT
12864 "HAVE_FACCESSAT",
12865#endif
12866
12867#ifdef HAVE_FCHDIR
12868 "HAVE_FCHDIR",
12869#endif
12870
12871#ifdef HAVE_FCHMOD
12872 "HAVE_FCHMOD",
12873#endif
12874
12875#ifdef HAVE_FCHMODAT
12876 "HAVE_FCHMODAT",
12877#endif
12878
12879#ifdef HAVE_FCHOWN
12880 "HAVE_FCHOWN",
12881#endif
12882
Larry Hastings00964ed2013-08-12 13:49:30 -040012883#ifdef HAVE_FCHOWNAT
12884 "HAVE_FCHOWNAT",
12885#endif
12886
Larry Hastings9cf065c2012-06-22 16:30:09 -070012887#ifdef HAVE_FEXECVE
12888 "HAVE_FEXECVE",
12889#endif
12890
12891#ifdef HAVE_FDOPENDIR
12892 "HAVE_FDOPENDIR",
12893#endif
12894
Georg Brandl306336b2012-06-24 12:55:33 +020012895#ifdef HAVE_FPATHCONF
12896 "HAVE_FPATHCONF",
12897#endif
12898
Larry Hastings9cf065c2012-06-22 16:30:09 -070012899#ifdef HAVE_FSTATAT
12900 "HAVE_FSTATAT",
12901#endif
12902
12903#ifdef HAVE_FSTATVFS
12904 "HAVE_FSTATVFS",
12905#endif
12906
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012907#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012908 "HAVE_FTRUNCATE",
12909#endif
12910
Larry Hastings9cf065c2012-06-22 16:30:09 -070012911#ifdef HAVE_FUTIMENS
12912 "HAVE_FUTIMENS",
12913#endif
12914
12915#ifdef HAVE_FUTIMES
12916 "HAVE_FUTIMES",
12917#endif
12918
12919#ifdef HAVE_FUTIMESAT
12920 "HAVE_FUTIMESAT",
12921#endif
12922
12923#ifdef HAVE_LINKAT
12924 "HAVE_LINKAT",
12925#endif
12926
12927#ifdef HAVE_LCHFLAGS
12928 "HAVE_LCHFLAGS",
12929#endif
12930
12931#ifdef HAVE_LCHMOD
12932 "HAVE_LCHMOD",
12933#endif
12934
12935#ifdef HAVE_LCHOWN
12936 "HAVE_LCHOWN",
12937#endif
12938
12939#ifdef HAVE_LSTAT
12940 "HAVE_LSTAT",
12941#endif
12942
12943#ifdef HAVE_LUTIMES
12944 "HAVE_LUTIMES",
12945#endif
12946
12947#ifdef HAVE_MKDIRAT
12948 "HAVE_MKDIRAT",
12949#endif
12950
12951#ifdef HAVE_MKFIFOAT
12952 "HAVE_MKFIFOAT",
12953#endif
12954
12955#ifdef HAVE_MKNODAT
12956 "HAVE_MKNODAT",
12957#endif
12958
12959#ifdef HAVE_OPENAT
12960 "HAVE_OPENAT",
12961#endif
12962
12963#ifdef HAVE_READLINKAT
12964 "HAVE_READLINKAT",
12965#endif
12966
12967#ifdef HAVE_RENAMEAT
12968 "HAVE_RENAMEAT",
12969#endif
12970
12971#ifdef HAVE_SYMLINKAT
12972 "HAVE_SYMLINKAT",
12973#endif
12974
12975#ifdef HAVE_UNLINKAT
12976 "HAVE_UNLINKAT",
12977#endif
12978
12979#ifdef HAVE_UTIMENSAT
12980 "HAVE_UTIMENSAT",
12981#endif
12982
12983#ifdef MS_WINDOWS
12984 "MS_WINDOWS",
12985#endif
12986
12987 NULL
12988};
12989
12990
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012991PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012992INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012993{
Victor Stinner8c62be82010-05-06 00:08:46 +000012994 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012995 PyObject *list;
12996 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012997
Brian Curtin52173d42010-12-02 18:29:18 +000012998#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012999 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013000#endif
13001
Victor Stinner8c62be82010-05-06 00:08:46 +000013002 m = PyModule_Create(&posixmodule);
13003 if (m == NULL)
13004 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013005
Victor Stinner8c62be82010-05-06 00:08:46 +000013006 /* Initialize environ dictionary */
13007 v = convertenviron();
13008 Py_XINCREF(v);
13009 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13010 return NULL;
13011 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013012
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 if (all_ins(m))
13014 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013015
Victor Stinner8c62be82010-05-06 00:08:46 +000013016 if (setup_confname_tables(m))
13017 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013018
Victor Stinner8c62be82010-05-06 00:08:46 +000013019 Py_INCREF(PyExc_OSError);
13020 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013021
Guido van Rossumb3d39562000-01-31 18:41:26 +000013022#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013023 if (posix_putenv_garbage == NULL)
13024 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013025#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013026
Victor Stinner8c62be82010-05-06 00:08:46 +000013027 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013028#if defined(HAVE_WAITID) && !defined(__APPLE__)
13029 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013030 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13031 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013032#endif
13033
Christian Heimes25827622013-10-12 01:27:08 +020013034 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013035 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13036 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13037 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013038 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13039 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013040 structseq_new = StatResultType.tp_new;
13041 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013042
Christian Heimes25827622013-10-12 01:27:08 +020013043 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013044 if (PyStructSequence_InitType2(&StatVFSResultType,
13045 &statvfs_result_desc) < 0)
13046 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013047#ifdef NEED_TICKS_PER_SECOND
13048# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013049 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013050# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013051 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013052# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013053 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013054# endif
13055#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013056
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013057#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013058 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013059 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13060 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013061 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013062#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013063
13064 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013065 if (PyStructSequence_InitType2(&TerminalSizeType,
13066 &TerminalSize_desc) < 0)
13067 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013068
13069 /* initialize scandir types */
13070 if (PyType_Ready(&ScandirIteratorType) < 0)
13071 return NULL;
13072 if (PyType_Ready(&DirEntryType) < 0)
13073 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013074 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013075#if defined(HAVE_WAITID) && !defined(__APPLE__)
13076 Py_INCREF((PyObject*) &WaitidResultType);
13077 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13078#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013079 Py_INCREF((PyObject*) &StatResultType);
13080 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13081 Py_INCREF((PyObject*) &StatVFSResultType);
13082 PyModule_AddObject(m, "statvfs_result",
13083 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013084
13085#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013086 Py_INCREF(&SchedParamType);
13087 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013088#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013089
Larry Hastings605a62d2012-06-24 04:33:36 -070013090 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013091 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13092 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013093 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13094
13095 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013096 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13097 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013098 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13099
Thomas Wouters477c8d52006-05-27 19:21:47 +000013100#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013101 /*
13102 * Step 2 of weak-linking support on Mac OS X.
13103 *
13104 * The code below removes functions that are not available on the
13105 * currently active platform.
13106 *
13107 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013108 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013109 * OSX 10.4.
13110 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013111#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013112 if (fstatvfs == NULL) {
13113 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13114 return NULL;
13115 }
13116 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013117#endif /* HAVE_FSTATVFS */
13118
13119#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013120 if (statvfs == NULL) {
13121 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13122 return NULL;
13123 }
13124 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013125#endif /* HAVE_STATVFS */
13126
13127# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013128 if (lchown == NULL) {
13129 if (PyObject_DelAttrString(m, "lchown") == -1) {
13130 return NULL;
13131 }
13132 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013133#endif /* HAVE_LCHOWN */
13134
13135
13136#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013137
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013138 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013139 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13140
Larry Hastings6fe20b32012-04-19 15:07:49 -070013141 billion = PyLong_FromLong(1000000000);
13142 if (!billion)
13143 return NULL;
13144
Larry Hastings9cf065c2012-06-22 16:30:09 -070013145 /* suppress "function not used" warnings */
13146 {
13147 int ignored;
13148 fd_specified("", -1);
13149 follow_symlinks_specified("", 1);
13150 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13151 dir_fd_converter(Py_None, &ignored);
13152 dir_fd_unavailable(Py_None, &ignored);
13153 }
13154
13155 /*
13156 * provide list of locally available functions
13157 * so os.py can populate support_* lists
13158 */
13159 list = PyList_New(0);
13160 if (!list)
13161 return NULL;
13162 for (trace = have_functions; *trace; trace++) {
13163 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13164 if (!unicode)
13165 return NULL;
13166 if (PyList_Append(list, unicode))
13167 return NULL;
13168 Py_DECREF(unicode);
13169 }
13170 PyModule_AddObject(m, "_have_functions", list);
13171
13172 initialized = 1;
13173
Victor Stinner8c62be82010-05-06 00:08:46 +000013174 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013175}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013176
13177#ifdef __cplusplus
13178}
13179#endif