blob: 65b20be4686e666794ec486e1d34bd758e43850f [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
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000035#ifdef __cplusplus
36extern "C" {
37#endif
38
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000039PyDoc_STRVAR(posix__doc__,
Guido van Rossumec4f4ac1997-06-02 22:20:51 +000040"This module provides access to operating system functionality that is\n\
41standardized by the C Standard and the POSIX standard (a thinly\n\
42disguised Unix interface). Refer to the library manual and\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000043corresponding Unix manual entries for more information on calls.");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000044
Martin v. Löwis0073f2e2002-11-21 23:52:35 +000045
Ross Lagerwall4d076da2011-03-18 06:56:53 +020046#ifdef HAVE_SYS_UIO_H
47#include <sys/uio.h>
48#endif
49
Thomas Wouters0e3f5912006-08-11 14:57:12 +000050#ifdef HAVE_SYS_TYPES_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000051#include <sys/types.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000052#endif /* HAVE_SYS_TYPES_H */
53
54#ifdef HAVE_SYS_STAT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +000055#include <sys/stat.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000056#endif /* HAVE_SYS_STAT_H */
Guido van Rossuma6535fd2001-10-18 19:44:10 +000057
Guido van Rossum36bc6801995-06-14 22:54:23 +000058#ifdef HAVE_SYS_WAIT_H
Victor Stinner8c62be82010-05-06 00:08:46 +000059#include <sys/wait.h> /* For WNOHANG */
Guido van Rossum36bc6801995-06-14 22:54:23 +000060#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +000061
Thomas Wouters0e3f5912006-08-11 14:57:12 +000062#ifdef HAVE_SIGNAL_H
Guido van Rossuma376cc51996-12-05 23:43:35 +000063#include <signal.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +000064#endif
Guido van Rossuma376cc51996-12-05 23:43:35 +000065
Guido van Rossumb6775db1994-08-01 11:34:53 +000066#ifdef HAVE_FCNTL_H
67#include <fcntl.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000068#endif /* HAVE_FCNTL_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +000069
Guido van Rossuma6535fd2001-10-18 19:44:10 +000070#ifdef HAVE_GRP_H
71#include <grp.h>
72#endif
73
Barry Warsaw5676bd12003-01-07 20:57:09 +000074#ifdef HAVE_SYSEXITS_H
75#include <sysexits.h>
76#endif /* HAVE_SYSEXITS_H */
77
Anthony Baxter8a560de2004-10-13 15:30:56 +000078#ifdef HAVE_SYS_LOADAVG_H
79#include <sys/loadavg.h>
80#endif
81
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000082#ifdef HAVE_LANGINFO_H
83#include <langinfo.h>
84#endif
85
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000086#ifdef HAVE_SYS_SENDFILE_H
87#include <sys/sendfile.h>
88#endif
89
Benjamin Peterson94b580d2011-08-02 17:30:04 -050090#ifdef HAVE_SCHED_H
91#include <sched.h>
92#endif
93
Benjamin Peterson2dbda072012-03-16 10:12:55 -050094#if !defined(CPU_ALLOC) && defined(HAVE_SCHED_SETAFFINITY)
Benjamin Peterson7b51b8d2012-03-14 22:28:25 -050095#undef HAVE_SCHED_SETAFFINITY
96#endif
97
doko@ubuntu.com4a173bc2014-04-17 19:47:16 +020098#if defined(HAVE_SYS_XATTR_H) && defined(__GLIBC__) && !defined(__FreeBSD_kernel__) && !defined(__GNU__)
Benjamin Peterson9428d532011-09-14 11:45:52 -040099#define USE_XATTRS
100#endif
101
102#ifdef USE_XATTRS
Benjamin Petersonb77fe172011-09-13 17:20:47 -0400103#include <sys/xattr.h>
Benjamin Peterson799bd802011-08-31 22:15:17 -0400104#endif
105
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000106#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
107#ifdef HAVE_SYS_SOCKET_H
108#include <sys/socket.h>
109#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000110#endif
111
Victor Stinner8b905bd2011-10-25 13:34:04 +0200112#ifdef HAVE_DLFCN_H
113#include <dlfcn.h>
114#endif
115
Charles-Francois Natali44feda32013-05-20 14:40:46 +0200116#ifdef __hpux
117#include <sys/mpctl.h>
118#endif
119
120#if defined(__DragonFly__) || \
121 defined(__OpenBSD__) || \
122 defined(__FreeBSD__) || \
123 defined(__NetBSD__) || \
124 defined(__APPLE__)
125#include <sys/sysctl.h>
126#endif
127
Antoine Pitroubcf2b592012-02-08 23:28:36 +0100128#if defined(MS_WINDOWS)
129# define TERMSIZE_USE_CONIO
130#elif defined(HAVE_SYS_IOCTL_H)
131# include <sys/ioctl.h>
132# if defined(HAVE_TERMIOS_H)
133# include <termios.h>
134# endif
135# if defined(TIOCGWINSZ)
136# define TERMSIZE_USE_IOCTL
137# endif
138#endif /* MS_WINDOWS */
139
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000140/* Various compilers have only certain posix functions */
Martin v. Löwis4f1cd8b2001-07-26 13:41:06 +0000141/* XXX Gosh I wish these were all moved into pyconfig.h */
Victor Stinner8c62be82010-05-06 00:08:46 +0000142#if defined(__WATCOMC__) && !defined(__QNX__) /* Watcom compiler */
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000143#define HAVE_OPENDIR 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000144#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000145#include <process.h>
146#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000147#ifdef _MSC_VER /* Microsoft compiler */
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +0000148#define HAVE_GETPPID 1
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +0000149#define HAVE_GETLOGIN 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000150#define HAVE_SPAWNV 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000151#define HAVE_EXECV 1
152#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000153#define HAVE_SYSTEM 1
154#define HAVE_CWAIT 1
155#define HAVE_FSYNC 1
Tim Peters11b23062003-04-23 02:39:17 +0000156#define fsync _commit
Andrew MacIntyre6c73af22002-03-03 03:07:07 +0000157#else
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000158/* Unix functions that the configure script doesn't check for */
159#define HAVE_EXECV 1
160#define HAVE_FORK 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000161#if defined(__USLC__) && defined(__SCO_VERSION__) /* SCO UDK Compiler */
Guido van Rossum2242f2f2001-04-11 20:58:20 +0000162#define HAVE_FORK1 1
163#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000164#define HAVE_GETEGID 1
165#define HAVE_GETEUID 1
166#define HAVE_GETGID 1
167#define HAVE_GETPPID 1
168#define HAVE_GETUID 1
169#define HAVE_KILL 1
170#define HAVE_OPENDIR 1
171#define HAVE_PIPE 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000172#define HAVE_SYSTEM 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000173#define HAVE_WAIT 1
Victor Stinner8c62be82010-05-06 00:08:46 +0000174#define HAVE_TTYNAME 1
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000175#endif /* _MSC_VER */
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000176#endif /* ! __WATCOMC__ || __QNX__ */
Guido van Rossumad0ee831995-03-01 10:34:45 +0000177
Victor Stinnera2f7c002012-02-08 03:36:25 +0100178
Larry Hastings61272b72014-01-07 12:41:53 -0800179/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +1000180# one of the few times we lie about this name!
Larry Hastings44e2eaa2013-11-23 15:37:55 -0800181module os
Larry Hastings61272b72014-01-07 12:41:53 -0800182[clinic start generated code]*/
Larry Hastings2f936352014-08-05 14:04:04 +1000183/*[clinic end generated code: output=da39a3ee5e6b4b0d input=94a0f0f978acae17]*/
Victor Stinnera2f7c002012-02-08 03:36:25 +0100184
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000185#ifndef _MSC_VER
Guido van Rossum36bc6801995-06-14 22:54:23 +0000186
Martin v. Löwis8eb92a02002-09-19 08:03:21 +0000187#if defined(__sgi)&&_COMPILER_VERSION>=700
188/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
189 (default) */
190extern char *ctermid_r(char *);
191#endif
192
Thomas Wouters1e0c2f42000-07-24 16:06:23 +0000193#ifndef HAVE_UNISTD_H
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000194#if defined(PYCC_VACPP)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000195extern int mkdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000196#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000197#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000198extern int mkdir(const char *);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000199#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000200extern int mkdir(const char *, mode_t);
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000201#endif
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000202#endif
203#if defined(__IBMC__) || defined(__IBMCPP__)
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000204extern int chdir(char *);
205extern int rmdir(char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000206#else
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000207extern int chdir(const char *);
208extern int rmdir(const char *);
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000209#endif
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000210extern int chmod(const char *, mode_t);
Christian Heimes4e30a842007-11-30 22:12:06 +0000211/*#ifdef HAVE_FCHMOD
212extern int fchmod(int, mode_t);
213#endif*/
214/*#ifdef HAVE_LCHMOD
215extern int lchmod(const char *, mode_t);
216#endif*/
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000217extern int chown(const char *, uid_t, gid_t);
218extern char *getcwd(char *, int);
219extern char *strerror(int);
220extern int link(const char *, const char *);
221extern int rename(const char *, const char *);
222extern int stat(const char *, struct stat *);
223extern int unlink(const char *);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000224#ifdef HAVE_SYMLINK
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000225extern int symlink(const char *, const char *);
Guido van Rossuma38a5031995-02-17 15:11:36 +0000226#endif /* HAVE_SYMLINK */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000227#ifdef HAVE_LSTAT
Fredrik Lundhff7df9d2000-07-08 22:48:53 +0000228extern int lstat(const char *, struct stat *);
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000229#endif /* HAVE_LSTAT */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000230#endif /* !HAVE_UNISTD_H */
Guido van Rossum36bc6801995-06-14 22:54:23 +0000231
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000232#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000233
Guido van Rossumb6775db1994-08-01 11:34:53 +0000234#ifdef HAVE_UTIME_H
235#include <utime.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000236#endif /* HAVE_UTIME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000237
Guido van Rossum14ed0b21994-09-29 09:50:09 +0000238#ifdef HAVE_SYS_UTIME_H
239#include <sys/utime.h>
240#define HAVE_UTIME_H /* pretend we do for the rest of this file */
241#endif /* HAVE_SYS_UTIME_H */
242
Guido van Rossumb6775db1994-08-01 11:34:53 +0000243#ifdef HAVE_SYS_TIMES_H
244#include <sys/times.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000245#endif /* HAVE_SYS_TIMES_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000246
247#ifdef HAVE_SYS_PARAM_H
248#include <sys/param.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000249#endif /* HAVE_SYS_PARAM_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000250
251#ifdef HAVE_SYS_UTSNAME_H
252#include <sys/utsname.h>
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +0000253#endif /* HAVE_SYS_UTSNAME_H */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000254
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000255#ifdef HAVE_DIRENT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000256#include <dirent.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000257#define NAMLEN(dirent) strlen((dirent)->d_name)
258#else
Guido van Rossumc5a0f531997-12-02 20:36:02 +0000259#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000260#include <direct.h>
261#define NAMLEN(dirent) strlen((dirent)->d_name)
262#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000263#define dirent direct
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000264#define NAMLEN(dirent) (dirent)->d_namlen
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000265#endif
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000266#ifdef HAVE_SYS_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000267#include <sys/ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000268#endif
269#ifdef HAVE_SYS_DIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000270#include <sys/dir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000271#endif
272#ifdef HAVE_NDIR_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000273#include <ndir.h>
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000274#endif
275#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000276
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000277#ifdef _MSC_VER
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000278#ifdef HAVE_DIRECT_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000279#include <direct.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000280#endif
281#ifdef HAVE_IO_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000282#include <io.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000283#endif
284#ifdef HAVE_PROCESS_H
Guido van Rossumb6775db1994-08-01 11:34:53 +0000285#include <process.h>
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000286#endif
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000287#ifndef VOLUME_NAME_DOS
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000288#define VOLUME_NAME_DOS 0x0
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000289#endif
290#ifndef VOLUME_NAME_NT
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000291#define VOLUME_NAME_NT 0x2
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000292#endif
293#ifndef IO_REPARSE_TAG_SYMLINK
Amaury Forgeot d'Arc844807e2010-08-16 22:16:51 +0000294#define IO_REPARSE_TAG_SYMLINK (0xA000000CL)
Raymond Hettinger0291c9f2010-08-01 21:10:35 +0000295#endif
Tim Golden0321cf22014-05-05 19:46:17 +0100296#ifndef IO_REPARSE_TAG_MOUNT_POINT
297#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
298#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000299#include "osdefs.h"
Kristján Valur Jónssonf64e6512009-04-13 10:16:14 +0000300#include <malloc.h>
Guido van Rossumb6775db1994-08-01 11:34:53 +0000301#include <windows.h>
Victor Stinner8c62be82010-05-06 00:08:46 +0000302#include <shellapi.h> /* for ShellExecute() */
Brian Curtine8e4b3b2010-09-23 20:04:14 +0000303#include <lmcons.h> /* for UNLEN */
Brian Curtin52173d42010-12-02 18:29:18 +0000304#ifdef SE_CREATE_SYMBOLIC_LINK_NAME /* Available starting with Vista */
305#define HAVE_SYMLINK
Brian Curtin3b4499c2010-12-28 14:31:47 +0000306static int win32_can_symlink = 0;
Brian Curtin52173d42010-12-02 18:29:18 +0000307#endif
Guido van Rossuma4916fa1996-05-23 22:58:55 +0000308#endif /* _MSC_VER */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000309
Tim Petersbc2e10e2002-03-03 23:17:02 +0000310#ifndef MAXPATHLEN
Thomas Wouters477c8d52006-05-27 19:21:47 +0000311#if defined(PATH_MAX) && PATH_MAX > 1024
312#define MAXPATHLEN PATH_MAX
313#else
Tim Petersbc2e10e2002-03-03 23:17:02 +0000314#define MAXPATHLEN 1024
Thomas Wouters477c8d52006-05-27 19:21:47 +0000315#endif
Tim Petersbc2e10e2002-03-03 23:17:02 +0000316#endif /* MAXPATHLEN */
317
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000318#ifdef UNION_WAIT
319/* Emulate some macros on systems that have a union instead of macros */
320
321#ifndef WIFEXITED
322#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
323#endif
324
325#ifndef WEXITSTATUS
326#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
327#endif
328
329#ifndef WTERMSIG
330#define WTERMSIG(u_wait) ((u_wait).w_termsig)
331#endif
332
Thomas Wouters49fd7fa2006-04-21 10:40:58 +0000333#define WAIT_TYPE union wait
334#define WAIT_STATUS_INT(s) (s.w_status)
335
336#else /* !UNION_WAIT */
337#define WAIT_TYPE int
338#define WAIT_STATUS_INT(s) (s)
Guido van Rossum54ecc3d1999-01-27 17:53:11 +0000339#endif /* UNION_WAIT */
340
Greg Wardb48bc172000-03-01 21:51:56 +0000341/* Don't use the "_r" form if we don't need it (also, won't have a
342 prototype for it, at least on Solaris -- maybe others as well?). */
343#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
344#define USE_CTERMID_R
345#endif
346
Fred Drake699f3522000-06-29 21:12:41 +0000347/* choose the appropriate stat and fstat functions and return structs */
Guido van Rossum64529cd2000-06-30 22:45:12 +0000348#undef STAT
Antoine Pitroue47e0932011-01-19 15:21:35 +0000349#undef FSTAT
350#undef STRUCT_STAT
Victor Stinner14b9b112013-06-25 00:37:25 +0200351#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +0000352# define STAT win32_stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700353# define LSTAT win32_lstat
Victor Stinnere134a7f2015-03-30 10:09:31 +0200354# define FSTAT _Py_fstat_noraise
Steve Dowerf2f373f2015-02-21 08:44:05 -0800355# define STRUCT_STAT struct _Py_stat_struct
Fred Drake699f3522000-06-29 21:12:41 +0000356#else
Victor Stinner8c62be82010-05-06 00:08:46 +0000357# define STAT stat
Larry Hastings9cf065c2012-06-22 16:30:09 -0700358# define LSTAT lstat
Victor Stinner8c62be82010-05-06 00:08:46 +0000359# define FSTAT fstat
360# define STRUCT_STAT struct stat
Fred Drake699f3522000-06-29 21:12:41 +0000361#endif
362
Tim Peters11b23062003-04-23 02:39:17 +0000363#if defined(MAJOR_IN_MKDEV)
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000364#include <sys/mkdev.h>
365#else
366#if defined(MAJOR_IN_SYSMACROS)
367#include <sys/sysmacros.h>
368#endif
Neal Norwitz3d949422002-04-20 13:46:43 +0000369#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
370#include <sys/mkdev.h>
371#endif
Martin v. Löwisdbe3f762002-10-10 14:27:30 +0000372#endif
Fred Drake699f3522000-06-29 21:12:41 +0000373
Victor Stinner6edddfa2013-11-24 19:22:57 +0100374#define DWORD_MAX 4294967295U
375
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200376#ifdef MS_WINDOWS
Victor Stinner6036e442015-03-08 01:58:04 +0100377#define INITFUNC PyInit_nt
378#define MODNAME "nt"
379#else
380#define INITFUNC PyInit_posix
381#define MODNAME "posix"
382#endif
383
384#ifdef MS_WINDOWS
Serhiy Storchaka06a13f82015-02-22 21:34:54 +0200385/* defined in fileutils.c */
386PyAPI_FUNC(void) _Py_time_t_to_FILE_TIME(time_t, int, FILETIME *);
387PyAPI_FUNC(void) _Py_attribute_data_to_stat(BY_HANDLE_FILE_INFORMATION *,
388 ULONG, struct _Py_stat_struct *);
389#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -0700390
391#ifdef MS_WINDOWS
392static int
393win32_warn_bytes_api()
394{
395 return PyErr_WarnEx(PyExc_DeprecationWarning,
396 "The Windows bytes API has been deprecated, "
397 "use Unicode filenames instead",
398 1);
399}
400#endif
401
402
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200403#ifndef MS_WINDOWS
404PyObject *
405_PyLong_FromUid(uid_t uid)
406{
407 if (uid == (uid_t)-1)
408 return PyLong_FromLong(-1);
409 return PyLong_FromUnsignedLong(uid);
410}
411
412PyObject *
413_PyLong_FromGid(gid_t gid)
414{
415 if (gid == (gid_t)-1)
416 return PyLong_FromLong(-1);
417 return PyLong_FromUnsignedLong(gid);
418}
419
420int
421_Py_Uid_Converter(PyObject *obj, void *p)
422{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700423 uid_t uid;
424 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200425 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200426 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700427 unsigned long uresult;
428
429 index = PyNumber_Index(obj);
430 if (index == NULL) {
431 PyErr_Format(PyExc_TypeError,
432 "uid should be integer, not %.200s",
433 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200434 return 0;
435 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700436
437 /*
438 * Handling uid_t is complicated for two reasons:
439 * * Although uid_t is (always?) unsigned, it still
440 * accepts -1.
441 * * We don't know its size in advance--it may be
442 * bigger than an int, or it may be smaller than
443 * a long.
444 *
445 * So a bit of defensive programming is in order.
446 * Start with interpreting the value passed
447 * in as a signed long and see if it works.
448 */
449
450 result = PyLong_AsLongAndOverflow(index, &overflow);
451
452 if (!overflow) {
453 uid = (uid_t)result;
454
455 if (result == -1) {
456 if (PyErr_Occurred())
457 goto fail;
458 /* It's a legitimate -1, we're done. */
459 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200460 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700461
462 /* Any other negative number is disallowed. */
463 if (result < 0)
464 goto underflow;
465
466 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200467 if (sizeof(uid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700468 (long)uid != result)
469 goto underflow;
470 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200471 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700472
473 if (overflow < 0)
474 goto underflow;
475
476 /*
477 * Okay, the value overflowed a signed long. If it
478 * fits in an *unsigned* long, it may still be okay,
479 * as uid_t may be unsigned long on this platform.
480 */
481 uresult = PyLong_AsUnsignedLong(index);
482 if (PyErr_Occurred()) {
483 if (PyErr_ExceptionMatches(PyExc_OverflowError))
484 goto overflow;
485 goto fail;
486 }
487
488 uid = (uid_t)uresult;
489
490 /*
491 * If uid == (uid_t)-1, the user actually passed in ULONG_MAX,
492 * but this value would get interpreted as (uid_t)-1 by chown
493 * and its siblings. That's not what the user meant! So we
494 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100495 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700496 */
497 if (uid == (uid_t)-1)
498 goto overflow;
499
500 /* Ensure the value wasn't truncated. */
501 if (sizeof(uid_t) < sizeof(long) &&
502 (unsigned long)uid != uresult)
503 goto overflow;
504 /* fallthrough */
505
506success:
507 Py_DECREF(index);
508 *(uid_t *)p = uid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200509 return 1;
510
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700511underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200512 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700513 "uid is less than minimum");
514 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200515
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700516overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200517 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700518 "uid is greater than maximum");
519 /* fallthrough */
520
521fail:
522 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200523 return 0;
524}
525
526int
527_Py_Gid_Converter(PyObject *obj, void *p)
528{
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700529 gid_t gid;
530 PyObject *index;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200531 int overflow;
Serhiy Storchakab4621892013-02-10 23:28:02 +0200532 long result;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700533 unsigned long uresult;
534
535 index = PyNumber_Index(obj);
536 if (index == NULL) {
537 PyErr_Format(PyExc_TypeError,
538 "gid should be integer, not %.200s",
539 Py_TYPE(obj)->tp_name);
Serhiy Storchakab4621892013-02-10 23:28:02 +0200540 return 0;
541 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700542
543 /*
544 * Handling gid_t is complicated for two reasons:
545 * * Although gid_t is (always?) unsigned, it still
546 * accepts -1.
547 * * We don't know its size in advance--it may be
548 * bigger than an int, or it may be smaller than
549 * a long.
550 *
551 * So a bit of defensive programming is in order.
552 * Start with interpreting the value passed
553 * in as a signed long and see if it works.
554 */
555
556 result = PyLong_AsLongAndOverflow(index, &overflow);
557
558 if (!overflow) {
559 gid = (gid_t)result;
560
561 if (result == -1) {
562 if (PyErr_Occurred())
563 goto fail;
564 /* It's a legitimate -1, we're done. */
565 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200566 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700567
568 /* Any other negative number is disallowed. */
569 if (result < 0) {
570 goto underflow;
571 }
572
573 /* Ensure the value wasn't truncated. */
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200574 if (sizeof(gid_t) < sizeof(long) &&
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700575 (long)gid != result)
576 goto underflow;
577 goto success;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200578 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700579
580 if (overflow < 0)
581 goto underflow;
582
583 /*
584 * Okay, the value overflowed a signed long. If it
585 * fits in an *unsigned* long, it may still be okay,
586 * as gid_t may be unsigned long on this platform.
587 */
588 uresult = PyLong_AsUnsignedLong(index);
589 if (PyErr_Occurred()) {
590 if (PyErr_ExceptionMatches(PyExc_OverflowError))
591 goto overflow;
592 goto fail;
593 }
594
595 gid = (gid_t)uresult;
596
597 /*
598 * If gid == (gid_t)-1, the user actually passed in ULONG_MAX,
599 * but this value would get interpreted as (gid_t)-1 by chown
600 * and its siblings. That's not what the user meant! So we
601 * throw an overflow exception instead. (We already
Tim Golden23005082013-10-25 11:22:37 +0100602 * handled a real -1 with PyLong_AsLongAndOverflow() above.)
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700603 */
604 if (gid == (gid_t)-1)
605 goto overflow;
606
607 /* Ensure the value wasn't truncated. */
608 if (sizeof(gid_t) < sizeof(long) &&
609 (unsigned long)gid != uresult)
610 goto overflow;
611 /* fallthrough */
612
613success:
614 Py_DECREF(index);
615 *(gid_t *)p = gid;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200616 return 1;
617
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700618underflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200619 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700620 "gid is less than minimum");
621 goto fail;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200622
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700623overflow:
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200624 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700625 "gid is greater than maximum");
626 /* fallthrough */
627
628fail:
629 Py_DECREF(index);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +0200630 return 0;
631}
632#endif /* MS_WINDOWS */
633
634
Gregory P. Smith702dada2015-01-28 16:07:52 -0800635#ifdef HAVE_LONG_LONG
636# define _PyLong_FromDev PyLong_FromLongLong
637#else
638# define _PyLong_FromDev PyLong_FromLong
639#endif
640
641
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200642#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
643static int
644_Py_Dev_Converter(PyObject *obj, void *p)
645{
646#ifdef HAVE_LONG_LONG
647 *((dev_t *)p) = PyLong_AsUnsignedLongLong(obj);
648#else
649 *((dev_t *)p) = PyLong_AsUnsignedLong(obj);
650#endif
651 if (PyErr_Occurred())
652 return 0;
653 return 1;
654}
Gregory P. Smith702dada2015-01-28 16:07:52 -0800655#endif /* HAVE_MKNOD && HAVE_MAKEDEV */
Serhiy Storchakab2653b32015-01-18 11:12:11 +0200656
657
Larry Hastings9cf065c2012-06-22 16:30:09 -0700658#ifdef AT_FDCWD
Trent Nelson9a461052012-09-18 21:50:06 -0400659/*
660 * Why the (int) cast? Solaris 10 defines AT_FDCWD as 0xffd19553 (-3041965);
661 * without the int cast, the value gets interpreted as uint (4291925331),
662 * which doesn't play nicely with all the initializer lines in this file that
663 * look like this:
664 * int dir_fd = DEFAULT_DIR_FD;
665 */
666#define DEFAULT_DIR_FD (int)AT_FDCWD
Larry Hastings9cf065c2012-06-22 16:30:09 -0700667#else
668#define DEFAULT_DIR_FD (-100)
669#endif
670
671static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200672_fd_converter(PyObject *o, int *p, const char *allowed)
673{
674 int overflow;
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700675 long long_value;
676
677 PyObject *index = PyNumber_Index(o);
678 if (index == NULL) {
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200679 PyErr_Format(PyExc_TypeError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700680 "argument should be %s, not %.200s",
681 allowed, Py_TYPE(o)->tp_name);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700682 return 0;
683 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700684
685 long_value = PyLong_AsLongAndOverflow(index, &overflow);
686 Py_DECREF(index);
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200687 if (overflow > 0 || long_value > INT_MAX) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700688 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700689 "fd is greater than maximum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700690 return 0;
691 }
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200692 if (overflow < 0 || long_value < INT_MIN) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700693 PyErr_SetString(PyExc_OverflowError,
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700694 "fd is less than minimum");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700695 return 0;
696 }
Larry Hastingsa27b83a2013-08-08 00:19:50 -0700697
Larry Hastings9cf065c2012-06-22 16:30:09 -0700698 *p = (int)long_value;
699 return 1;
700}
701
702static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200703dir_fd_converter(PyObject *o, void *p)
704{
705 if (o == Py_None) {
706 *(int *)p = DEFAULT_DIR_FD;
707 return 1;
708 }
709 return _fd_converter(o, (int *)p, "integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700710}
711
712
Larry Hastings9cf065c2012-06-22 16:30:09 -0700713/*
714 * A PyArg_ParseTuple "converter" function
715 * that handles filesystem paths in the manner
716 * preferred by the os module.
717 *
718 * path_converter accepts (Unicode) strings and their
719 * subclasses, and bytes and their subclasses. What
720 * it does with the argument depends on the platform:
721 *
722 * * On Windows, if we get a (Unicode) string we
723 * extract the wchar_t * and return it; if we get
724 * bytes we extract the char * and return that.
725 *
726 * * On all other platforms, strings are encoded
727 * to bytes using PyUnicode_FSConverter, then we
728 * extract the char * from the bytes object and
729 * return that.
730 *
731 * path_converter also optionally accepts signed
732 * integers (representing open file descriptors) instead
733 * of path strings.
734 *
735 * Input fields:
736 * path.nullable
737 * If nonzero, the path is permitted to be None.
738 * path.allow_fd
739 * If nonzero, the path is permitted to be a file handle
740 * (a signed int) instead of a string.
741 * path.function_name
742 * If non-NULL, path_converter will use that as the name
743 * of the function in error messages.
Larry Hastings31826802013-10-19 00:09:25 -0700744 * (If path.function_name is NULL it omits the function name.)
Larry Hastings9cf065c2012-06-22 16:30:09 -0700745 * path.argument_name
746 * If non-NULL, path_converter will use that as the name
747 * of the parameter in error messages.
748 * (If path.argument_name is NULL it uses "path".)
749 *
750 * Output fields:
751 * path.wide
752 * Points to the path if it was expressed as Unicode
753 * and was not encoded. (Only used on Windows.)
754 * path.narrow
755 * Points to the path if it was expressed as bytes,
756 * or it was Unicode and was encoded to bytes.
757 * path.fd
758 * Contains a file descriptor if path.accept_fd was true
759 * and the caller provided a signed integer instead of any
760 * sort of string.
761 *
762 * WARNING: if your "path" parameter is optional, and is
763 * unspecified, path_converter will never get called.
764 * So if you set allow_fd, you *MUST* initialize path.fd = -1
765 * yourself!
766 * path.length
767 * The length of the path in characters, if specified as
768 * a string.
769 * path.object
770 * The original object passed in.
771 * path.cleanup
772 * For internal use only. May point to a temporary object.
773 * (Pay no attention to the man behind the curtain.)
774 *
775 * At most one of path.wide or path.narrow will be non-NULL.
776 * If path was None and path.nullable was set,
777 * or if path was an integer and path.allow_fd was set,
778 * both path.wide and path.narrow will be NULL
779 * and path.length will be 0.
Georg Brandlf7875592012-06-24 13:58:31 +0200780 *
Larry Hastings9cf065c2012-06-22 16:30:09 -0700781 * path_converter takes care to not write to the path_t
782 * unless it's successful. However it must reset the
783 * "cleanup" field each time it's called.
784 *
785 * Use as follows:
786 * path_t path;
787 * memset(&path, 0, sizeof(path));
788 * PyArg_ParseTuple(args, "O&", path_converter, &path);
789 * // ... use values from path ...
790 * path_cleanup(&path);
791 *
792 * (Note that if PyArg_Parse fails you don't need to call
793 * path_cleanup(). However it is safe to do so.)
794 */
795typedef struct {
Victor Stinner292c8352012-10-30 02:17:38 +0100796 const char *function_name;
797 const char *argument_name;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700798 int nullable;
799 int allow_fd;
800 wchar_t *wide;
801 char *narrow;
802 int fd;
803 Py_ssize_t length;
804 PyObject *object;
805 PyObject *cleanup;
806} path_t;
807
Larry Hastings2f936352014-08-05 14:04:04 +1000808#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
809 {function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
Larry Hastings31826802013-10-19 00:09:25 -0700810
Larry Hastings9cf065c2012-06-22 16:30:09 -0700811static void
812path_cleanup(path_t *path) {
813 if (path->cleanup) {
Serhiy Storchaka505ff752014-02-09 13:33:53 +0200814 Py_CLEAR(path->cleanup);
Larry Hastings9cf065c2012-06-22 16:30:09 -0700815 }
816}
817
818static int
819path_converter(PyObject *o, void *p) {
820 path_t *path = (path_t *)p;
821 PyObject *unicode, *bytes;
822 Py_ssize_t length;
823 char *narrow;
824
825#define FORMAT_EXCEPTION(exc, fmt) \
826 PyErr_Format(exc, "%s%s" fmt, \
827 path->function_name ? path->function_name : "", \
828 path->function_name ? ": " : "", \
829 path->argument_name ? path->argument_name : "path")
830
831 /* Py_CLEANUP_SUPPORTED support */
832 if (o == NULL) {
833 path_cleanup(path);
834 return 1;
835 }
836
837 /* ensure it's always safe to call path_cleanup() */
838 path->cleanup = NULL;
839
840 if (o == Py_None) {
841 if (!path->nullable) {
842 FORMAT_EXCEPTION(PyExc_TypeError,
843 "can't specify None for %s argument");
844 return 0;
845 }
846 path->wide = NULL;
847 path->narrow = NULL;
848 path->length = 0;
849 path->object = o;
850 path->fd = -1;
851 return 1;
852 }
853
854 unicode = PyUnicode_FromObject(o);
855 if (unicode) {
856#ifdef MS_WINDOWS
857 wchar_t *wide;
Victor Stinner59799a82013-11-13 14:17:30 +0100858
859 wide = PyUnicode_AsUnicodeAndSize(unicode, &length);
860 if (!wide) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700861 Py_DECREF(unicode);
862 return 0;
863 }
Victor Stinner59799a82013-11-13 14:17:30 +0100864 if (length > 32767) {
865 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700866 Py_DECREF(unicode);
867 return 0;
868 }
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300869 if (wcslen(wide) != length) {
Serhiy Storchaka7e9d1d12015-04-20 10:12:28 +0300870 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character");
Serhiy Storchaka2b0d2002015-04-20 09:53:58 +0300871 Py_DECREF(unicode);
872 return 0;
873 }
Larry Hastings9cf065c2012-06-22 16:30:09 -0700874
875 path->wide = wide;
876 path->narrow = NULL;
877 path->length = length;
878 path->object = o;
879 path->fd = -1;
880 path->cleanup = unicode;
881 return Py_CLEANUP_SUPPORTED;
882#else
883 int converted = PyUnicode_FSConverter(unicode, &bytes);
884 Py_DECREF(unicode);
885 if (!converted)
886 bytes = NULL;
887#endif
888 }
889 else {
890 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200891 if (PyObject_CheckBuffer(o))
892 bytes = PyBytes_FromObject(o);
893 else
894 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700895 if (!bytes) {
896 PyErr_Clear();
897 if (path->allow_fd) {
898 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200899 int result = _fd_converter(o, &fd,
900 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700901 if (result) {
902 path->wide = NULL;
903 path->narrow = NULL;
904 path->length = 0;
905 path->object = o;
906 path->fd = fd;
907 return result;
908 }
909 }
910 }
911 }
912
913 if (!bytes) {
914 if (!PyErr_Occurred())
915 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
916 return 0;
917 }
918
919#ifdef MS_WINDOWS
920 if (win32_warn_bytes_api()) {
921 Py_DECREF(bytes);
922 return 0;
923 }
924#endif
925
926 length = PyBytes_GET_SIZE(bytes);
927#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100928 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700929 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
930 Py_DECREF(bytes);
931 return 0;
932 }
933#endif
934
935 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200936 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300937 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700938 Py_DECREF(bytes);
939 return 0;
940 }
941
942 path->wide = NULL;
943 path->narrow = narrow;
944 path->length = length;
945 path->object = o;
946 path->fd = -1;
947 path->cleanup = bytes;
948 return Py_CLEANUP_SUPPORTED;
949}
950
951static void
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200952argument_unavailable_error(const char *function_name, const char *argument_name)
953{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700954 PyErr_Format(PyExc_NotImplementedError,
955 "%s%s%s unavailable on this platform",
956 (function_name != NULL) ? function_name : "",
957 (function_name != NULL) ? ": ": "",
958 argument_name);
959}
960
961static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200962dir_fd_unavailable(PyObject *o, void *p)
963{
964 int dir_fd;
965 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700966 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200967 if (dir_fd != DEFAULT_DIR_FD) {
968 argument_unavailable_error(NULL, "dir_fd");
969 return 0;
970 }
971 *(int *)p = dir_fd;
972 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700973}
974
975static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200976fd_specified(const char *function_name, int fd)
977{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700978 if (fd == -1)
979 return 0;
980
981 argument_unavailable_error(function_name, "fd");
982 return 1;
983}
984
985static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200986follow_symlinks_specified(const char *function_name, int follow_symlinks)
987{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700988 if (follow_symlinks)
989 return 0;
990
991 argument_unavailable_error(function_name, "follow_symlinks");
992 return 1;
993}
994
995static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +0200996path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
997{
Larry Hastings9cf065c2012-06-22 16:30:09 -0700998 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
999 PyErr_Format(PyExc_ValueError,
1000 "%s: can't specify dir_fd without matching path",
1001 function_name);
1002 return 1;
1003 }
1004 return 0;
1005}
1006
1007static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001008dir_fd_and_fd_invalid(const char *function_name, int dir_fd, int fd)
1009{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001010 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1011 PyErr_Format(PyExc_ValueError,
1012 "%s: can't specify both dir_fd and fd",
1013 function_name);
1014 return 1;
1015 }
1016 return 0;
1017}
1018
1019static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001020fd_and_follow_symlinks_invalid(const char *function_name, int fd,
1021 int follow_symlinks)
1022{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001023 if ((fd > 0) && (!follow_symlinks)) {
1024 PyErr_Format(PyExc_ValueError,
1025 "%s: cannot use fd and follow_symlinks together",
1026 function_name);
1027 return 1;
1028 }
1029 return 0;
1030}
1031
1032static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001033dir_fd_and_follow_symlinks_invalid(const char *function_name, int dir_fd,
1034 int follow_symlinks)
1035{
Larry Hastings9cf065c2012-06-22 16:30:09 -07001036 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1037 PyErr_Format(PyExc_ValueError,
1038 "%s: cannot use dir_fd and follow_symlinks together",
1039 function_name);
1040 return 1;
1041 }
1042 return 0;
1043}
1044
Larry Hastings2f936352014-08-05 14:04:04 +10001045#ifdef MS_WINDOWS
1046 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001047#else
Larry Hastings2f936352014-08-05 14:04:04 +10001048 typedef off_t Py_off_t;
1049#endif
1050
1051static int
1052Py_off_t_converter(PyObject *arg, void *addr)
1053{
1054#ifdef HAVE_LARGEFILE_SUPPORT
1055 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1056#else
1057 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001058#endif
1059 if (PyErr_Occurred())
1060 return 0;
1061 return 1;
1062}
Larry Hastings2f936352014-08-05 14:04:04 +10001063
1064static PyObject *
1065PyLong_FromPy_off_t(Py_off_t offset)
1066{
1067#ifdef HAVE_LARGEFILE_SUPPORT
1068 return PyLong_FromLongLong(offset);
1069#else
1070 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001071#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001072}
1073
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001074
Steve Dowerd81431f2015-03-06 14:47:02 -08001075#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1076/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1077 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001078 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001079#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001080#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001081#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001082#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001083#define _NO_CONSOLE_FILENO (intptr_t)-2
1084
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001085/* the special case of checking dup2. The target fd must be in a sensible range */
1086static int
1087_PyVerify_fd_dup2(int fd1, int fd2)
1088{
Victor Stinner8c62be82010-05-06 00:08:46 +00001089 if (!_PyVerify_fd(fd1))
1090 return 0;
1091 if (fd2 == _NO_CONSOLE_FILENO)
1092 return 0;
1093 if ((unsigned)fd2 < _NHANDLE_)
1094 return 1;
1095 else
1096 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001097}
1098#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001099#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001100#endif
1101
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001102#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001103
1104static int
Brian Curtind25aef52011-06-13 15:16:04 -05001105win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001106{
1107 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1108 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1109 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001110
1111 if (0 == DeviceIoControl(
1112 reparse_point_handle,
1113 FSCTL_GET_REPARSE_POINT,
1114 NULL, 0, /* in buffer */
1115 target_buffer, sizeof(target_buffer),
1116 &n_bytes_returned,
1117 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001118 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001119
1120 if (reparse_tag)
1121 *reparse_tag = rdb->ReparseTag;
1122
Brian Curtind25aef52011-06-13 15:16:04 -05001123 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001124}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001125
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001126#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001127
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001128/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001129#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001130/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001131** environ directly, we must obtain it with _NSGetEnviron(). See also
1132** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001133*/
1134#include <crt_externs.h>
1135static char **environ;
1136#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001137extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001138#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001139
Barry Warsaw53699e91996-12-10 23:23:01 +00001140static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001141convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001142{
Victor Stinner8c62be82010-05-06 00:08:46 +00001143 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001144#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001145 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001146#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001147 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001148#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001149
Victor Stinner8c62be82010-05-06 00:08:46 +00001150 d = PyDict_New();
1151 if (d == NULL)
1152 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001153#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001154 if (environ == NULL)
1155 environ = *_NSGetEnviron();
1156#endif
1157#ifdef MS_WINDOWS
1158 /* _wenviron must be initialized in this way if the program is started
1159 through main() instead of wmain(). */
1160 _wgetenv(L"");
1161 if (_wenviron == NULL)
1162 return d;
1163 /* This part ignores errors */
1164 for (e = _wenviron; *e != NULL; e++) {
1165 PyObject *k;
1166 PyObject *v;
1167 wchar_t *p = wcschr(*e, L'=');
1168 if (p == NULL)
1169 continue;
1170 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1171 if (k == NULL) {
1172 PyErr_Clear();
1173 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001174 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001175 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1176 if (v == NULL) {
1177 PyErr_Clear();
1178 Py_DECREF(k);
1179 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001180 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001181 if (PyDict_GetItem(d, k) == NULL) {
1182 if (PyDict_SetItem(d, k, v) != 0)
1183 PyErr_Clear();
1184 }
1185 Py_DECREF(k);
1186 Py_DECREF(v);
1187 }
1188#else
1189 if (environ == NULL)
1190 return d;
1191 /* This part ignores errors */
1192 for (e = environ; *e != NULL; e++) {
1193 PyObject *k;
1194 PyObject *v;
1195 char *p = strchr(*e, '=');
1196 if (p == NULL)
1197 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001198 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001199 if (k == NULL) {
1200 PyErr_Clear();
1201 continue;
1202 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001203 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001204 if (v == NULL) {
1205 PyErr_Clear();
1206 Py_DECREF(k);
1207 continue;
1208 }
1209 if (PyDict_GetItem(d, k) == NULL) {
1210 if (PyDict_SetItem(d, k, v) != 0)
1211 PyErr_Clear();
1212 }
1213 Py_DECREF(k);
1214 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001215 }
1216#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001217 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001218}
1219
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001220/* Set a POSIX-specific error from errno, and return NULL */
1221
Barry Warsawd58d7641998-07-23 16:14:40 +00001222static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001223posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001224{
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001226}
Mark Hammondef8b6542001-05-13 08:04:26 +00001227
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001228#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001229static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001230win32_error(const char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001231{
Victor Stinner8c62be82010-05-06 00:08:46 +00001232 /* XXX We should pass the function name along in the future.
1233 (winreg.c also wants to pass the function name.)
1234 This would however require an additional param to the
1235 Windows error object, which is non-trivial.
1236 */
1237 errno = GetLastError();
1238 if (filename)
1239 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1240 else
1241 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001242}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001243
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001244static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02001245win32_error_object(const char* function, PyObject* filename)
Victor Stinnereb5657a2011-09-30 01:44:27 +02001246{
1247 /* XXX - see win32_error for comments on 'function' */
1248 errno = GetLastError();
1249 if (filename)
1250 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001251 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001252 errno,
1253 filename);
1254 else
1255 return PyErr_SetFromWindowsErr(errno);
1256}
1257
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001258#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001259
Larry Hastings9cf065c2012-06-22 16:30:09 -07001260static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001261path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001262{
1263#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001264 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1265 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001266#else
Victor Stinner292c8352012-10-30 02:17:38 +01001267 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001268#endif
1269}
1270
Larry Hastings31826802013-10-19 00:09:25 -07001271
Larry Hastingsb0827312014-02-09 22:05:19 -08001272static PyObject *
1273path_error2(path_t *path, path_t *path2)
1274{
1275#ifdef MS_WINDOWS
1276 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1277 0, path->object, path2->object);
1278#else
1279 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1280 path->object, path2->object);
1281#endif
1282}
1283
1284
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001285/* POSIX generic methods */
1286
Larry Hastings2f936352014-08-05 14:04:04 +10001287static int
1288fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001289{
Victor Stinner8c62be82010-05-06 00:08:46 +00001290 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001291 int *pointer = (int *)p;
1292 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001293 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001294 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001295 *pointer = fd;
1296 return 1;
1297}
1298
1299static PyObject *
1300posix_fildes_fd(int fd, int (*func)(int))
1301{
1302 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001303 int async_err = 0;
1304
Steve Dower8fc89802015-04-12 00:26:27 -04001305 if (!_PyVerify_fd(fd))
1306 return posix_error();
1307
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001308 do {
1309 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001310 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001311 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001312 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001313 Py_END_ALLOW_THREADS
1314 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1315 if (res != 0)
1316 return (!async_err) ? posix_error() : NULL;
1317 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001318}
Guido van Rossum21142a01999-01-08 21:05:37 +00001319
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001320
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001321#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001322/* This is a reimplementation of the C library's chdir function,
1323 but one that produces Win32 errors instead of DOS error codes.
1324 chdir is essentially a wrapper around SetCurrentDirectory; however,
1325 it also needs to set "magic" environment variables indicating
1326 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001327static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001328win32_chdir(LPCSTR path)
1329{
Victor Stinner75875072013-11-24 19:23:25 +01001330 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001331 int result;
1332 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001333
Victor Stinner8c62be82010-05-06 00:08:46 +00001334 if(!SetCurrentDirectoryA(path))
1335 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001336 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001337 if (!result)
1338 return FALSE;
1339 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001340 than MAX_PATH-1 (not including the final null character). */
1341 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001342 if (strncmp(new_path, "\\\\", 2) == 0 ||
1343 strncmp(new_path, "//", 2) == 0)
1344 /* UNC path, nothing to do. */
1345 return TRUE;
1346 env[1] = new_path[0];
1347 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001348}
1349
1350/* The Unicode version differs from the ANSI version
1351 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001352static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001353win32_wchdir(LPCWSTR path)
1354{
Victor Stinnered537822015-12-13 21:40:26 +01001355 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001356 int result;
1357 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001358
Victor Stinner8c62be82010-05-06 00:08:46 +00001359 if(!SetCurrentDirectoryW(path))
1360 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001361 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001362 if (!result)
1363 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001364 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001365 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 if (!new_path) {
1367 SetLastError(ERROR_OUTOFMEMORY);
1368 return FALSE;
1369 }
1370 result = GetCurrentDirectoryW(result, new_path);
1371 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001372 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001373 return FALSE;
1374 }
1375 }
1376 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1377 wcsncmp(new_path, L"//", 2) == 0)
1378 /* UNC path, nothing to do. */
1379 return TRUE;
1380 env[1] = new_path[0];
1381 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001382 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001383 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001384 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001385}
1386#endif
1387
Martin v. Löwis14694662006-02-03 12:54:16 +00001388#ifdef MS_WINDOWS
1389/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1390 - time stamps are restricted to second resolution
1391 - file modification times suffer from forth-and-back conversions between
1392 UTC and local time
1393 Therefore, we implement our own stat, based on the Win32 API directly.
1394*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001395#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001396#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001397
Guido van Rossumd8faa362007-04-27 19:54:29 +00001398static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001399attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001400{
Victor Stinner8c62be82010-05-06 00:08:46 +00001401 HANDLE hFindFile;
1402 WIN32_FIND_DATAA FileData;
1403 hFindFile = FindFirstFileA(pszFile, &FileData);
1404 if (hFindFile == INVALID_HANDLE_VALUE)
1405 return FALSE;
1406 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001407 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001408 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001409 info->dwFileAttributes = FileData.dwFileAttributes;
1410 info->ftCreationTime = FileData.ftCreationTime;
1411 info->ftLastAccessTime = FileData.ftLastAccessTime;
1412 info->ftLastWriteTime = FileData.ftLastWriteTime;
1413 info->nFileSizeHigh = FileData.nFileSizeHigh;
1414 info->nFileSizeLow = FileData.nFileSizeLow;
1415/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001416 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1417 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001418 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001419}
1420
Victor Stinner6036e442015-03-08 01:58:04 +01001421static void
1422find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1423 BY_HANDLE_FILE_INFORMATION *info,
1424 ULONG *reparse_tag)
1425{
1426 memset(info, 0, sizeof(*info));
1427 info->dwFileAttributes = pFileData->dwFileAttributes;
1428 info->ftCreationTime = pFileData->ftCreationTime;
1429 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1430 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1431 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1432 info->nFileSizeLow = pFileData->nFileSizeLow;
1433/* info->nNumberOfLinks = 1; */
1434 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1435 *reparse_tag = pFileData->dwReserved0;
1436 else
1437 *reparse_tag = 0;
1438}
1439
Guido van Rossumd8faa362007-04-27 19:54:29 +00001440static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001441attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001442{
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 HANDLE hFindFile;
1444 WIN32_FIND_DATAW FileData;
1445 hFindFile = FindFirstFileW(pszFile, &FileData);
1446 if (hFindFile == INVALID_HANDLE_VALUE)
1447 return FALSE;
1448 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001449 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001450 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001451}
1452
Brian Curtind25aef52011-06-13 15:16:04 -05001453static BOOL
1454get_target_path(HANDLE hdl, wchar_t **target_path)
1455{
1456 int buf_size, result_length;
1457 wchar_t *buf;
1458
1459 /* We have a good handle to the target, use it to determine
1460 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001461 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1462 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001463 if(!buf_size)
1464 return FALSE;
1465
Victor Stinnerc36674a2016-03-16 14:30:16 +01001466 buf = (wchar_t *)PyMem_RawMalloc((buf_size + 1) * sizeof(wchar_t));
Brian Curtinc8be8402011-06-14 09:52:50 -05001467 if (!buf) {
1468 SetLastError(ERROR_OUTOFMEMORY);
1469 return FALSE;
1470 }
1471
Steve Dower2ea51c92015-03-20 21:49:12 -07001472 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001473 buf, buf_size, VOLUME_NAME_DOS);
1474
1475 if(!result_length) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001476 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001477 return FALSE;
1478 }
1479
1480 if(!CloseHandle(hdl)) {
Victor Stinnerc36674a2016-03-16 14:30:16 +01001481 PyMem_RawFree(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001482 return FALSE;
1483 }
1484
1485 buf[result_length] = 0;
1486
1487 *target_path = buf;
1488 return TRUE;
1489}
1490
1491static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001492win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001493 BOOL traverse);
1494static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001495win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001496 BOOL traverse)
1497{
Victor Stinner26de69d2011-06-17 15:15:38 +02001498 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001499 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001500 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001501 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001502 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001503 const char *dot;
1504
1505 hFile = CreateFileA(
1506 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001507 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001508 0, /* share mode */
1509 NULL, /* security attributes */
1510 OPEN_EXISTING,
1511 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001512 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1513 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001514 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001515 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1516 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001517 NULL);
1518
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001519 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001520 /* Either the target doesn't exist, or we don't have access to
1521 get a handle to it. If the former, we need to return an error.
1522 If the latter, we can use attributes_from_dir. */
1523 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001524 return -1;
1525 /* Could not get attributes on open file. Fall back to
1526 reading the directory. */
1527 if (!attributes_from_dir(path, &info, &reparse_tag))
1528 /* Very strange. This should not fail now */
1529 return -1;
1530 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1531 if (traverse) {
1532 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001533 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001534 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001535 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001536 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001537 } else {
1538 if (!GetFileInformationByHandle(hFile, &info)) {
1539 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001540 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001541 }
1542 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001543 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1544 return -1;
1545
1546 /* Close the outer open file handle now that we're about to
1547 reopen it with different flags. */
1548 if (!CloseHandle(hFile))
1549 return -1;
1550
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001551 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001552 /* In order to call GetFinalPathNameByHandle we need to open
1553 the file without the reparse handling flag set. */
1554 hFile2 = CreateFileA(
1555 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1556 NULL, OPEN_EXISTING,
1557 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1558 NULL);
1559 if (hFile2 == INVALID_HANDLE_VALUE)
1560 return -1;
1561
1562 if (!get_target_path(hFile2, &target_path))
1563 return -1;
1564
1565 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001566 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001567 return code;
1568 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001569 } else
1570 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001571 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001572 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001573
1574 /* Set S_IEXEC if it is an .exe, .bat, ... */
1575 dot = strrchr(path, '.');
1576 if (dot) {
1577 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1578 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1579 result->st_mode |= 0111;
1580 }
1581 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001582}
1583
1584static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001585win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001586 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001587{
1588 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001589 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001590 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001591 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001592 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001593 const wchar_t *dot;
1594
1595 hFile = CreateFileW(
1596 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001597 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001598 0, /* share mode */
1599 NULL, /* security attributes */
1600 OPEN_EXISTING,
1601 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001602 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1603 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001604 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001605 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001606 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001607 NULL);
1608
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001609 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001610 /* Either the target doesn't exist, or we don't have access to
1611 get a handle to it. If the former, we need to return an error.
1612 If the latter, we can use attributes_from_dir. */
1613 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001614 return -1;
1615 /* Could not get attributes on open file. Fall back to
1616 reading the directory. */
1617 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1618 /* Very strange. This should not fail now */
1619 return -1;
1620 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1621 if (traverse) {
1622 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001623 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001625 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001626 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001627 } else {
1628 if (!GetFileInformationByHandle(hFile, &info)) {
1629 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001630 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001631 }
1632 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001633 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1634 return -1;
1635
1636 /* Close the outer open file handle now that we're about to
1637 reopen it with different flags. */
1638 if (!CloseHandle(hFile))
1639 return -1;
1640
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001641 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001642 /* In order to call GetFinalPathNameByHandle we need to open
1643 the file without the reparse handling flag set. */
1644 hFile2 = CreateFileW(
1645 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1646 NULL, OPEN_EXISTING,
1647 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1648 NULL);
1649 if (hFile2 == INVALID_HANDLE_VALUE)
1650 return -1;
1651
1652 if (!get_target_path(hFile2, &target_path))
1653 return -1;
1654
1655 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerc36674a2016-03-16 14:30:16 +01001656 PyMem_RawFree(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001657 return code;
1658 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001659 } else
1660 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001661 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001662 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001663
1664 /* Set S_IEXEC if it is an .exe, .bat, ... */
1665 dot = wcsrchr(path, '.');
1666 if (dot) {
1667 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1668 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1669 result->st_mode |= 0111;
1670 }
1671 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001672}
1673
1674static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001675win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677 /* Protocol violation: we explicitly clear errno, instead of
1678 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001679 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001680 errno = 0;
1681 return code;
1682}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001683
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001684static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001685win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001686{
1687 /* Protocol violation: we explicitly clear errno, instead of
1688 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001689 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001690 errno = 0;
1691 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001692}
Brian Curtind25aef52011-06-13 15:16:04 -05001693/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001694
1695 In Posix, stat automatically traverses symlinks and returns the stat
1696 structure for the target. In Windows, the equivalent GetFileAttributes by
1697 default does not traverse symlinks and instead returns attributes for
1698 the symlink.
1699
1700 Therefore, win32_lstat will get the attributes traditionally, and
1701 win32_stat will first explicitly resolve the symlink target and then will
1702 call win32_lstat on that result.
1703
Ezio Melotti4969f702011-03-15 05:59:46 +02001704 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001705
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001706static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001707win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001708{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001710}
1711
Victor Stinner8c62be82010-05-06 00:08:46 +00001712static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001713win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001714{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001716}
1717
1718static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001719win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001720{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001721 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001722}
1723
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001724static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001725win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001726{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001727 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001728}
1729
Martin v. Löwis14694662006-02-03 12:54:16 +00001730#endif /* MS_WINDOWS */
1731
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001732PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001733"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001734This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001735 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001736or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1737\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001738Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1739or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001740\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001741See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001742
1743static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001744 {"st_mode", "protection bits"},
1745 {"st_ino", "inode"},
1746 {"st_dev", "device"},
1747 {"st_nlink", "number of hard links"},
1748 {"st_uid", "user ID of owner"},
1749 {"st_gid", "group ID of owner"},
1750 {"st_size", "total size, in bytes"},
1751 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1752 {NULL, "integer time of last access"},
1753 {NULL, "integer time of last modification"},
1754 {NULL, "integer time of last change"},
1755 {"st_atime", "time of last access"},
1756 {"st_mtime", "time of last modification"},
1757 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001758 {"st_atime_ns", "time of last access in nanoseconds"},
1759 {"st_mtime_ns", "time of last modification in nanoseconds"},
1760 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001761#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001762 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001763#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001764#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001765 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001766#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001767#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001768 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001769#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001770#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001771 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001772#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001773#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001774 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001775#endif
1776#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001777 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001778#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001779#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1780 {"st_file_attributes", "Windows file attribute bits"},
1781#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001782 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001783};
1784
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001785#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001786#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001787#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001788#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001789#endif
1790
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001791#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001792#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1793#else
1794#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1795#endif
1796
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001797#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001798#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1799#else
1800#define ST_RDEV_IDX ST_BLOCKS_IDX
1801#endif
1802
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001803#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1804#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1805#else
1806#define ST_FLAGS_IDX ST_RDEV_IDX
1807#endif
1808
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001809#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001810#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001811#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001812#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001813#endif
1814
1815#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1816#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1817#else
1818#define ST_BIRTHTIME_IDX ST_GEN_IDX
1819#endif
1820
Zachary Ware63f277b2014-06-19 09:46:37 -05001821#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1822#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1823#else
1824#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1825#endif
1826
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001828 "stat_result", /* name */
1829 stat_result__doc__, /* doc */
1830 stat_result_fields,
1831 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001832};
1833
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001834PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001835"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1836This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001837 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001838or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001839\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001840See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001841
1842static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001843 {"f_bsize", },
1844 {"f_frsize", },
1845 {"f_blocks", },
1846 {"f_bfree", },
1847 {"f_bavail", },
1848 {"f_files", },
1849 {"f_ffree", },
1850 {"f_favail", },
1851 {"f_flag", },
1852 {"f_namemax",},
1853 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854};
1855
1856static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001857 "statvfs_result", /* name */
1858 statvfs_result__doc__, /* doc */
1859 statvfs_result_fields,
1860 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001861};
1862
Ross Lagerwall7807c352011-03-17 20:20:30 +02001863#if defined(HAVE_WAITID) && !defined(__APPLE__)
1864PyDoc_STRVAR(waitid_result__doc__,
1865"waitid_result: Result from waitid.\n\n\
1866This object may be accessed either as a tuple of\n\
1867 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1868or via the attributes si_pid, si_uid, and so on.\n\
1869\n\
1870See os.waitid for more information.");
1871
1872static PyStructSequence_Field waitid_result_fields[] = {
1873 {"si_pid", },
1874 {"si_uid", },
1875 {"si_signo", },
1876 {"si_status", },
1877 {"si_code", },
1878 {0}
1879};
1880
1881static PyStructSequence_Desc waitid_result_desc = {
1882 "waitid_result", /* name */
1883 waitid_result__doc__, /* doc */
1884 waitid_result_fields,
1885 5
1886};
1887static PyTypeObject WaitidResultType;
1888#endif
1889
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001890static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001891static PyTypeObject StatResultType;
1892static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001893#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001894static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001895#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001896static newfunc structseq_new;
1897
1898static PyObject *
1899statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1900{
Victor Stinner8c62be82010-05-06 00:08:46 +00001901 PyStructSequence *result;
1902 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001903
Victor Stinner8c62be82010-05-06 00:08:46 +00001904 result = (PyStructSequence*)structseq_new(type, args, kwds);
1905 if (!result)
1906 return NULL;
1907 /* If we have been initialized from a tuple,
1908 st_?time might be set to None. Initialize it
1909 from the int slots. */
1910 for (i = 7; i <= 9; i++) {
1911 if (result->ob_item[i+3] == Py_None) {
1912 Py_DECREF(Py_None);
1913 Py_INCREF(result->ob_item[i]);
1914 result->ob_item[i+3] = result->ob_item[i];
1915 }
1916 }
1917 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001918}
1919
1920
1921
1922/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001923static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001924
1925PyDoc_STRVAR(stat_float_times__doc__,
1926"stat_float_times([newval]) -> oldval\n\n\
1927Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001928\n\
1929If value is True, future calls to stat() return floats; if it is False,\n\
1930future calls return ints.\n\
1931If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001932
Larry Hastings2f936352014-08-05 14:04:04 +10001933/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001934static PyObject*
1935stat_float_times(PyObject* self, PyObject *args)
1936{
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 int newval = -1;
1938 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1939 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001940 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1941 "stat_float_times() is deprecated",
1942 1))
1943 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001944 if (newval == -1)
1945 /* Return old value */
1946 return PyBool_FromLong(_stat_float_times);
1947 _stat_float_times = newval;
1948 Py_INCREF(Py_None);
1949 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001950}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001951
Larry Hastings6fe20b32012-04-19 15:07:49 -07001952static PyObject *billion = NULL;
1953
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001954static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001955fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001956{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001957 PyObject *s = _PyLong_FromTime_t(sec);
1958 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1959 PyObject *s_in_ns = NULL;
1960 PyObject *ns_total = NULL;
1961 PyObject *float_s = NULL;
1962
1963 if (!(s && ns_fractional))
1964 goto exit;
1965
1966 s_in_ns = PyNumber_Multiply(s, billion);
1967 if (!s_in_ns)
1968 goto exit;
1969
1970 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1971 if (!ns_total)
1972 goto exit;
1973
Victor Stinner4195b5c2012-02-08 23:03:19 +01001974 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001975 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1976 if (!float_s)
1977 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001978 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001979 else {
1980 float_s = s;
1981 Py_INCREF(float_s);
1982 }
1983
1984 PyStructSequence_SET_ITEM(v, index, s);
1985 PyStructSequence_SET_ITEM(v, index+3, float_s);
1986 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1987 s = NULL;
1988 float_s = NULL;
1989 ns_total = NULL;
1990exit:
1991 Py_XDECREF(s);
1992 Py_XDECREF(ns_fractional);
1993 Py_XDECREF(s_in_ns);
1994 Py_XDECREF(ns_total);
1995 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001996}
1997
Tim Peters5aa91602002-01-30 05:46:57 +00001998/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001999 (used by posix_stat() and posix_fstat()) */
2000static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01002001_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00002002{
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 unsigned long ansec, mnsec, cnsec;
2004 PyObject *v = PyStructSequence_New(&StatResultType);
2005 if (v == NULL)
2006 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002007
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002009#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002010 PyStructSequence_SET_ITEM(v, 1,
2011 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002012#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002014#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002015#ifdef MS_WINDOWS
2016 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002017#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002018 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002019#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002021#if defined(MS_WINDOWS)
2022 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2023 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2024#else
2025 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2026 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2027#endif
Fred Drake699f3522000-06-29 21:12:41 +00002028#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 PyStructSequence_SET_ITEM(v, 6,
2030 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002031#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002033#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002034
Martin v. Löwis14694662006-02-03 12:54:16 +00002035#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 ansec = st->st_atim.tv_nsec;
2037 mnsec = st->st_mtim.tv_nsec;
2038 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002039#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002040 ansec = st->st_atimespec.tv_nsec;
2041 mnsec = st->st_mtimespec.tv_nsec;
2042 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002043#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002044 ansec = st->st_atime_nsec;
2045 mnsec = st->st_mtime_nsec;
2046 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002047#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002049#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002050 fill_time(v, 7, st->st_atime, ansec);
2051 fill_time(v, 8, st->st_mtime, mnsec);
2052 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002053
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002054#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2056 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002057#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002058#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2060 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002061#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002062#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002063 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2064 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002065#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002066#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002067 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2068 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002069#endif
2070#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002071 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002072 PyObject *val;
2073 unsigned long bsec,bnsec;
2074 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002075#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002076 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002077#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002078 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002079#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002080 if (_stat_float_times) {
2081 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2082 } else {
2083 val = PyLong_FromLong((long)bsec);
2084 }
2085 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2086 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002087 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002088#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002089#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002090 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2091 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002092#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002093#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2094 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2095 PyLong_FromUnsignedLong(st->st_file_attributes));
2096#endif
Fred Drake699f3522000-06-29 21:12:41 +00002097
Victor Stinner8c62be82010-05-06 00:08:46 +00002098 if (PyErr_Occurred()) {
2099 Py_DECREF(v);
2100 return NULL;
2101 }
Fred Drake699f3522000-06-29 21:12:41 +00002102
Victor Stinner8c62be82010-05-06 00:08:46 +00002103 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002104}
2105
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002106/* POSIX methods */
2107
Guido van Rossum94f6f721999-01-06 18:42:14 +00002108
2109static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02002110posix_do_stat(const char *function_name, path_t *path,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002111 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002112{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002113 STRUCT_STAT st;
2114 int result;
2115
2116#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2117 if (follow_symlinks_specified(function_name, follow_symlinks))
2118 return NULL;
2119#endif
2120
2121 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2122 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2123 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2124 return NULL;
2125
2126 Py_BEGIN_ALLOW_THREADS
2127 if (path->fd != -1)
2128 result = FSTAT(path->fd, &st);
2129 else
2130#ifdef MS_WINDOWS
2131 if (path->wide) {
2132 if (follow_symlinks)
2133 result = win32_stat_w(path->wide, &st);
2134 else
2135 result = win32_lstat_w(path->wide, &st);
2136 }
2137 else
2138#endif
2139#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2140 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2141 result = LSTAT(path->narrow, &st);
2142 else
2143#endif
2144#ifdef HAVE_FSTATAT
2145 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2146 result = fstatat(dir_fd, path->narrow, &st,
2147 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2148 else
2149#endif
2150 result = STAT(path->narrow, &st);
2151 Py_END_ALLOW_THREADS
2152
Victor Stinner292c8352012-10-30 02:17:38 +01002153 if (result != 0) {
2154 return path_error(path);
2155 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002156
2157 return _pystat_fromstructstat(&st);
2158}
2159
Larry Hastings2f936352014-08-05 14:04:04 +10002160/*[python input]
2161
2162for s in """
2163
2164FACCESSAT
2165FCHMODAT
2166FCHOWNAT
2167FSTATAT
2168LINKAT
2169MKDIRAT
2170MKFIFOAT
2171MKNODAT
2172OPENAT
2173READLINKAT
2174SYMLINKAT
2175UNLINKAT
2176
2177""".strip().split():
2178 s = s.strip()
2179 print("""
2180#ifdef HAVE_{s}
2181 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002182#else
Larry Hastings2f936352014-08-05 14:04:04 +10002183 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002184#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002185""".rstrip().format(s=s))
2186
2187for s in """
2188
2189FCHDIR
2190FCHMOD
2191FCHOWN
2192FDOPENDIR
2193FEXECVE
2194FPATHCONF
2195FSTATVFS
2196FTRUNCATE
2197
2198""".strip().split():
2199 s = s.strip()
2200 print("""
2201#ifdef HAVE_{s}
2202 #define PATH_HAVE_{s} 1
2203#else
2204 #define PATH_HAVE_{s} 0
2205#endif
2206
2207""".rstrip().format(s=s))
2208[python start generated code]*/
2209
2210#ifdef HAVE_FACCESSAT
2211 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2212#else
2213 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2214#endif
2215
2216#ifdef HAVE_FCHMODAT
2217 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2218#else
2219 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2220#endif
2221
2222#ifdef HAVE_FCHOWNAT
2223 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2224#else
2225 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2226#endif
2227
2228#ifdef HAVE_FSTATAT
2229 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2230#else
2231 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2232#endif
2233
2234#ifdef HAVE_LINKAT
2235 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2236#else
2237 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2238#endif
2239
2240#ifdef HAVE_MKDIRAT
2241 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2242#else
2243 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2244#endif
2245
2246#ifdef HAVE_MKFIFOAT
2247 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2248#else
2249 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2250#endif
2251
2252#ifdef HAVE_MKNODAT
2253 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2254#else
2255 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2256#endif
2257
2258#ifdef HAVE_OPENAT
2259 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2260#else
2261 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2262#endif
2263
2264#ifdef HAVE_READLINKAT
2265 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2266#else
2267 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2268#endif
2269
2270#ifdef HAVE_SYMLINKAT
2271 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2272#else
2273 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2274#endif
2275
2276#ifdef HAVE_UNLINKAT
2277 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2278#else
2279 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2280#endif
2281
2282#ifdef HAVE_FCHDIR
2283 #define PATH_HAVE_FCHDIR 1
2284#else
2285 #define PATH_HAVE_FCHDIR 0
2286#endif
2287
2288#ifdef HAVE_FCHMOD
2289 #define PATH_HAVE_FCHMOD 1
2290#else
2291 #define PATH_HAVE_FCHMOD 0
2292#endif
2293
2294#ifdef HAVE_FCHOWN
2295 #define PATH_HAVE_FCHOWN 1
2296#else
2297 #define PATH_HAVE_FCHOWN 0
2298#endif
2299
2300#ifdef HAVE_FDOPENDIR
2301 #define PATH_HAVE_FDOPENDIR 1
2302#else
2303 #define PATH_HAVE_FDOPENDIR 0
2304#endif
2305
2306#ifdef HAVE_FEXECVE
2307 #define PATH_HAVE_FEXECVE 1
2308#else
2309 #define PATH_HAVE_FEXECVE 0
2310#endif
2311
2312#ifdef HAVE_FPATHCONF
2313 #define PATH_HAVE_FPATHCONF 1
2314#else
2315 #define PATH_HAVE_FPATHCONF 0
2316#endif
2317
2318#ifdef HAVE_FSTATVFS
2319 #define PATH_HAVE_FSTATVFS 1
2320#else
2321 #define PATH_HAVE_FSTATVFS 0
2322#endif
2323
2324#ifdef HAVE_FTRUNCATE
2325 #define PATH_HAVE_FTRUNCATE 1
2326#else
2327 #define PATH_HAVE_FTRUNCATE 0
2328#endif
2329/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002330
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002331#ifdef MS_WINDOWS
2332 #undef PATH_HAVE_FTRUNCATE
2333 #define PATH_HAVE_FTRUNCATE 1
2334#endif
Larry Hastings31826802013-10-19 00:09:25 -07002335
Larry Hastings61272b72014-01-07 12:41:53 -08002336/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002337
2338class path_t_converter(CConverter):
2339
2340 type = "path_t"
2341 impl_by_reference = True
2342 parse_by_reference = True
2343
2344 converter = 'path_converter'
2345
2346 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002347 # right now path_t doesn't support default values.
2348 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002349 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002350 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002351
Larry Hastings2f936352014-08-05 14:04:04 +10002352 if self.c_default not in (None, 'Py_None'):
2353 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002354
2355 self.nullable = nullable
2356 self.allow_fd = allow_fd
2357
Larry Hastings7726ac92014-01-31 22:03:12 -08002358 def pre_render(self):
2359 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002360 if isinstance(value, str):
2361 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002362 return str(int(bool(value)))
2363
2364 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002365 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002366 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002367 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002368 strify(self.nullable),
2369 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002370 )
2371
2372 def cleanup(self):
2373 return "path_cleanup(&" + self.name + ");\n"
2374
2375
2376class dir_fd_converter(CConverter):
2377 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002378
Larry Hastings2f936352014-08-05 14:04:04 +10002379 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002380 if self.default in (unspecified, None):
2381 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002382 if isinstance(requires, str):
2383 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2384 else:
2385 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002386
Larry Hastings2f936352014-08-05 14:04:04 +10002387class fildes_converter(CConverter):
2388 type = 'int'
2389 converter = 'fildes_converter'
2390
2391class uid_t_converter(CConverter):
2392 type = "uid_t"
2393 converter = '_Py_Uid_Converter'
2394
2395class gid_t_converter(CConverter):
2396 type = "gid_t"
2397 converter = '_Py_Gid_Converter'
2398
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002399class dev_t_converter(CConverter):
2400 type = 'dev_t'
2401 converter = '_Py_Dev_Converter'
2402
2403class dev_t_return_converter(unsigned_long_return_converter):
2404 type = 'dev_t'
2405 conversion_fn = '_PyLong_FromDev'
2406 unsigned_cast = '(dev_t)'
2407
Larry Hastings2f936352014-08-05 14:04:04 +10002408class FSConverter_converter(CConverter):
2409 type = 'PyObject *'
2410 converter = 'PyUnicode_FSConverter'
2411 def converter_init(self):
2412 if self.default is not unspecified:
2413 fail("FSConverter_converter does not support default values")
2414 self.c_default = 'NULL'
2415
2416 def cleanup(self):
2417 return "Py_XDECREF(" + self.name + ");\n"
2418
2419class pid_t_converter(CConverter):
2420 type = 'pid_t'
2421 format_unit = '" _Py_PARSE_PID "'
2422
2423class idtype_t_converter(int_converter):
2424 type = 'idtype_t'
2425
2426class id_t_converter(CConverter):
2427 type = 'id_t'
2428 format_unit = '" _Py_PARSE_PID "'
2429
2430class Py_intptr_t_converter(CConverter):
2431 type = 'Py_intptr_t'
2432 format_unit = '" _Py_PARSE_INTPTR "'
2433
2434class Py_off_t_converter(CConverter):
2435 type = 'Py_off_t'
2436 converter = 'Py_off_t_converter'
2437
2438class Py_off_t_return_converter(long_return_converter):
2439 type = 'Py_off_t'
2440 conversion_fn = 'PyLong_FromPy_off_t'
2441
2442class path_confname_converter(CConverter):
2443 type="int"
2444 converter="conv_path_confname"
2445
2446class confstr_confname_converter(path_confname_converter):
2447 converter='conv_confstr_confname'
2448
2449class sysconf_confname_converter(path_confname_converter):
2450 converter="conv_sysconf_confname"
2451
2452class sched_param_converter(CConverter):
2453 type = 'struct sched_param'
2454 converter = 'convert_sched_param'
2455 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002456
Larry Hastings61272b72014-01-07 12:41:53 -08002457[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002458/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002459
Larry Hastings61272b72014-01-07 12:41:53 -08002460/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002461
Larry Hastings2a727912014-01-16 11:32:01 -08002462os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002463
2464 path : path_t(allow_fd=True)
2465 Path to be examined; can be string, bytes, or open-file-descriptor int.
2466
2467 *
2468
Larry Hastings2f936352014-08-05 14:04:04 +10002469 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002470 If not None, it should be a file descriptor open to a directory,
2471 and path should be a relative string; path will then be relative to
2472 that directory.
2473
2474 follow_symlinks: bool = True
2475 If False, and the last element of the path is a symbolic link,
2476 stat will examine the symbolic link itself instead of the file
2477 the link points to.
2478
2479Perform a stat system call on the given path.
2480
2481dir_fd and follow_symlinks may not be implemented
2482 on your platform. If they are unavailable, using them will raise a
2483 NotImplementedError.
2484
2485It's an error to use dir_fd or follow_symlinks when specifying path as
2486 an open file descriptor.
2487
Larry Hastings61272b72014-01-07 12:41:53 -08002488[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002489
Larry Hastings31826802013-10-19 00:09:25 -07002490static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002491os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd,
2492 int follow_symlinks)
2493/*[clinic end generated code: output=e4f7569f95d523ca input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002494{
2495 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2496}
2497
Larry Hastings2f936352014-08-05 14:04:04 +10002498
2499/*[clinic input]
2500os.lstat
2501
2502 path : path_t
2503
2504 *
2505
2506 dir_fd : dir_fd(requires='fstatat') = None
2507
2508Perform a stat system call on the given path, without following symbolic links.
2509
2510Like stat(), but do not follow symbolic links.
2511Equivalent to stat(path, follow_symlinks=False).
2512[clinic start generated code]*/
2513
Larry Hastings2f936352014-08-05 14:04:04 +10002514static PyObject *
2515os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002516/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002517{
2518 int follow_symlinks = 0;
2519 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2520}
Larry Hastings31826802013-10-19 00:09:25 -07002521
Larry Hastings2f936352014-08-05 14:04:04 +10002522
Larry Hastings61272b72014-01-07 12:41:53 -08002523/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002524os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002525
2526 path: path_t(allow_fd=True)
2527 Path to be tested; can be string, bytes, or open-file-descriptor int.
2528
2529 mode: int
2530 Operating-system mode bitfield. Can be F_OK to test existence,
2531 or the inclusive-OR of R_OK, W_OK, and X_OK.
2532
2533 *
2534
Larry Hastings2f936352014-08-05 14:04:04 +10002535 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002536 If not None, it should be a file descriptor open to a directory,
2537 and path should be relative; path will then be relative to that
2538 directory.
2539
2540 effective_ids: bool = False
2541 If True, access will use the effective uid/gid instead of
2542 the real uid/gid.
2543
2544 follow_symlinks: bool = True
2545 If False, and the last element of the path is a symbolic link,
2546 access will examine the symbolic link itself instead of the file
2547 the link points to.
2548
2549Use the real uid/gid to test for access to a path.
2550
2551{parameters}
2552dir_fd, effective_ids, and follow_symlinks may not be implemented
2553 on your platform. If they are unavailable, using them will raise a
2554 NotImplementedError.
2555
2556Note that most operations will use the effective uid/gid, therefore this
2557 routine can be used in a suid/sgid environment to test if the invoking user
2558 has the specified access to the path.
2559
Larry Hastings61272b72014-01-07 12:41:53 -08002560[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002561
Larry Hastings2f936352014-08-05 14:04:04 +10002562static int
Larry Hastings89964c42015-04-14 18:07:59 -04002563os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2564 int effective_ids, int follow_symlinks)
2565/*[clinic end generated code: output=abaa53340210088d input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002566{
Larry Hastings2f936352014-08-05 14:04:04 +10002567 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002568
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002569#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002570 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002571#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002572 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002573#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002574
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575#ifndef HAVE_FACCESSAT
2576 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002577 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002578
2579 if (effective_ids) {
2580 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002581 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582 }
2583#endif
2584
2585#ifdef MS_WINDOWS
2586 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002587 if (path->wide != NULL)
2588 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002590 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591 Py_END_ALLOW_THREADS
2592
2593 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002594 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002595 * * we didn't get a -1, and
2596 * * write access wasn't requested,
2597 * * or the file isn't read-only,
2598 * * or it's a directory.
2599 * (Directories cannot be read-only on Windows.)
2600 */
Larry Hastings2f936352014-08-05 14:04:04 +10002601 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002602 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002603 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002604 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002605#else
2606
2607 Py_BEGIN_ALLOW_THREADS
2608#ifdef HAVE_FACCESSAT
2609 if ((dir_fd != DEFAULT_DIR_FD) ||
2610 effective_ids ||
2611 !follow_symlinks) {
2612 int flags = 0;
2613 if (!follow_symlinks)
2614 flags |= AT_SYMLINK_NOFOLLOW;
2615 if (effective_ids)
2616 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002617 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002618 }
2619 else
2620#endif
Larry Hastings31826802013-10-19 00:09:25 -07002621 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002622 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002623 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002624#endif
2625
Larry Hastings9cf065c2012-06-22 16:30:09 -07002626 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002627}
2628
Guido van Rossumd371ff11999-01-25 16:12:23 +00002629#ifndef F_OK
2630#define F_OK 0
2631#endif
2632#ifndef R_OK
2633#define R_OK 4
2634#endif
2635#ifndef W_OK
2636#define W_OK 2
2637#endif
2638#ifndef X_OK
2639#define X_OK 1
2640#endif
2641
Larry Hastings31826802013-10-19 00:09:25 -07002642
Guido van Rossumd371ff11999-01-25 16:12:23 +00002643#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002644/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002645os.ttyname -> DecodeFSDefault
2646
2647 fd: int
2648 Integer file descriptor handle.
2649
2650 /
2651
2652Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002653[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002654
Larry Hastings31826802013-10-19 00:09:25 -07002655static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002656os_ttyname_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002657/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002658{
2659 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002660
Larry Hastings31826802013-10-19 00:09:25 -07002661 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002662 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002663 posix_error();
2664 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002665}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002666#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002667
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002668#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002669/*[clinic input]
2670os.ctermid
2671
2672Return the name of the controlling terminal for this process.
2673[clinic start generated code]*/
2674
Larry Hastings2f936352014-08-05 14:04:04 +10002675static PyObject *
2676os_ctermid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002677/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002678{
Victor Stinner8c62be82010-05-06 00:08:46 +00002679 char *ret;
2680 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002681
Greg Wardb48bc172000-03-01 21:51:56 +00002682#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002683 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002684#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002685 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002686#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002687 if (ret == NULL)
2688 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002689 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002690}
Larry Hastings2f936352014-08-05 14:04:04 +10002691#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002692
Larry Hastings2f936352014-08-05 14:04:04 +10002693
2694/*[clinic input]
2695os.chdir
2696
2697 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2698
2699Change the current working directory to the specified path.
2700
2701path may always be specified as a string.
2702On some platforms, path may also be specified as an open file descriptor.
2703 If this functionality is unavailable, using it raises an exception.
2704[clinic start generated code]*/
2705
Larry Hastings2f936352014-08-05 14:04:04 +10002706static PyObject *
2707os_chdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002708/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002709{
2710 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002711
2712 Py_BEGIN_ALLOW_THREADS
2713#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002714 if (path->wide)
2715 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716 else
Larry Hastings2f936352014-08-05 14:04:04 +10002717 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002718 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719#else
2720#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002721 if (path->fd != -1)
2722 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002723 else
2724#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002725 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002726#endif
2727 Py_END_ALLOW_THREADS
2728
2729 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002730 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002731 }
2732
Larry Hastings2f936352014-08-05 14:04:04 +10002733 Py_RETURN_NONE;
2734}
2735
2736
2737#ifdef HAVE_FCHDIR
2738/*[clinic input]
2739os.fchdir
2740
2741 fd: fildes
2742
2743Change to the directory of the given file descriptor.
2744
2745fd must be opened on a directory, not a file.
2746Equivalent to os.chdir(fd).
2747
2748[clinic start generated code]*/
2749
Fred Drake4d1e64b2002-04-15 19:40:07 +00002750static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002751os_fchdir_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002752/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002753{
Larry Hastings2f936352014-08-05 14:04:04 +10002754 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002755}
2756#endif /* HAVE_FCHDIR */
2757
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002758
Larry Hastings2f936352014-08-05 14:04:04 +10002759/*[clinic input]
2760os.chmod
2761
2762 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2763 Path to be modified. May always be specified as a str or bytes.
2764 On some platforms, path may also be specified as an open file descriptor.
2765 If this functionality is unavailable, using it raises an exception.
2766
2767 mode: int
2768 Operating-system mode bitfield.
2769
2770 *
2771
2772 dir_fd : dir_fd(requires='fchmodat') = None
2773 If not None, it should be a file descriptor open to a directory,
2774 and path should be relative; path will then be relative to that
2775 directory.
2776
2777 follow_symlinks: bool = True
2778 If False, and the last element of the path is a symbolic link,
2779 chmod will modify the symbolic link itself instead of the file
2780 the link points to.
2781
2782Change the access permissions of a file.
2783
2784It is an error to use dir_fd or follow_symlinks when specifying path as
2785 an open file descriptor.
2786dir_fd and follow_symlinks may not be implemented on your platform.
2787 If they are unavailable, using them will raise a NotImplementedError.
2788
2789[clinic start generated code]*/
2790
Larry Hastings2f936352014-08-05 14:04:04 +10002791static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002792os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2793 int follow_symlinks)
2794/*[clinic end generated code: output=05e7f73b1a843ba2 input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002795{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002796 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002797
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002798#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002799 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002801
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#ifdef HAVE_FCHMODAT
2803 int fchmodat_nofollow_unsupported = 0;
2804#endif
2805
Larry Hastings9cf065c2012-06-22 16:30:09 -07002806#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2807 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002808 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002809#endif
2810
2811#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002812 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002813 if (path->wide)
2814 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002815 else
Larry Hastings2f936352014-08-05 14:04:04 +10002816 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002817 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 result = 0;
2819 else {
2820 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002821 attr &= ~FILE_ATTRIBUTE_READONLY;
2822 else
2823 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002824 if (path->wide)
2825 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 else
Larry Hastings2f936352014-08-05 14:04:04 +10002827 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002828 }
2829 Py_END_ALLOW_THREADS
2830
2831 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002832 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002833 }
2834#else /* MS_WINDOWS */
2835 Py_BEGIN_ALLOW_THREADS
2836#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002837 if (path->fd != -1)
2838 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002839 else
2840#endif
2841#ifdef HAVE_LCHMOD
2842 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002843 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 else
2845#endif
2846#ifdef HAVE_FCHMODAT
2847 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2848 /*
2849 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2850 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002851 * and then says it isn't implemented yet.
2852 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002853 *
2854 * Once it is supported, os.chmod will automatically
2855 * support dir_fd and follow_symlinks=False. (Hopefully.)
2856 * Until then, we need to be careful what exception we raise.
2857 */
Larry Hastings2f936352014-08-05 14:04:04 +10002858 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002859 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2860 /*
2861 * But wait! We can't throw the exception without allowing threads,
2862 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2863 */
2864 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002865 result &&
2866 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2867 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002868 }
2869 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002870#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002871 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002872 Py_END_ALLOW_THREADS
2873
2874 if (result) {
2875#ifdef HAVE_FCHMODAT
2876 if (fchmodat_nofollow_unsupported) {
2877 if (dir_fd != DEFAULT_DIR_FD)
2878 dir_fd_and_follow_symlinks_invalid("chmod",
2879 dir_fd, follow_symlinks);
2880 else
2881 follow_symlinks_specified("chmod", follow_symlinks);
2882 }
2883 else
2884#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002885 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002886 }
2887#endif
2888
Larry Hastings2f936352014-08-05 14:04:04 +10002889 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002890}
2891
Larry Hastings9cf065c2012-06-22 16:30:09 -07002892
Christian Heimes4e30a842007-11-30 22:12:06 +00002893#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002894/*[clinic input]
2895os.fchmod
2896
2897 fd: int
2898 mode: int
2899
2900Change the access permissions of the file given by file descriptor fd.
2901
2902Equivalent to os.chmod(fd, mode).
2903[clinic start generated code]*/
2904
Larry Hastings2f936352014-08-05 14:04:04 +10002905static PyObject *
2906os_fchmod_impl(PyModuleDef *module, int fd, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002907/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002908{
2909 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002910 int async_err = 0;
2911
2912 do {
2913 Py_BEGIN_ALLOW_THREADS
2914 res = fchmod(fd, mode);
2915 Py_END_ALLOW_THREADS
2916 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2917 if (res != 0)
2918 return (!async_err) ? posix_error() : NULL;
2919
Victor Stinner8c62be82010-05-06 00:08:46 +00002920 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002921}
2922#endif /* HAVE_FCHMOD */
2923
Larry Hastings2f936352014-08-05 14:04:04 +10002924
Christian Heimes4e30a842007-11-30 22:12:06 +00002925#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002926/*[clinic input]
2927os.lchmod
2928
2929 path: path_t
2930 mode: int
2931
2932Change the access permissions of a file, without following symbolic links.
2933
2934If path is a symlink, this affects the link itself rather than the target.
2935Equivalent to chmod(path, mode, follow_symlinks=False)."
2936[clinic start generated code]*/
2937
Larry Hastings2f936352014-08-05 14:04:04 +10002938static PyObject *
2939os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002940/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002941{
Victor Stinner8c62be82010-05-06 00:08:46 +00002942 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002944 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002945 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002946 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002947 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002948 return NULL;
2949 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002950 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002951}
2952#endif /* HAVE_LCHMOD */
2953
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002954
Thomas Wouterscf297e42007-02-23 15:07:44 +00002955#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002956/*[clinic input]
2957os.chflags
2958
2959 path: path_t
2960 flags: unsigned_long(bitwise=True)
2961 follow_symlinks: bool=True
2962
2963Set file flags.
2964
2965If follow_symlinks is False, and the last element of the path is a symbolic
2966 link, chflags will change flags on the symbolic link itself instead of the
2967 file the link points to.
2968follow_symlinks may not be implemented on your platform. If it is
2969unavailable, using it will raise a NotImplementedError.
2970
2971[clinic start generated code]*/
2972
Larry Hastings2f936352014-08-05 14:04:04 +10002973static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002974os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags,
2975 int follow_symlinks)
2976/*[clinic end generated code: output=ff2d6e73534a95b9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002977{
2978 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979
2980#ifndef HAVE_LCHFLAGS
2981 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002982 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002983#endif
2984
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986#ifdef HAVE_LCHFLAGS
2987 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002988 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989 else
2990#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002991 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002992 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002993
Larry Hastings2f936352014-08-05 14:04:04 +10002994 if (result)
2995 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002996
Larry Hastings2f936352014-08-05 14:04:04 +10002997 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002998}
2999#endif /* HAVE_CHFLAGS */
3000
Larry Hastings2f936352014-08-05 14:04:04 +10003001
Thomas Wouterscf297e42007-02-23 15:07:44 +00003002#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10003003/*[clinic input]
3004os.lchflags
3005
3006 path: path_t
3007 flags: unsigned_long(bitwise=True)
3008
3009Set file flags.
3010
3011This function will not follow symbolic links.
3012Equivalent to chflags(path, flags, follow_symlinks=False).
3013[clinic start generated code]*/
3014
Larry Hastings2f936352014-08-05 14:04:04 +10003015static PyObject *
3016os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003017/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003018{
Victor Stinner8c62be82010-05-06 00:08:46 +00003019 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003020 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003021 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003022 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003023 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003024 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003025 }
Victor Stinner292c8352012-10-30 02:17:38 +01003026 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003027}
3028#endif /* HAVE_LCHFLAGS */
3029
Larry Hastings2f936352014-08-05 14:04:04 +10003030
Martin v. Löwis244edc82001-10-04 22:44:26 +00003031#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003032/*[clinic input]
3033os.chroot
3034 path: path_t
3035
3036Change root directory to path.
3037
3038[clinic start generated code]*/
3039
Larry Hastings2f936352014-08-05 14:04:04 +10003040static PyObject *
3041os_chroot_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003042/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003043{
3044 int res;
3045 Py_BEGIN_ALLOW_THREADS
3046 res = chroot(path->narrow);
3047 Py_END_ALLOW_THREADS
3048 if (res < 0)
3049 return path_error(path);
3050 Py_RETURN_NONE;
3051}
3052#endif /* HAVE_CHROOT */
3053
Martin v. Löwis244edc82001-10-04 22:44:26 +00003054
Guido van Rossum21142a01999-01-08 21:05:37 +00003055#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003056/*[clinic input]
3057os.fsync
3058
3059 fd: fildes
3060
3061Force write of fd to disk.
3062[clinic start generated code]*/
3063
Larry Hastings2f936352014-08-05 14:04:04 +10003064static PyObject *
3065os_fsync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003066/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003067{
3068 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003069}
3070#endif /* HAVE_FSYNC */
3071
Larry Hastings2f936352014-08-05 14:04:04 +10003072
Ross Lagerwall7807c352011-03-17 20:20:30 +02003073#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003074/*[clinic input]
3075os.sync
3076
3077Force write of everything to disk.
3078[clinic start generated code]*/
3079
Larry Hastings2f936352014-08-05 14:04:04 +10003080static PyObject *
3081os_sync_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003082/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003083{
3084 Py_BEGIN_ALLOW_THREADS
3085 sync();
3086 Py_END_ALLOW_THREADS
3087 Py_RETURN_NONE;
3088}
Larry Hastings2f936352014-08-05 14:04:04 +10003089#endif /* HAVE_SYNC */
3090
Ross Lagerwall7807c352011-03-17 20:20:30 +02003091
Guido van Rossum21142a01999-01-08 21:05:37 +00003092#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003093#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003094extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3095#endif
3096
Larry Hastings2f936352014-08-05 14:04:04 +10003097/*[clinic input]
3098os.fdatasync
3099
3100 fd: fildes
3101
3102Force write of fd to disk without forcing update of metadata.
3103[clinic start generated code]*/
3104
Larry Hastings2f936352014-08-05 14:04:04 +10003105static PyObject *
3106os_fdatasync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003107/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003108{
3109 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003110}
3111#endif /* HAVE_FDATASYNC */
3112
3113
Fredrik Lundh10723342000-07-10 16:38:09 +00003114#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003115/*[clinic input]
3116os.chown
3117
3118 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3119 Path to be examined; can be string, bytes, or open-file-descriptor int.
3120
3121 uid: uid_t
3122
3123 gid: gid_t
3124
3125 *
3126
3127 dir_fd : dir_fd(requires='fchownat') = None
3128 If not None, it should be a file descriptor open to a directory,
3129 and path should be relative; path will then be relative to that
3130 directory.
3131
3132 follow_symlinks: bool = True
3133 If False, and the last element of the path is a symbolic link,
3134 stat will examine the symbolic link itself instead of the file
3135 the link points to.
3136
3137Change the owner and group id of path to the numeric uid and gid.\
3138
3139path may always be specified as a string.
3140On some platforms, path may also be specified as an open file descriptor.
3141 If this functionality is unavailable, using it raises an exception.
3142If dir_fd is not None, it should be a file descriptor open to a directory,
3143 and path should be relative; path will then be relative to that directory.
3144If follow_symlinks is False, and the last element of the path is a symbolic
3145 link, chown will modify the symbolic link itself instead of the file the
3146 link points to.
3147It is an error to use dir_fd or follow_symlinks when specifying path as
3148 an open file descriptor.
3149dir_fd and follow_symlinks may not be implemented on your platform.
3150 If they are unavailable, using them will raise a NotImplementedError.
3151
3152[clinic start generated code]*/
3153
Larry Hastings2f936352014-08-05 14:04:04 +10003154static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003155os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid,
3156 int dir_fd, int follow_symlinks)
3157/*[clinic end generated code: output=e0a4559f394dbd91 input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003158{
3159 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003160
3161#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3162 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003163 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003164#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003165 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3166 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3167 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003168
3169#ifdef __APPLE__
3170 /*
3171 * This is for Mac OS X 10.3, which doesn't have lchown.
3172 * (But we still have an lchown symbol because of weak-linking.)
3173 * It doesn't have fchownat either. So there's no possibility
3174 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003175 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003176 if ((!follow_symlinks) && (lchown == NULL)) {
3177 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003178 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179 }
3180#endif
3181
Victor Stinner8c62be82010-05-06 00:08:46 +00003182 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003183#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003184 if (path->fd != -1)
3185 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003186 else
3187#endif
3188#ifdef HAVE_LCHOWN
3189 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003190 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003191 else
3192#endif
3193#ifdef HAVE_FCHOWNAT
3194 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003195 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003196 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3197 else
3198#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003199 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003200 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003201
Larry Hastings2f936352014-08-05 14:04:04 +10003202 if (result)
3203 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003204
Larry Hastings2f936352014-08-05 14:04:04 +10003205 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003206}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003207#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003208
Larry Hastings2f936352014-08-05 14:04:04 +10003209
Christian Heimes4e30a842007-11-30 22:12:06 +00003210#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003211/*[clinic input]
3212os.fchown
3213
3214 fd: int
3215 uid: uid_t
3216 gid: gid_t
3217
3218Change the owner and group id of the file specified by file descriptor.
3219
3220Equivalent to os.chown(fd, uid, gid).
3221
3222[clinic start generated code]*/
3223
Larry Hastings2f936352014-08-05 14:04:04 +10003224static PyObject *
3225os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003226/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003227{
Victor Stinner8c62be82010-05-06 00:08:46 +00003228 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003229 int async_err = 0;
3230
3231 do {
3232 Py_BEGIN_ALLOW_THREADS
3233 res = fchown(fd, uid, gid);
3234 Py_END_ALLOW_THREADS
3235 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3236 if (res != 0)
3237 return (!async_err) ? posix_error() : NULL;
3238
Victor Stinner8c62be82010-05-06 00:08:46 +00003239 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003240}
3241#endif /* HAVE_FCHOWN */
3242
Larry Hastings2f936352014-08-05 14:04:04 +10003243
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003244#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003245/*[clinic input]
3246os.lchown
3247
3248 path : path_t
3249 uid: uid_t
3250 gid: gid_t
3251
3252Change the owner and group id of path to the numeric uid and gid.
3253
3254This function will not follow symbolic links.
3255Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3256[clinic start generated code]*/
3257
Larry Hastings2f936352014-08-05 14:04:04 +10003258static PyObject *
3259os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003260/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003261{
Victor Stinner8c62be82010-05-06 00:08:46 +00003262 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003263 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003264 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003265 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003266 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003267 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003268 }
Larry Hastings2f936352014-08-05 14:04:04 +10003269 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003270}
3271#endif /* HAVE_LCHOWN */
3272
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003273
Barry Warsaw53699e91996-12-10 23:23:01 +00003274static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003275posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003276{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003277 char *buf, *tmpbuf;
3278 char *cwd;
3279 const size_t chunk = 1024;
3280 size_t buflen = 0;
3281 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003282
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003283#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003285 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003286 wchar_t *wbuf2 = wbuf;
3287 PyObject *resobj;
3288 DWORD len;
3289 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003290 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003291 /* If the buffer is large enough, len does not include the
3292 terminating \0. If the buffer is too small, len includes
3293 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003294 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003295 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003296 if (wbuf2)
3297 len = GetCurrentDirectoryW(len, wbuf2);
3298 }
3299 Py_END_ALLOW_THREADS
3300 if (!wbuf2) {
3301 PyErr_NoMemory();
3302 return NULL;
3303 }
3304 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003305 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003306 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003307 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003308 }
3309 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003310 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003311 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003312 return resobj;
3313 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003314
3315 if (win32_warn_bytes_api())
3316 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003317#endif
3318
Victor Stinner4403d7d2015-04-25 00:16:10 +02003319 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003320 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003321 do {
3322 buflen += chunk;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003323#ifdef MS_WINDOWS
3324 if (buflen > INT_MAX) {
3325 PyErr_NoMemory();
3326 break;
3327 }
3328#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003329 tmpbuf = PyMem_RawRealloc(buf, buflen);
3330 if (tmpbuf == NULL)
3331 break;
3332
3333 buf = tmpbuf;
Victor Stinnerc44f7072016-03-14 18:07:53 +01003334#ifdef MS_WINDOWS
3335 cwd = getcwd(buf, (int)buflen);
3336#else
Victor Stinner4403d7d2015-04-25 00:16:10 +02003337 cwd = getcwd(buf, buflen);
Victor Stinnerc44f7072016-03-14 18:07:53 +01003338#endif
Victor Stinner4403d7d2015-04-25 00:16:10 +02003339 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003340 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003341
3342 if (cwd == NULL) {
3343 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003344 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003345 }
3346
Victor Stinner8c62be82010-05-06 00:08:46 +00003347 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003348 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3349 else
3350 obj = PyUnicode_DecodeFSDefault(buf);
3351 PyMem_RawFree(buf);
3352
3353 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003354}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003355
Larry Hastings2f936352014-08-05 14:04:04 +10003356
3357/*[clinic input]
3358os.getcwd
3359
3360Return a unicode string representing the current working directory.
3361[clinic start generated code]*/
3362
Larry Hastings2f936352014-08-05 14:04:04 +10003363static PyObject *
3364os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003365/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003366{
3367 return posix_getcwd(0);
3368}
3369
Larry Hastings2f936352014-08-05 14:04:04 +10003370
3371/*[clinic input]
3372os.getcwdb
3373
3374Return a bytes string representing the current working directory.
3375[clinic start generated code]*/
3376
Larry Hastings2f936352014-08-05 14:04:04 +10003377static PyObject *
3378os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003379/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003380{
3381 return posix_getcwd(1);
3382}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003383
Larry Hastings2f936352014-08-05 14:04:04 +10003384
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3386#define HAVE_LINK 1
3387#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003388
Guido van Rossumb6775db1994-08-01 11:34:53 +00003389#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003390/*[clinic input]
3391
3392os.link
3393
3394 src : path_t
3395 dst : path_t
3396 *
3397 src_dir_fd : dir_fd = None
3398 dst_dir_fd : dir_fd = None
3399 follow_symlinks: bool = True
3400
3401Create a hard link to a file.
3402
3403If either src_dir_fd or dst_dir_fd is not None, it should be a file
3404 descriptor open to a directory, and the respective path string (src or dst)
3405 should be relative; the path will then be relative to that directory.
3406If follow_symlinks is False, and the last element of src is a symbolic
3407 link, link will create a link to the symbolic link itself instead of the
3408 file the link points to.
3409src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3410 platform. If they are unavailable, using them will raise a
3411 NotImplementedError.
3412[clinic start generated code]*/
3413
Larry Hastings2f936352014-08-05 14:04:04 +10003414static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003415os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
3416 int dst_dir_fd, int follow_symlinks)
3417/*[clinic end generated code: output=f47a7e88f7b391b6 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003418{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419#ifdef MS_WINDOWS
3420 BOOL result;
3421#else
3422 int result;
3423#endif
3424
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425#ifndef HAVE_LINKAT
3426 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3427 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003428 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 }
3430#endif
3431
Larry Hastings2f936352014-08-05 14:04:04 +10003432 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003433 PyErr_SetString(PyExc_NotImplementedError,
3434 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003435 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003436 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003437
Brian Curtin1b9df392010-11-24 20:24:31 +00003438#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003440 if (src->wide)
3441 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003442 else
Larry Hastings2f936352014-08-05 14:04:04 +10003443 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003444 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003445
Larry Hastings2f936352014-08-05 14:04:04 +10003446 if (!result)
3447 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003448#else
3449 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003450#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3452 (dst_dir_fd != DEFAULT_DIR_FD) ||
3453 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003454 result = linkat(src_dir_fd, src->narrow,
3455 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003456 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3457 else
3458#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003459 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003460 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003461
Larry Hastings2f936352014-08-05 14:04:04 +10003462 if (result)
3463 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003464#endif
3465
Larry Hastings2f936352014-08-05 14:04:04 +10003466 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003467}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003468#endif
3469
Brian Curtin1b9df392010-11-24 20:24:31 +00003470
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003471#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003472static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003473_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003474{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003475 PyObject *v;
3476 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3477 BOOL result;
3478 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003479 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003481 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483
Gregory P. Smith40a21602013-03-20 20:52:50 -07003484 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003486 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003487
Gregory P. Smith40a21602013-03-20 20:52:50 -07003488 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003489 po_wchars = L".";
3490 len = 1;
3491 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003492 po_wchars = path->wide;
3493 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003494 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003495 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003496 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 if (!wnamebuf) {
3498 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003501 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003503 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003504 if (wch != SEP && wch != ALTSEP && wch != L':')
3505 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 wcscpy(wnamebuf + len, L"*.*");
3507 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003508 if ((list = PyList_New(0)) == NULL) {
3509 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003510 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003511 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003512 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003513 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 if (hFindFile == INVALID_HANDLE_VALUE) {
3515 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 if (error == ERROR_FILE_NOT_FOUND)
3517 goto exit;
3518 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003519 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 }
3522 do {
3523 /* Skip over . and .. */
3524 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3525 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003526 v = PyUnicode_FromWideChar(wFileData.cFileName,
3527 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003528 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003529 Py_DECREF(list);
3530 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003531 break;
3532 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003533 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003534 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003535 Py_DECREF(list);
3536 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003537 break;
3538 }
3539 Py_DECREF(v);
3540 }
3541 Py_BEGIN_ALLOW_THREADS
3542 result = FindNextFileW(hFindFile, &wFileData);
3543 Py_END_ALLOW_THREADS
3544 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3545 it got to the end of the directory. */
3546 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003548 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 }
3551 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003552
Larry Hastings9cf065c2012-06-22 16:30:09 -07003553 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003554 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003555 strcpy(namebuf, path->narrow);
3556 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003557 if (len > 0) {
3558 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003559 if (ch != '\\' && ch != '/' && ch != ':')
3560 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003561 strcpy(namebuf + len, "*.*");
3562 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003563
Larry Hastings9cf065c2012-06-22 16:30:09 -07003564 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003565 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003566
Antoine Pitroub73caab2010-08-09 23:39:31 +00003567 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003568 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003569 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 if (hFindFile == INVALID_HANDLE_VALUE) {
3571 int error = GetLastError();
3572 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 goto exit;
3574 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003575 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003576 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 }
3578 do {
3579 /* Skip over . and .. */
3580 if (strcmp(FileData.cFileName, ".") != 0 &&
3581 strcmp(FileData.cFileName, "..") != 0) {
3582 v = PyBytes_FromString(FileData.cFileName);
3583 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003584 Py_DECREF(list);
3585 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003586 break;
3587 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003588 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590 Py_DECREF(list);
3591 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003592 break;
3593 }
3594 Py_DECREF(v);
3595 }
3596 Py_BEGIN_ALLOW_THREADS
3597 result = FindNextFile(hFindFile, &FileData);
3598 Py_END_ALLOW_THREADS
3599 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3600 it got to the end of the directory. */
3601 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003605 }
3606 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003607
Larry Hastings9cf065c2012-06-22 16:30:09 -07003608exit:
3609 if (hFindFile != INVALID_HANDLE_VALUE) {
3610 if (FindClose(hFindFile) == FALSE) {
3611 if (list != NULL) {
3612 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003613 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003614 }
3615 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003616 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003617 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003618
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003620} /* end of _listdir_windows_no_opendir */
3621
3622#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3623
3624static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003625_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003626{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003627 PyObject *v;
3628 DIR *dirp = NULL;
3629 struct dirent *ep;
3630 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003631#ifdef HAVE_FDOPENDIR
3632 int fd = -1;
3633#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003634
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003636#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003637 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003638 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003639 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003640 if (fd == -1)
3641 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003642
Larry Hastingsfdaea062012-06-25 04:42:23 -07003643 return_str = 1;
3644
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 Py_BEGIN_ALLOW_THREADS
3646 dirp = fdopendir(fd);
3647 Py_END_ALLOW_THREADS
3648 }
3649 else
3650#endif
3651 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003652 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003653 if (path->narrow) {
3654 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003655 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003656 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003657 }
3658 else {
3659 name = ".";
3660 return_str = 1;
3661 }
3662
Larry Hastings9cf065c2012-06-22 16:30:09 -07003663 Py_BEGIN_ALLOW_THREADS
3664 dirp = opendir(name);
3665 Py_END_ALLOW_THREADS
3666 }
3667
3668 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003669 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003670#ifdef HAVE_FDOPENDIR
3671 if (fd != -1) {
3672 Py_BEGIN_ALLOW_THREADS
3673 close(fd);
3674 Py_END_ALLOW_THREADS
3675 }
3676#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 goto exit;
3678 }
3679 if ((list = PyList_New(0)) == NULL) {
3680 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003681 }
3682 for (;;) {
3683 errno = 0;
3684 Py_BEGIN_ALLOW_THREADS
3685 ep = readdir(dirp);
3686 Py_END_ALLOW_THREADS
3687 if (ep == NULL) {
3688 if (errno == 0) {
3689 break;
3690 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003692 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 }
3695 }
3696 if (ep->d_name[0] == '.' &&
3697 (NAMLEN(ep) == 1 ||
3698 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3699 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003700 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003701 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3702 else
3703 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003704 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003705 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003706 break;
3707 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003709 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003711 break;
3712 }
3713 Py_DECREF(v);
3714 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003715
Larry Hastings9cf065c2012-06-22 16:30:09 -07003716exit:
3717 if (dirp != NULL) {
3718 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003719#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003720 if (fd > -1)
3721 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003722#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003723 closedir(dirp);
3724 Py_END_ALLOW_THREADS
3725 }
3726
Larry Hastings9cf065c2012-06-22 16:30:09 -07003727 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003728} /* end of _posix_listdir */
3729#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003730
Larry Hastings2f936352014-08-05 14:04:04 +10003731
3732/*[clinic input]
3733os.listdir
3734
3735 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3736
3737Return a list containing the names of the files in the directory.
3738
3739path can be specified as either str or bytes. If path is bytes,
3740 the filenames returned will also be bytes; in all other circumstances
3741 the filenames returned will be str.
3742If path is None, uses the path='.'.
3743On some platforms, path may also be specified as an open file descriptor;\
3744 the file descriptor must refer to a directory.
3745 If this functionality is unavailable, using it raises NotImplementedError.
3746
3747The list is in arbitrary order. It does not include the special
3748entries '.' and '..' even if they are present in the directory.
3749
3750
3751[clinic start generated code]*/
3752
Larry Hastings2f936352014-08-05 14:04:04 +10003753static PyObject *
3754os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003755/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003756{
3757#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3758 return _listdir_windows_no_opendir(path, NULL);
3759#else
3760 return _posix_listdir(path, NULL);
3761#endif
3762}
3763
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003764#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003765/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003766/*[clinic input]
3767os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003768
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003769 path: path_t
3770 /
3771
3772[clinic start generated code]*/
3773
3774static PyObject *
3775os__getfullpathname_impl(PyModuleDef *module, path_t *path)
3776/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/
3777{
3778 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003779 {
Victor Stinner75875072013-11-24 19:23:25 +01003780 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003781 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003782 DWORD result;
3783 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003784
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003785 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003786 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003787 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003788 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003789 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 if (!woutbufp)
3791 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003792 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003793 }
3794 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003795 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003796 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003797 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003798 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003799 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003800 return v;
3801 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003802 else {
3803 char outbuf[MAX_PATH];
3804 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003805
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003806 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3807 outbuf, &temp)) {
3808 win32_error_object("GetFullPathName", path->object);
3809 return NULL;
3810 }
3811 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003812 }
Larry Hastings2f936352014-08-05 14:04:04 +10003813}
Brian Curtind40e6f72010-07-08 21:39:08 +00003814
Brian Curtind25aef52011-06-13 15:16:04 -05003815
Larry Hastings2f936352014-08-05 14:04:04 +10003816/*[clinic input]
3817os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003818
Larry Hastings2f936352014-08-05 14:04:04 +10003819 path: unicode
3820 /
3821
3822A helper function for samepath on windows.
3823[clinic start generated code]*/
3824
Larry Hastings2f936352014-08-05 14:04:04 +10003825static PyObject *
3826os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003827/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003828{
3829 HANDLE hFile;
3830 int buf_size;
3831 wchar_t *target_path;
3832 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003833 PyObject *result;
3834 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003835
Larry Hastings2f936352014-08-05 14:04:04 +10003836 path_wchar = PyUnicode_AsUnicode(path);
3837 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003838 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003839
Brian Curtind40e6f72010-07-08 21:39:08 +00003840 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003841 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003842 0, /* desired access */
3843 0, /* share mode */
3844 NULL, /* security attributes */
3845 OPEN_EXISTING,
3846 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3847 FILE_FLAG_BACKUP_SEMANTICS,
3848 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003849
Victor Stinnereb5657a2011-09-30 01:44:27 +02003850 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003851 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003852
3853 /* We have a good handle to the target, use it to determine the
3854 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003855 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856
3857 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003858 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003859
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003860 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003861 if(!target_path)
3862 return PyErr_NoMemory();
3863
Steve Dower2ea51c92015-03-20 21:49:12 -07003864 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3865 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003866 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003867 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003868
3869 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003870 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003871
3872 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003873 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003874 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003875 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003876}
Brian Curtin62857742010-09-06 17:07:27 +00003877
Brian Curtin95d028f2011-06-09 09:10:38 -05003878PyDoc_STRVAR(posix__isdir__doc__,
3879"Return true if the pathname refers to an existing directory.");
3880
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003881/*[clinic input]
3882os._isdir
3883
3884 path: path_t
3885 /
3886
3887[clinic start generated code]*/
3888
Brian Curtin9c669cc2011-06-08 18:17:18 -05003889static PyObject *
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003890os__isdir_impl(PyModuleDef *module, path_t *path)
3891/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003892{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003893 DWORD attributes;
3894
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003895 if (!path->narrow)
3896 attributes = GetFileAttributesW(path->wide);
3897 else
3898 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003899
Brian Curtin9c669cc2011-06-08 18:17:18 -05003900 if (attributes == INVALID_FILE_ATTRIBUTES)
3901 Py_RETURN_FALSE;
3902
Brian Curtin9c669cc2011-06-08 18:17:18 -05003903 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3904 Py_RETURN_TRUE;
3905 else
3906 Py_RETURN_FALSE;
3907}
Tim Golden6b528062013-08-01 12:44:00 +01003908
Tim Golden6b528062013-08-01 12:44:00 +01003909
Larry Hastings2f936352014-08-05 14:04:04 +10003910/*[clinic input]
3911os._getvolumepathname
3912
3913 path: unicode
3914
3915A helper function for ismount on Win32.
3916[clinic start generated code]*/
3917
Larry Hastings2f936352014-08-05 14:04:04 +10003918static PyObject *
3919os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003920/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003921{
3922 PyObject *result;
3923 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003924 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003925 BOOL ret;
3926
Larry Hastings2f936352014-08-05 14:04:04 +10003927 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3928 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003929 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003930 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003931
3932 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003933 buflen = Py_MAX(buflen, MAX_PATH);
3934
3935 if (buflen > DWORD_MAX) {
3936 PyErr_SetString(PyExc_OverflowError, "path too long");
3937 return NULL;
3938 }
3939
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003940 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003941 if (mountpath == NULL)
3942 return PyErr_NoMemory();
3943
3944 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003945 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003946 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003947 Py_END_ALLOW_THREADS
3948
3949 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003950 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003951 goto exit;
3952 }
3953 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3954
3955exit:
3956 PyMem_Free(mountpath);
3957 return result;
3958}
Tim Golden6b528062013-08-01 12:44:00 +01003959
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003960#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003961
Larry Hastings2f936352014-08-05 14:04:04 +10003962
3963/*[clinic input]
3964os.mkdir
3965
3966 path : path_t
3967
3968 mode: int = 0o777
3969
3970 *
3971
3972 dir_fd : dir_fd(requires='mkdirat') = None
3973
3974# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3975
3976Create a directory.
3977
3978If dir_fd is not None, it should be a file descriptor open to a directory,
3979 and path should be relative; path will then be relative to that directory.
3980dir_fd may not be implemented on your platform.
3981 If it is unavailable, using it will raise a NotImplementedError.
3982
3983The mode argument is ignored on Windows.
3984[clinic start generated code]*/
3985
Larry Hastings2f936352014-08-05 14:04:04 +10003986static PyObject *
3987os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003988/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003989{
3990 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003991
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003992#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003993 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003994 if (path->wide)
3995 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003996 else
Larry Hastings2f936352014-08-05 14:04:04 +10003997 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003998 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003999
Larry Hastings2f936352014-08-05 14:04:04 +10004000 if (!result)
4001 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004002#else
Victor Stinner8c62be82010-05-06 00:08:46 +00004003 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004004#if HAVE_MKDIRAT
4005 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004006 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004007 else
4008#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00004009#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004010 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004011#else
Larry Hastings2f936352014-08-05 14:04:04 +10004012 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004013#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004014 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004015 if (result < 0)
4016 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004017#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004018 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004019}
4020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004021
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004022/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4023#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004024#include <sys/resource.h>
4025#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004026
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004027
4028#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004029/*[clinic input]
4030os.nice
4031
4032 increment: int
4033 /
4034
4035Add increment to the priority of process and return the new priority.
4036[clinic start generated code]*/
4037
Larry Hastings2f936352014-08-05 14:04:04 +10004038static PyObject *
4039os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004040/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004041{
4042 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004043
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 /* There are two flavours of 'nice': one that returns the new
4045 priority (as required by almost all standards out there) and the
4046 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4047 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004048
Victor Stinner8c62be82010-05-06 00:08:46 +00004049 If we are of the nice family that returns the new priority, we
4050 need to clear errno before the call, and check if errno is filled
4051 before calling posix_error() on a returnvalue of -1, because the
4052 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004053
Victor Stinner8c62be82010-05-06 00:08:46 +00004054 errno = 0;
4055 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004056#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004057 if (value == 0)
4058 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004059#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004060 if (value == -1 && errno != 0)
4061 /* either nice() or getpriority() returned an error */
4062 return posix_error();
4063 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004064}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004065#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004066
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004067
4068#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004069/*[clinic input]
4070os.getpriority
4071
4072 which: int
4073 who: int
4074
4075Return program scheduling priority.
4076[clinic start generated code]*/
4077
Larry Hastings2f936352014-08-05 14:04:04 +10004078static PyObject *
4079os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004080/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004081{
4082 int retval;
4083
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004084 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004085 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004086 if (errno != 0)
4087 return posix_error();
4088 return PyLong_FromLong((long)retval);
4089}
4090#endif /* HAVE_GETPRIORITY */
4091
4092
4093#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004094/*[clinic input]
4095os.setpriority
4096
4097 which: int
4098 who: int
4099 priority: int
4100
4101Set program scheduling priority.
4102[clinic start generated code]*/
4103
Larry Hastings2f936352014-08-05 14:04:04 +10004104static PyObject *
4105os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004106/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004107{
4108 int retval;
4109
4110 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004111 if (retval == -1)
4112 return posix_error();
4113 Py_RETURN_NONE;
4114}
4115#endif /* HAVE_SETPRIORITY */
4116
4117
Barry Warsaw53699e91996-12-10 23:23:01 +00004118static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004119internal_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 +00004120{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004123
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004124#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004125 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004126 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004127#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004129#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004130
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4132 (dst_dir_fd != DEFAULT_DIR_FD);
4133#ifndef HAVE_RENAMEAT
4134 if (dir_fd_specified) {
4135 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004136 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004137 }
4138#endif
4139
Larry Hastings2f936352014-08-05 14:04:04 +10004140 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141 PyErr_Format(PyExc_ValueError,
4142 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004143 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144 }
4145
4146#ifdef MS_WINDOWS
4147 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004148 if (src->wide)
4149 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 else
Larry Hastings2f936352014-08-05 14:04:04 +10004151 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152 Py_END_ALLOW_THREADS
4153
Larry Hastings2f936352014-08-05 14:04:04 +10004154 if (!result)
4155 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004156
4157#else
4158 Py_BEGIN_ALLOW_THREADS
4159#ifdef HAVE_RENAMEAT
4160 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004161 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162 else
4163#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004164 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004165 Py_END_ALLOW_THREADS
4166
Larry Hastings2f936352014-08-05 14:04:04 +10004167 if (result)
4168 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004169#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004170 Py_RETURN_NONE;
4171}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004172
Larry Hastings2f936352014-08-05 14:04:04 +10004173
4174/*[clinic input]
4175os.rename
4176
4177 src : path_t
4178 dst : path_t
4179 *
4180 src_dir_fd : dir_fd = None
4181 dst_dir_fd : dir_fd = None
4182
4183Rename a file or directory.
4184
4185If either src_dir_fd or dst_dir_fd is not None, it should be a file
4186 descriptor open to a directory, and the respective path string (src or dst)
4187 should be relative; the path will then be relative to that directory.
4188src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4189 If they are unavailable, using them will raise a NotImplementedError.
4190[clinic start generated code]*/
4191
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004192static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004193os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
4194 int dst_dir_fd)
4195/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004196{
Larry Hastings2f936352014-08-05 14:04:04 +10004197 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004198}
4199
Larry Hastings2f936352014-08-05 14:04:04 +10004200
4201/*[clinic input]
4202os.replace = os.rename
4203
4204Rename a file or directory, overwriting the destination.
4205
4206If either src_dir_fd or dst_dir_fd is not None, it should be a file
4207 descriptor open to a directory, and the respective path string (src or dst)
4208 should be relative; the path will then be relative to that directory.
4209src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4210 If they are unavailable, using them will raise a NotImplementedError."
4211[clinic start generated code]*/
4212
Larry Hastings2f936352014-08-05 14:04:04 +10004213static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004214os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst,
4215 int src_dir_fd, int dst_dir_fd)
4216/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004217{
4218 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4219}
4220
4221
4222/*[clinic input]
4223os.rmdir
4224
4225 path: path_t
4226 *
4227 dir_fd: dir_fd(requires='unlinkat') = None
4228
4229Remove a directory.
4230
4231If dir_fd is not None, it should be a file descriptor open to a directory,
4232 and path should be relative; path will then be relative to that directory.
4233dir_fd may not be implemented on your platform.
4234 If it is unavailable, using it will raise a NotImplementedError.
4235[clinic start generated code]*/
4236
Larry Hastings2f936352014-08-05 14:04:04 +10004237static PyObject *
4238os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004239/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004240{
4241 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004242
4243 Py_BEGIN_ALLOW_THREADS
4244#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004245 if (path->wide)
4246 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247 else
Larry Hastings2f936352014-08-05 14:04:04 +10004248 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004249 result = !result; /* Windows, success=1, UNIX, success=0 */
4250#else
4251#ifdef HAVE_UNLINKAT
4252 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004253 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004254 else
4255#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004256 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004257#endif
4258 Py_END_ALLOW_THREADS
4259
Larry Hastings2f936352014-08-05 14:04:04 +10004260 if (result)
4261 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004262
Larry Hastings2f936352014-08-05 14:04:04 +10004263 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004264}
4265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004266
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004267#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004268#ifdef MS_WINDOWS
4269/*[clinic input]
4270os.system -> long
4271
4272 command: Py_UNICODE
4273
4274Execute the command in a subshell.
4275[clinic start generated code]*/
4276
Larry Hastings2f936352014-08-05 14:04:04 +10004277static long
4278os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004279/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004280{
4281 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004282 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004283 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004284 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004285 return result;
4286}
4287#else /* MS_WINDOWS */
4288/*[clinic input]
4289os.system -> long
4290
4291 command: FSConverter
4292
4293Execute the command in a subshell.
4294[clinic start generated code]*/
4295
Larry Hastings2f936352014-08-05 14:04:04 +10004296static long
4297os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004298/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004299{
4300 long result;
4301 char *bytes = PyBytes_AsString(command);
4302 Py_BEGIN_ALLOW_THREADS
4303 result = system(bytes);
4304 Py_END_ALLOW_THREADS
4305 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004306}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004307#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004308#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004309
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004310
Larry Hastings2f936352014-08-05 14:04:04 +10004311/*[clinic input]
4312os.umask
4313
4314 mask: int
4315 /
4316
4317Set the current numeric umask and return the previous umask.
4318[clinic start generated code]*/
4319
Larry Hastings2f936352014-08-05 14:04:04 +10004320static PyObject *
4321os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004322/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004323{
4324 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004325 if (i < 0)
4326 return posix_error();
4327 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004328}
4329
Brian Curtind40e6f72010-07-08 21:39:08 +00004330#ifdef MS_WINDOWS
4331
4332/* override the default DeleteFileW behavior so that directory
4333symlinks can be removed with this function, the same as with
4334Unix symlinks */
4335BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4336{
4337 WIN32_FILE_ATTRIBUTE_DATA info;
4338 WIN32_FIND_DATAW find_data;
4339 HANDLE find_data_handle;
4340 int is_directory = 0;
4341 int is_link = 0;
4342
4343 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4344 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004345
Brian Curtind40e6f72010-07-08 21:39:08 +00004346 /* Get WIN32_FIND_DATA structure for the path to determine if
4347 it is a symlink */
4348 if(is_directory &&
4349 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4350 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4351
4352 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004353 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4354 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4355 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4356 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004357 FindClose(find_data_handle);
4358 }
4359 }
4360 }
4361
4362 if (is_directory && is_link)
4363 return RemoveDirectoryW(lpFileName);
4364
4365 return DeleteFileW(lpFileName);
4366}
4367#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004368
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004369
Larry Hastings2f936352014-08-05 14:04:04 +10004370/*[clinic input]
4371os.unlink
4372
4373 path: path_t
4374 *
4375 dir_fd: dir_fd(requires='unlinkat')=None
4376
4377Remove a file (same as remove()).
4378
4379If dir_fd is not None, it should be a file descriptor open to a directory,
4380 and path should be relative; path will then be relative to that directory.
4381dir_fd may not be implemented on your platform.
4382 If it is unavailable, using it will raise a NotImplementedError.
4383
4384[clinic start generated code]*/
4385
Larry Hastings2f936352014-08-05 14:04:04 +10004386static PyObject *
4387os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004388/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004389{
4390 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391
4392 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004393 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004395 if (path->wide)
4396 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004397 else
Larry Hastings2f936352014-08-05 14:04:04 +10004398 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399 result = !result; /* Windows, success=1, UNIX, success=0 */
4400#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004401#ifdef HAVE_UNLINKAT
4402 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004403 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004404 else
4405#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004406 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004407#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004408 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004409 Py_END_ALLOW_THREADS
4410
Larry Hastings2f936352014-08-05 14:04:04 +10004411 if (result)
4412 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004413
Larry Hastings2f936352014-08-05 14:04:04 +10004414 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004415}
4416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004417
Larry Hastings2f936352014-08-05 14:04:04 +10004418/*[clinic input]
4419os.remove = os.unlink
4420
4421Remove a file (same as unlink()).
4422
4423If dir_fd is not None, it should be a file descriptor open to a directory,
4424 and path should be relative; path will then be relative to that directory.
4425dir_fd may not be implemented on your platform.
4426 If it is unavailable, using it will raise a NotImplementedError.
4427[clinic start generated code]*/
4428
Larry Hastings2f936352014-08-05 14:04:04 +10004429static PyObject *
4430os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004431/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004432{
4433 return os_unlink_impl(module, path, dir_fd);
4434}
4435
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004436
Larry Hastings605a62d2012-06-24 04:33:36 -07004437static PyStructSequence_Field uname_result_fields[] = {
4438 {"sysname", "operating system name"},
4439 {"nodename", "name of machine on network (implementation-defined)"},
4440 {"release", "operating system release"},
4441 {"version", "operating system version"},
4442 {"machine", "hardware identifier"},
4443 {NULL}
4444};
4445
4446PyDoc_STRVAR(uname_result__doc__,
4447"uname_result: Result from os.uname().\n\n\
4448This object may be accessed either as a tuple of\n\
4449 (sysname, nodename, release, version, machine),\n\
4450or via the attributes sysname, nodename, release, version, and machine.\n\
4451\n\
4452See os.uname for more information.");
4453
4454static PyStructSequence_Desc uname_result_desc = {
4455 "uname_result", /* name */
4456 uname_result__doc__, /* doc */
4457 uname_result_fields,
4458 5
4459};
4460
4461static PyTypeObject UnameResultType;
4462
4463
4464#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004465/*[clinic input]
4466os.uname
4467
4468Return an object identifying the current operating system.
4469
4470The object behaves like a named tuple with the following fields:
4471 (sysname, nodename, release, version, machine)
4472
4473[clinic start generated code]*/
4474
Larry Hastings2f936352014-08-05 14:04:04 +10004475static PyObject *
4476os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004477/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004478{
Victor Stinner8c62be82010-05-06 00:08:46 +00004479 struct utsname u;
4480 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004481 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004482
Victor Stinner8c62be82010-05-06 00:08:46 +00004483 Py_BEGIN_ALLOW_THREADS
4484 res = uname(&u);
4485 Py_END_ALLOW_THREADS
4486 if (res < 0)
4487 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004488
4489 value = PyStructSequence_New(&UnameResultType);
4490 if (value == NULL)
4491 return NULL;
4492
4493#define SET(i, field) \
4494 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004495 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004496 if (!o) { \
4497 Py_DECREF(value); \
4498 return NULL; \
4499 } \
4500 PyStructSequence_SET_ITEM(value, i, o); \
4501 } \
4502
4503 SET(0, u.sysname);
4504 SET(1, u.nodename);
4505 SET(2, u.release);
4506 SET(3, u.version);
4507 SET(4, u.machine);
4508
4509#undef SET
4510
4511 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004512}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004513#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004514
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004515
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516
4517typedef struct {
4518 int now;
4519 time_t atime_s;
4520 long atime_ns;
4521 time_t mtime_s;
4522 long mtime_ns;
4523} utime_t;
4524
4525/*
Victor Stinner484df002014-10-09 13:52:31 +02004526 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 * they also intentionally leak the declaration of a pointer named "time"
4528 */
4529#define UTIME_TO_TIMESPEC \
4530 struct timespec ts[2]; \
4531 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004532 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004533 time = NULL; \
4534 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004535 ts[0].tv_sec = ut->atime_s; \
4536 ts[0].tv_nsec = ut->atime_ns; \
4537 ts[1].tv_sec = ut->mtime_s; \
4538 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004539 time = ts; \
4540 } \
4541
4542#define UTIME_TO_TIMEVAL \
4543 struct timeval tv[2]; \
4544 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004545 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004546 time = NULL; \
4547 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004548 tv[0].tv_sec = ut->atime_s; \
4549 tv[0].tv_usec = ut->atime_ns / 1000; \
4550 tv[1].tv_sec = ut->mtime_s; \
4551 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004552 time = tv; \
4553 } \
4554
4555#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004556 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004557 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004558 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004559 time = NULL; \
4560 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004561 u.actime = ut->atime_s; \
4562 u.modtime = ut->mtime_s; \
4563 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564 }
4565
4566#define UTIME_TO_TIME_T \
4567 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004568 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004569 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004570 time = NULL; \
4571 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004572 timet[0] = ut->atime_s; \
4573 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004574 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004575 } \
4576
4577
Victor Stinner528a9ab2015-09-03 21:30:26 +02004578#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004579
4580static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004581utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582{
4583#ifdef HAVE_UTIMENSAT
4584 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4585 UTIME_TO_TIMESPEC;
4586 return utimensat(dir_fd, path, time, flags);
4587#elif defined(HAVE_FUTIMESAT)
4588 UTIME_TO_TIMEVAL;
4589 /*
4590 * follow_symlinks will never be false here;
4591 * we only allow !follow_symlinks and dir_fd together
4592 * if we have utimensat()
4593 */
4594 assert(follow_symlinks);
4595 return futimesat(dir_fd, path, time);
4596#endif
4597}
4598
Larry Hastings2f936352014-08-05 14:04:04 +10004599 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4600#else
4601 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004602#endif
4603
Victor Stinner528a9ab2015-09-03 21:30:26 +02004604#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605
4606static int
Victor Stinner484df002014-10-09 13:52:31 +02004607utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004608{
4609#ifdef HAVE_FUTIMENS
4610 UTIME_TO_TIMESPEC;
4611 return futimens(fd, time);
4612#else
4613 UTIME_TO_TIMEVAL;
4614 return futimes(fd, time);
4615#endif
4616}
4617
Larry Hastings2f936352014-08-05 14:04:04 +10004618 #define PATH_UTIME_HAVE_FD 1
4619#else
4620 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621#endif
4622
Victor Stinner5ebae872015-09-22 01:29:33 +02004623#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4624# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4625#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004626
Victor Stinner4552ced2015-09-21 22:37:15 +02004627#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004628
4629static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004630utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004631{
4632#ifdef HAVE_UTIMENSAT
4633 UTIME_TO_TIMESPEC;
4634 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4635#else
4636 UTIME_TO_TIMEVAL;
4637 return lutimes(path, time);
4638#endif
4639}
4640
4641#endif
4642
4643#ifndef MS_WINDOWS
4644
4645static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004646utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004647{
4648#ifdef HAVE_UTIMENSAT
4649 UTIME_TO_TIMESPEC;
4650 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4651#elif defined(HAVE_UTIMES)
4652 UTIME_TO_TIMEVAL;
4653 return utimes(path, time);
4654#elif defined(HAVE_UTIME_H)
4655 UTIME_TO_UTIMBUF;
4656 return utime(path, time);
4657#else
4658 UTIME_TO_TIME_T;
4659 return utime(path, time);
4660#endif
4661}
4662
4663#endif
4664
Larry Hastings76ad59b2012-05-03 00:30:07 -07004665static int
4666split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4667{
4668 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004669 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004670 divmod = PyNumber_Divmod(py_long, billion);
4671 if (!divmod)
4672 goto exit;
4673 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4674 if ((*s == -1) && PyErr_Occurred())
4675 goto exit;
4676 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004677 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004678 goto exit;
4679
4680 result = 1;
4681exit:
4682 Py_XDECREF(divmod);
4683 return result;
4684}
4685
Larry Hastings2f936352014-08-05 14:04:04 +10004686
4687/*[clinic input]
4688os.utime
4689
4690 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4691 times: object = NULL
4692 *
4693 ns: object = NULL
4694 dir_fd: dir_fd(requires='futimensat') = None
4695 follow_symlinks: bool=True
4696
Martin Panter0ff89092015-09-09 01:56:53 +00004697# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004698
4699Set the access and modified time of path.
4700
4701path may always be specified as a string.
4702On some platforms, path may also be specified as an open file descriptor.
4703 If this functionality is unavailable, using it raises an exception.
4704
4705If times is not None, it must be a tuple (atime, mtime);
4706 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004707If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004708 atime_ns and mtime_ns should be expressed as integer nanoseconds
4709 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004710If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004711Specifying tuples for both times and ns is an error.
4712
4713If dir_fd is not None, it should be a file descriptor open to a directory,
4714 and path should be relative; path will then be relative to that directory.
4715If follow_symlinks is False, and the last element of the path is a symbolic
4716 link, utime will modify the symbolic link itself instead of the file the
4717 link points to.
4718It is an error to use dir_fd or follow_symlinks when specifying path
4719 as an open file descriptor.
4720dir_fd and follow_symlinks may not be available on your platform.
4721 If they are unavailable, using them will raise a NotImplementedError.
4722
4723[clinic start generated code]*/
4724
Larry Hastings2f936352014-08-05 14:04:04 +10004725static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004726os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times,
4727 PyObject *ns, int dir_fd, int follow_symlinks)
Martin Panter0ff89092015-09-09 01:56:53 +00004728/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004729{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004730#ifdef MS_WINDOWS
4731 HANDLE hFile;
4732 FILETIME atime, mtime;
4733#else
4734 int result;
4735#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004736
Larry Hastings9cf065c2012-06-22 16:30:09 -07004737 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004738 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004739
Christian Heimesb3c87242013-08-01 00:08:16 +02004740 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004741
Larry Hastings9cf065c2012-06-22 16:30:09 -07004742 if (times && (times != Py_None) && ns) {
4743 PyErr_SetString(PyExc_ValueError,
4744 "utime: you may specify either 'times'"
4745 " or 'ns' but not both");
4746 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004747 }
4748
4749 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004750 time_t a_sec, m_sec;
4751 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 PyErr_SetString(PyExc_TypeError,
4754 "utime: 'times' must be either"
4755 " a tuple of two ints or None");
4756 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004757 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004758 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004759 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004760 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004761 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004762 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004764 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004765 utime.atime_s = a_sec;
4766 utime.atime_ns = a_nsec;
4767 utime.mtime_s = m_sec;
4768 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004769 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004771 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772 PyErr_SetString(PyExc_TypeError,
4773 "utime: 'ns' must be a tuple of two ints");
4774 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004775 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004776 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004777 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004778 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004779 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 &utime.mtime_s, &utime.mtime_ns)) {
4781 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004782 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004783 }
4784 else {
4785 /* times and ns are both None/unspecified. use "now". */
4786 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004787 }
4788
Victor Stinner4552ced2015-09-21 22:37:15 +02004789#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004790 if (follow_symlinks_specified("utime", follow_symlinks))
4791 goto exit;
4792#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004793
Larry Hastings2f936352014-08-05 14:04:04 +10004794 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4795 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4796 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004797 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004798
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799#if !defined(HAVE_UTIMENSAT)
4800 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004801 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004802 "utime: cannot use dir_fd and follow_symlinks "
4803 "together on this platform");
4804 goto exit;
4805 }
4806#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004807
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004808#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004810 if (path->wide)
4811 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 NULL, OPEN_EXISTING,
4813 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814 else
Larry Hastings2f936352014-08-05 14:04:04 +10004815 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 NULL, OPEN_EXISTING,
4817 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004818 Py_END_ALLOW_THREADS
4819 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004820 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004822 }
4823
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004825 GetSystemTimeAsFileTime(&mtime);
4826 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004827 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004828 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004829 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4830 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004831 }
4832 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4833 /* Avoid putting the file name into the error here,
4834 as that may confuse the user into believing that
4835 something is wrong with the file, when it also
4836 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004837 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004839 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004840#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004841 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004842
Victor Stinner4552ced2015-09-21 22:37:15 +02004843#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004844 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004845 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004846 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004847#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848
Victor Stinner528a9ab2015-09-03 21:30:26 +02004849#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004850 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004851 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852 else
4853#endif
4854
Victor Stinner528a9ab2015-09-03 21:30:26 +02004855#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004856 if (path->fd != -1)
4857 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004858 else
4859#endif
4860
Larry Hastings2f936352014-08-05 14:04:04 +10004861 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862
4863 Py_END_ALLOW_THREADS
4864
4865 if (result < 0) {
4866 /* see previous comment about not putting filename in error here */
4867 return_value = posix_error();
4868 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004869 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004870
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004871#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004872
4873 Py_INCREF(Py_None);
4874 return_value = Py_None;
4875
4876exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004877#ifdef MS_WINDOWS
4878 if (hFile != INVALID_HANDLE_VALUE)
4879 CloseHandle(hFile);
4880#endif
4881 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004882}
4883
Guido van Rossum3b066191991-06-04 19:40:25 +00004884/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004885
Larry Hastings2f936352014-08-05 14:04:04 +10004886
4887/*[clinic input]
4888os._exit
4889
4890 status: int
4891
4892Exit to the system with specified status, without normal exit processing.
4893[clinic start generated code]*/
4894
Larry Hastings2f936352014-08-05 14:04:04 +10004895static PyObject *
4896os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004897/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004898{
4899 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004900 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004901}
4902
Martin v. Löwis114619e2002-10-07 06:44:21 +00004903#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4904static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004905free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004906{
Victor Stinner8c62be82010-05-06 00:08:46 +00004907 Py_ssize_t i;
4908 for (i = 0; i < count; i++)
4909 PyMem_Free(array[i]);
4910 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004911}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004912
Antoine Pitrou69f71142009-05-24 21:25:49 +00004913static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004914int fsconvert_strdup(PyObject *o, char**out)
4915{
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 PyObject *bytes;
4917 Py_ssize_t size;
4918 if (!PyUnicode_FSConverter(o, &bytes))
4919 return 0;
4920 size = PyBytes_GET_SIZE(bytes);
4921 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004922 if (!*out) {
4923 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004924 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004925 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 memcpy(*out, PyBytes_AsString(bytes), size+1);
4927 Py_DECREF(bytes);
4928 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004929}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004930#endif
4931
Ross Lagerwall7807c352011-03-17 20:20:30 +02004932#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004933static char**
4934parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4935{
Victor Stinner8c62be82010-05-06 00:08:46 +00004936 char **envlist;
4937 Py_ssize_t i, pos, envc;
4938 PyObject *keys=NULL, *vals=NULL;
4939 PyObject *key, *val, *key2, *val2;
4940 char *p, *k, *v;
4941 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004942
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 i = PyMapping_Size(env);
4944 if (i < 0)
4945 return NULL;
4946 envlist = PyMem_NEW(char *, i + 1);
4947 if (envlist == NULL) {
4948 PyErr_NoMemory();
4949 return NULL;
4950 }
4951 envc = 0;
4952 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004953 if (!keys)
4954 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004956 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004957 goto error;
4958 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4959 PyErr_Format(PyExc_TypeError,
4960 "env.keys() or env.values() is not a list");
4961 goto error;
4962 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004963
Victor Stinner8c62be82010-05-06 00:08:46 +00004964 for (pos = 0; pos < i; pos++) {
4965 key = PyList_GetItem(keys, pos);
4966 val = PyList_GetItem(vals, pos);
4967 if (!key || !val)
4968 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004969
Victor Stinner8c62be82010-05-06 00:08:46 +00004970 if (PyUnicode_FSConverter(key, &key2) == 0)
4971 goto error;
4972 if (PyUnicode_FSConverter(val, &val2) == 0) {
4973 Py_DECREF(key2);
4974 goto error;
4975 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004976
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 k = PyBytes_AsString(key2);
4978 v = PyBytes_AsString(val2);
4979 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 p = PyMem_NEW(char, len);
4982 if (p == NULL) {
4983 PyErr_NoMemory();
4984 Py_DECREF(key2);
4985 Py_DECREF(val2);
4986 goto error;
4987 }
4988 PyOS_snprintf(p, len, "%s=%s", k, v);
4989 envlist[envc++] = p;
4990 Py_DECREF(key2);
4991 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004992 }
4993 Py_DECREF(vals);
4994 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004995
Victor Stinner8c62be82010-05-06 00:08:46 +00004996 envlist[envc] = 0;
4997 *envc_ptr = envc;
4998 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004999
5000error:
Victor Stinner8c62be82010-05-06 00:08:46 +00005001 Py_XDECREF(keys);
5002 Py_XDECREF(vals);
5003 while (--envc >= 0)
5004 PyMem_DEL(envlist[envc]);
5005 PyMem_DEL(envlist);
5006 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00005007}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005008
Ross Lagerwall7807c352011-03-17 20:20:30 +02005009static char**
5010parse_arglist(PyObject* argv, Py_ssize_t *argc)
5011{
5012 int i;
5013 char **argvlist = PyMem_NEW(char *, *argc+1);
5014 if (argvlist == NULL) {
5015 PyErr_NoMemory();
5016 return NULL;
5017 }
5018 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005019 PyObject* item = PySequence_ITEM(argv, i);
5020 if (item == NULL)
5021 goto fail;
5022 if (!fsconvert_strdup(item, &argvlist[i])) {
5023 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005024 goto fail;
5025 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005026 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005027 }
5028 argvlist[*argc] = NULL;
5029 return argvlist;
5030fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005031 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005032 free_string_array(argvlist, *argc);
5033 return NULL;
5034}
5035#endif
5036
Larry Hastings2f936352014-08-05 14:04:04 +10005037
Ross Lagerwall7807c352011-03-17 20:20:30 +02005038#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005039/*[clinic input]
5040os.execv
5041
5042 path: FSConverter
5043 Path of executable file.
5044 argv: object
5045 Tuple or list of strings.
5046 /
5047
5048Execute an executable path with arguments, replacing current process.
5049[clinic start generated code]*/
5050
Larry Hastings2f936352014-08-05 14:04:04 +10005051static PyObject *
5052os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005053/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005054{
5055 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 char **argvlist;
5057 Py_ssize_t argc;
5058
5059 /* execv has two arguments: (path, argv), where
5060 argv is a list or tuple of strings. */
5061
Larry Hastings2f936352014-08-05 14:04:04 +10005062 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005063 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5064 PyErr_SetString(PyExc_TypeError,
5065 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 return NULL;
5067 }
5068 argc = PySequence_Size(argv);
5069 if (argc < 1) {
5070 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005071 return NULL;
5072 }
5073
5074 argvlist = parse_arglist(argv, &argc);
5075 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005076 return NULL;
5077 }
5078
Larry Hastings2f936352014-08-05 14:04:04 +10005079 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080
5081 /* If we get here it's definitely an error */
5082
5083 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005084 return posix_error();
5085}
5086
Larry Hastings2f936352014-08-05 14:04:04 +10005087
5088/*[clinic input]
5089os.execve
5090
5091 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5092 Path of executable file.
5093 argv: object
5094 Tuple or list of strings.
5095 env: object
5096 Dictionary of strings mapping to strings.
5097
5098Execute an executable path with arguments, replacing current process.
5099[clinic start generated code]*/
5100
Larry Hastings2f936352014-08-05 14:04:04 +10005101static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005102os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv,
5103 PyObject *env)
5104/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005106 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005108 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005109
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 /* execve has three arguments: (path, argv, env), where
5111 argv is a list or tuple of strings and env is a dictionary
5112 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005113
Ross Lagerwall7807c352011-03-17 20:20:30 +02005114 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005115 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005116 "execve: argv must be a tuple or list");
5117 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005118 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005119 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005120 if (!PyMapping_Check(env)) {
5121 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005122 "execve: environment must be a mapping object");
5123 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005124 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005125
Ross Lagerwall7807c352011-03-17 20:20:30 +02005126 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005127 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005128 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005129 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005130
Victor Stinner8c62be82010-05-06 00:08:46 +00005131 envlist = parse_envlist(env, &envc);
5132 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005133 goto fail;
5134
Larry Hastings9cf065c2012-06-22 16:30:09 -07005135#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005136 if (path->fd > -1)
5137 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005138 else
5139#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005140 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005141
5142 /* If we get here it's definitely an error */
5143
Larry Hastings2f936352014-08-05 14:04:04 +10005144 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005145
5146 while (--envc >= 0)
5147 PyMem_DEL(envlist[envc]);
5148 PyMem_DEL(envlist);
5149 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005150 if (argvlist)
5151 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005152 return NULL;
5153}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005154#endif /* HAVE_EXECV */
5155
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005156
Guido van Rossuma1065681999-01-25 23:20:23 +00005157#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005158/*[clinic input]
5159os.spawnv
5160
5161 mode: int
5162 Mode of process creation.
5163 path: FSConverter
5164 Path of executable file.
5165 argv: object
5166 Tuple or list of strings.
5167 /
5168
5169Execute the program specified by path in a new process.
5170[clinic start generated code]*/
5171
Larry Hastings2f936352014-08-05 14:04:04 +10005172static PyObject *
5173os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005174/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005175{
5176 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005178 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005179 Py_ssize_t argc;
5180 Py_intptr_t spawnval;
5181 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005182
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 /* spawnv has three arguments: (mode, path, argv), where
5184 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005185
Larry Hastings2f936352014-08-05 14:04:04 +10005186 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005187 if (PyList_Check(argv)) {
5188 argc = PyList_Size(argv);
5189 getitem = PyList_GetItem;
5190 }
5191 else if (PyTuple_Check(argv)) {
5192 argc = PyTuple_Size(argv);
5193 getitem = PyTuple_GetItem;
5194 }
5195 else {
5196 PyErr_SetString(PyExc_TypeError,
5197 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 return NULL;
5199 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005200
Victor Stinner8c62be82010-05-06 00:08:46 +00005201 argvlist = PyMem_NEW(char *, argc+1);
5202 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 return PyErr_NoMemory();
5204 }
5205 for (i = 0; i < argc; i++) {
5206 if (!fsconvert_strdup((*getitem)(argv, i),
5207 &argvlist[i])) {
5208 free_string_array(argvlist, i);
5209 PyErr_SetString(
5210 PyExc_TypeError,
5211 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 return NULL;
5213 }
5214 }
5215 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005216
Victor Stinner8c62be82010-05-06 00:08:46 +00005217 if (mode == _OLD_P_OVERLAY)
5218 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005219
Victor Stinner8c62be82010-05-06 00:08:46 +00005220 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005221 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005222 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005223
Victor Stinner8c62be82010-05-06 00:08:46 +00005224 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005225
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 if (spawnval == -1)
5227 return posix_error();
5228 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005229 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005230}
5231
5232
Larry Hastings2f936352014-08-05 14:04:04 +10005233/*[clinic input]
5234os.spawnve
5235
5236 mode: int
5237 Mode of process creation.
5238 path: FSConverter
5239 Path of executable file.
5240 argv: object
5241 Tuple or list of strings.
5242 env: object
5243 Dictionary of strings mapping to strings.
5244 /
5245
5246Execute the program specified by path in a new process.
5247[clinic start generated code]*/
5248
Larry Hastings2f936352014-08-05 14:04:04 +10005249static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005250os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path,
5251 PyObject *argv, PyObject *env)
5252/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005253{
5254 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005255 char **argvlist;
5256 char **envlist;
5257 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005258 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005259 Py_intptr_t spawnval;
5260 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5261 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005262
Victor Stinner8c62be82010-05-06 00:08:46 +00005263 /* spawnve has four arguments: (mode, path, argv, env), where
5264 argv is a list or tuple of strings and env is a dictionary
5265 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005266
Larry Hastings2f936352014-08-05 14:04:04 +10005267 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005268 if (PyList_Check(argv)) {
5269 argc = PyList_Size(argv);
5270 getitem = PyList_GetItem;
5271 }
5272 else if (PyTuple_Check(argv)) {
5273 argc = PyTuple_Size(argv);
5274 getitem = PyTuple_GetItem;
5275 }
5276 else {
5277 PyErr_SetString(PyExc_TypeError,
5278 "spawnve() arg 2 must be a tuple or list");
5279 goto fail_0;
5280 }
5281 if (!PyMapping_Check(env)) {
5282 PyErr_SetString(PyExc_TypeError,
5283 "spawnve() arg 3 must be a mapping object");
5284 goto fail_0;
5285 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005286
Victor Stinner8c62be82010-05-06 00:08:46 +00005287 argvlist = PyMem_NEW(char *, argc+1);
5288 if (argvlist == NULL) {
5289 PyErr_NoMemory();
5290 goto fail_0;
5291 }
5292 for (i = 0; i < argc; i++) {
5293 if (!fsconvert_strdup((*getitem)(argv, i),
5294 &argvlist[i]))
5295 {
5296 lastarg = i;
5297 goto fail_1;
5298 }
5299 }
5300 lastarg = argc;
5301 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005302
Victor Stinner8c62be82010-05-06 00:08:46 +00005303 envlist = parse_envlist(env, &envc);
5304 if (envlist == NULL)
5305 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005306
Victor Stinner8c62be82010-05-06 00:08:46 +00005307 if (mode == _OLD_P_OVERLAY)
5308 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005309
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005311 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005312 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005313
Victor Stinner8c62be82010-05-06 00:08:46 +00005314 if (spawnval == -1)
5315 (void) posix_error();
5316 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005317 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005318
Victor Stinner8c62be82010-05-06 00:08:46 +00005319 while (--envc >= 0)
5320 PyMem_DEL(envlist[envc]);
5321 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005322 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005323 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005324 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005325 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005326}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005327
Guido van Rossuma1065681999-01-25 23:20:23 +00005328#endif /* HAVE_SPAWNV */
5329
5330
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005331#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005332/*[clinic input]
5333os.fork1
5334
5335Fork a child process with a single multiplexed (i.e., not bound) thread.
5336
5337Return 0 to child process and PID of child to parent process.
5338[clinic start generated code]*/
5339
Larry Hastings2f936352014-08-05 14:04:04 +10005340static PyObject *
5341os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005342/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005343{
Victor Stinner8c62be82010-05-06 00:08:46 +00005344 pid_t pid;
5345 int result = 0;
5346 _PyImport_AcquireLock();
5347 pid = fork1();
5348 if (pid == 0) {
5349 /* child: this clobbers and resets the import lock. */
5350 PyOS_AfterFork();
5351 } else {
5352 /* parent: release the import lock. */
5353 result = _PyImport_ReleaseLock();
5354 }
5355 if (pid == -1)
5356 return posix_error();
5357 if (result < 0) {
5358 /* Don't clobber the OSError if the fork failed. */
5359 PyErr_SetString(PyExc_RuntimeError,
5360 "not holding the import lock");
5361 return NULL;
5362 }
5363 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005364}
Larry Hastings2f936352014-08-05 14:04:04 +10005365#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005366
5367
Guido van Rossumad0ee831995-03-01 10:34:45 +00005368#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005369/*[clinic input]
5370os.fork
5371
5372Fork a child process.
5373
5374Return 0 to child process and PID of child to parent process.
5375[clinic start generated code]*/
5376
Larry Hastings2f936352014-08-05 14:04:04 +10005377static PyObject *
5378os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005379/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005380{
Victor Stinner8c62be82010-05-06 00:08:46 +00005381 pid_t pid;
5382 int result = 0;
5383 _PyImport_AcquireLock();
5384 pid = fork();
5385 if (pid == 0) {
5386 /* child: this clobbers and resets the import lock. */
5387 PyOS_AfterFork();
5388 } else {
5389 /* parent: release the import lock. */
5390 result = _PyImport_ReleaseLock();
5391 }
5392 if (pid == -1)
5393 return posix_error();
5394 if (result < 0) {
5395 /* Don't clobber the OSError if the fork failed. */
5396 PyErr_SetString(PyExc_RuntimeError,
5397 "not holding the import lock");
5398 return NULL;
5399 }
5400 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005401}
Larry Hastings2f936352014-08-05 14:04:04 +10005402#endif /* HAVE_FORK */
5403
Guido van Rossum85e3b011991-06-03 12:42:10 +00005404
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005405#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005406#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005407/*[clinic input]
5408os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005409
Larry Hastings2f936352014-08-05 14:04:04 +10005410 policy: int
5411
5412Get the maximum scheduling priority for policy.
5413[clinic start generated code]*/
5414
Larry Hastings2f936352014-08-05 14:04:04 +10005415static PyObject *
5416os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005417/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005418{
5419 int max;
5420
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005421 max = sched_get_priority_max(policy);
5422 if (max < 0)
5423 return posix_error();
5424 return PyLong_FromLong(max);
5425}
5426
Larry Hastings2f936352014-08-05 14:04:04 +10005427
5428/*[clinic input]
5429os.sched_get_priority_min
5430
5431 policy: int
5432
5433Get the minimum scheduling priority for policy.
5434[clinic start generated code]*/
5435
Larry Hastings2f936352014-08-05 14:04:04 +10005436static PyObject *
5437os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005438/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005439{
5440 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005441 if (min < 0)
5442 return posix_error();
5443 return PyLong_FromLong(min);
5444}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005445#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5446
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005447
Larry Hastings2f936352014-08-05 14:04:04 +10005448#ifdef HAVE_SCHED_SETSCHEDULER
5449/*[clinic input]
5450os.sched_getscheduler
5451 pid: pid_t
5452 /
5453
5454Get the scheduling policy for the process identifiedy by pid.
5455
5456Passing 0 for pid returns the scheduling policy for the calling process.
5457[clinic start generated code]*/
5458
Larry Hastings2f936352014-08-05 14:04:04 +10005459static PyObject *
5460os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005461/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005462{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005463 int policy;
5464
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005465 policy = sched_getscheduler(pid);
5466 if (policy < 0)
5467 return posix_error();
5468 return PyLong_FromLong(policy);
5469}
Larry Hastings2f936352014-08-05 14:04:04 +10005470#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005471
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005472
5473#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005474/*[clinic input]
5475class os.sched_param "PyObject *" "&SchedParamType"
5476
5477@classmethod
5478os.sched_param.__new__
5479
5480 sched_priority: object
5481 A scheduling parameter.
5482
5483Current has only one field: sched_priority");
5484[clinic start generated code]*/
5485
Larry Hastings2f936352014-08-05 14:04:04 +10005486static PyObject *
5487os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005488/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005489{
5490 PyObject *res;
5491
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005492 res = PyStructSequence_New(type);
5493 if (!res)
5494 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005495 Py_INCREF(sched_priority);
5496 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005497 return res;
5498}
5499
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005500
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005501PyDoc_VAR(os_sched_param__doc__);
5502
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005503static PyStructSequence_Field sched_param_fields[] = {
5504 {"sched_priority", "the scheduling priority"},
5505 {0}
5506};
5507
5508static PyStructSequence_Desc sched_param_desc = {
5509 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005510 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005511 sched_param_fields,
5512 1
5513};
5514
5515static int
5516convert_sched_param(PyObject *param, struct sched_param *res)
5517{
5518 long priority;
5519
5520 if (Py_TYPE(param) != &SchedParamType) {
5521 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5522 return 0;
5523 }
5524 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5525 if (priority == -1 && PyErr_Occurred())
5526 return 0;
5527 if (priority > INT_MAX || priority < INT_MIN) {
5528 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5529 return 0;
5530 }
5531 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5532 return 1;
5533}
Larry Hastings2f936352014-08-05 14:04:04 +10005534#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005535
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005536
5537#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005538/*[clinic input]
5539os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005540
Larry Hastings2f936352014-08-05 14:04:04 +10005541 pid: pid_t
5542 policy: int
5543 param: sched_param
5544 /
5545
5546Set the scheduling policy for the process identified by pid.
5547
5548If pid is 0, the calling process is changed.
5549param is an instance of sched_param.
5550[clinic start generated code]*/
5551
Larry Hastings2f936352014-08-05 14:04:04 +10005552static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005553os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy,
5554 struct sched_param *param)
5555/*[clinic end generated code: output=37053e5c528c35c9 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005556{
Jesus Cea9c822272011-09-10 01:40:52 +02005557 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005558 ** sched_setscheduler() returns 0 in Linux, but the previous
5559 ** scheduling policy under Solaris/Illumos, and others.
5560 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005561 */
Larry Hastings2f936352014-08-05 14:04:04 +10005562 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005563 return posix_error();
5564 Py_RETURN_NONE;
5565}
Larry Hastings2f936352014-08-05 14:04:04 +10005566#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005567
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005568
5569#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005570/*[clinic input]
5571os.sched_getparam
5572 pid: pid_t
5573 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005574
Larry Hastings2f936352014-08-05 14:04:04 +10005575Returns scheduling parameters for the process identified by pid.
5576
5577If pid is 0, returns parameters for the calling process.
5578Return value is an instance of sched_param.
5579[clinic start generated code]*/
5580
Larry Hastings2f936352014-08-05 14:04:04 +10005581static PyObject *
5582os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005583/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005584{
5585 struct sched_param param;
5586 PyObject *result;
5587 PyObject *priority;
5588
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005589 if (sched_getparam(pid, &param))
5590 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005591 result = PyStructSequence_New(&SchedParamType);
5592 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005593 return NULL;
5594 priority = PyLong_FromLong(param.sched_priority);
5595 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005596 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005597 return NULL;
5598 }
Larry Hastings2f936352014-08-05 14:04:04 +10005599 PyStructSequence_SET_ITEM(result, 0, priority);
5600 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005601}
5602
Larry Hastings2f936352014-08-05 14:04:04 +10005603
5604/*[clinic input]
5605os.sched_setparam
5606 pid: pid_t
5607 param: sched_param
5608 /
5609
5610Set scheduling parameters for the process identified by pid.
5611
5612If pid is 0, sets parameters for the calling process.
5613param should be an instance of sched_param.
5614[clinic start generated code]*/
5615
Larry Hastings2f936352014-08-05 14:04:04 +10005616static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005617os_sched_setparam_impl(PyModuleDef *module, pid_t pid,
5618 struct sched_param *param)
5619/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005620{
5621 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005622 return posix_error();
5623 Py_RETURN_NONE;
5624}
Larry Hastings2f936352014-08-05 14:04:04 +10005625#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005626
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005627
5628#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005629/*[clinic input]
5630os.sched_rr_get_interval -> double
5631 pid: pid_t
5632 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005633
Larry Hastings2f936352014-08-05 14:04:04 +10005634Return the round-robin quantum for the process identified by pid, in seconds.
5635
5636Value returned is a float.
5637[clinic start generated code]*/
5638
Larry Hastings2f936352014-08-05 14:04:04 +10005639static double
5640os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005641/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005642{
5643 struct timespec interval;
5644 if (sched_rr_get_interval(pid, &interval)) {
5645 posix_error();
5646 return -1.0;
5647 }
5648 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5649}
5650#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005651
Larry Hastings2f936352014-08-05 14:04:04 +10005652
5653/*[clinic input]
5654os.sched_yield
5655
5656Voluntarily relinquish the CPU.
5657[clinic start generated code]*/
5658
Larry Hastings2f936352014-08-05 14:04:04 +10005659static PyObject *
5660os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005661/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005662{
5663 if (sched_yield())
5664 return posix_error();
5665 Py_RETURN_NONE;
5666}
5667
Benjamin Peterson2740af82011-08-02 17:41:34 -05005668#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005669/* The minimum number of CPUs allocated in a cpu_set_t */
5670static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005671
Larry Hastings2f936352014-08-05 14:04:04 +10005672/*[clinic input]
5673os.sched_setaffinity
5674 pid: pid_t
5675 mask : object
5676 /
5677
5678Set the CPU affinity of the process identified by pid to mask.
5679
5680mask should be an iterable of integers identifying CPUs.
5681[clinic start generated code]*/
5682
Larry Hastings2f936352014-08-05 14:04:04 +10005683static PyObject *
5684os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005685/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005686{
Antoine Pitrou84869872012-08-04 16:16:35 +02005687 int ncpus;
5688 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005689 cpu_set_t *cpu_set = NULL;
5690 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005691
Larry Hastings2f936352014-08-05 14:04:04 +10005692 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005693 if (iterator == NULL)
5694 return NULL;
5695
5696 ncpus = NCPUS_START;
5697 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005698 cpu_set = CPU_ALLOC(ncpus);
5699 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005700 PyErr_NoMemory();
5701 goto error;
5702 }
Larry Hastings2f936352014-08-05 14:04:04 +10005703 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005704
5705 while ((item = PyIter_Next(iterator))) {
5706 long cpu;
5707 if (!PyLong_Check(item)) {
5708 PyErr_Format(PyExc_TypeError,
5709 "expected an iterator of ints, "
5710 "but iterator yielded %R",
5711 Py_TYPE(item));
5712 Py_DECREF(item);
5713 goto error;
5714 }
5715 cpu = PyLong_AsLong(item);
5716 Py_DECREF(item);
5717 if (cpu < 0) {
5718 if (!PyErr_Occurred())
5719 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5720 goto error;
5721 }
5722 if (cpu > INT_MAX - 1) {
5723 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5724 goto error;
5725 }
5726 if (cpu >= ncpus) {
5727 /* Grow CPU mask to fit the CPU number */
5728 int newncpus = ncpus;
5729 cpu_set_t *newmask;
5730 size_t newsetsize;
5731 while (newncpus <= cpu) {
5732 if (newncpus > INT_MAX / 2)
5733 newncpus = cpu + 1;
5734 else
5735 newncpus = newncpus * 2;
5736 }
5737 newmask = CPU_ALLOC(newncpus);
5738 if (newmask == NULL) {
5739 PyErr_NoMemory();
5740 goto error;
5741 }
5742 newsetsize = CPU_ALLOC_SIZE(newncpus);
5743 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005744 memcpy(newmask, cpu_set, setsize);
5745 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005746 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005747 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005748 ncpus = newncpus;
5749 }
Larry Hastings2f936352014-08-05 14:04:04 +10005750 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005751 }
5752 Py_CLEAR(iterator);
5753
Larry Hastings2f936352014-08-05 14:04:04 +10005754 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005755 posix_error();
5756 goto error;
5757 }
Larry Hastings2f936352014-08-05 14:04:04 +10005758 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005759 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005760
5761error:
Larry Hastings2f936352014-08-05 14:04:04 +10005762 if (cpu_set)
5763 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005764 Py_XDECREF(iterator);
5765 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005766}
5767
Larry Hastings2f936352014-08-05 14:04:04 +10005768
5769/*[clinic input]
5770os.sched_getaffinity
5771 pid: pid_t
5772 /
5773
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005774Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005775
5776The affinity is returned as a set of CPU identifiers.
5777[clinic start generated code]*/
5778
Larry Hastings2f936352014-08-05 14:04:04 +10005779static PyObject *
5780os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Charles-François Natali80d62e62015-08-13 20:37:08 +01005781/*[clinic end generated code: output=b431a8f310e369e7 input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005782{
Antoine Pitrou84869872012-08-04 16:16:35 +02005783 int cpu, ncpus, count;
5784 size_t setsize;
5785 cpu_set_t *mask = NULL;
5786 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005787
Antoine Pitrou84869872012-08-04 16:16:35 +02005788 ncpus = NCPUS_START;
5789 while (1) {
5790 setsize = CPU_ALLOC_SIZE(ncpus);
5791 mask = CPU_ALLOC(ncpus);
5792 if (mask == NULL)
5793 return PyErr_NoMemory();
5794 if (sched_getaffinity(pid, setsize, mask) == 0)
5795 break;
5796 CPU_FREE(mask);
5797 if (errno != EINVAL)
5798 return posix_error();
5799 if (ncpus > INT_MAX / 2) {
5800 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5801 "a large enough CPU set");
5802 return NULL;
5803 }
5804 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005805 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005806
5807 res = PySet_New(NULL);
5808 if (res == NULL)
5809 goto error;
5810 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5811 if (CPU_ISSET_S(cpu, setsize, mask)) {
5812 PyObject *cpu_num = PyLong_FromLong(cpu);
5813 --count;
5814 if (cpu_num == NULL)
5815 goto error;
5816 if (PySet_Add(res, cpu_num)) {
5817 Py_DECREF(cpu_num);
5818 goto error;
5819 }
5820 Py_DECREF(cpu_num);
5821 }
5822 }
5823 CPU_FREE(mask);
5824 return res;
5825
5826error:
5827 if (mask)
5828 CPU_FREE(mask);
5829 Py_XDECREF(res);
5830 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005831}
5832
Benjamin Peterson2740af82011-08-02 17:41:34 -05005833#endif /* HAVE_SCHED_SETAFFINITY */
5834
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005835#endif /* HAVE_SCHED_H */
5836
Larry Hastings2f936352014-08-05 14:04:04 +10005837
Neal Norwitzb59798b2003-03-21 01:43:31 +00005838/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005839/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5840#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005841#define DEV_PTY_FILE "/dev/ptc"
5842#define HAVE_DEV_PTMX
5843#else
5844#define DEV_PTY_FILE "/dev/ptmx"
5845#endif
5846
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005847#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005848#ifdef HAVE_PTY_H
5849#include <pty.h>
5850#else
5851#ifdef HAVE_LIBUTIL_H
5852#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005853#else
5854#ifdef HAVE_UTIL_H
5855#include <util.h>
5856#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005857#endif /* HAVE_LIBUTIL_H */
5858#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005859#ifdef HAVE_STROPTS_H
5860#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005861#endif
5862#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005863
Larry Hastings2f936352014-08-05 14:04:04 +10005864
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005865#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005866/*[clinic input]
5867os.openpty
5868
5869Open a pseudo-terminal.
5870
5871Return a tuple of (master_fd, slave_fd) containing open file descriptors
5872for both the master and slave ends.
5873[clinic start generated code]*/
5874
Larry Hastings2f936352014-08-05 14:04:04 +10005875static PyObject *
5876os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005877/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005878{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005879 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005880#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005882#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005883#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005885#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005887#endif
5888#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005889
Thomas Wouters70c21a12000-07-14 14:28:33 +00005890#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005891 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005892 goto posix_error;
5893
5894 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5895 goto error;
5896 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5897 goto error;
5898
Neal Norwitzb59798b2003-03-21 01:43:31 +00005899#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5901 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005902 goto posix_error;
5903 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5904 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005905
Victor Stinnerdaf45552013-08-28 00:53:59 +02005906 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005907 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005908 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005909
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005910#else
Victor Stinner000de532013-11-25 23:19:58 +01005911 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005913 goto posix_error;
5914
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005916
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 /* change permission of slave */
5918 if (grantpt(master_fd) < 0) {
5919 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005920 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005921 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005922
Victor Stinner8c62be82010-05-06 00:08:46 +00005923 /* unlock slave */
5924 if (unlockpt(master_fd) < 0) {
5925 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005926 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005927 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005928
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005930
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 slave_name = ptsname(master_fd); /* get name of slave */
5932 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005933 goto posix_error;
5934
5935 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005936 if (slave_fd == -1)
5937 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005938
5939 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5940 goto posix_error;
5941
Neal Norwitzb59798b2003-03-21 01:43:31 +00005942#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005943 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5944 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005945#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005946 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005947#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005948#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005949#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005950
Victor Stinner8c62be82010-05-06 00:08:46 +00005951 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005952
Victor Stinnerdaf45552013-08-28 00:53:59 +02005953posix_error:
5954 posix_error();
5955error:
5956 if (master_fd != -1)
5957 close(master_fd);
5958 if (slave_fd != -1)
5959 close(slave_fd);
5960 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005961}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005962#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005963
Larry Hastings2f936352014-08-05 14:04:04 +10005964
Fred Drake8cef4cf2000-06-28 16:40:38 +00005965#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005966/*[clinic input]
5967os.forkpty
5968
5969Fork a new process with a new pseudo-terminal as controlling tty.
5970
5971Returns a tuple of (pid, master_fd).
5972Like fork(), return pid of 0 to the child process,
5973and pid of child to the parent process.
5974To both, return fd of newly opened pseudo-terminal.
5975[clinic start generated code]*/
5976
Larry Hastings2f936352014-08-05 14:04:04 +10005977static PyObject *
5978os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005979/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005980{
Victor Stinner8c62be82010-05-06 00:08:46 +00005981 int master_fd = -1, result = 0;
5982 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005983
Victor Stinner8c62be82010-05-06 00:08:46 +00005984 _PyImport_AcquireLock();
5985 pid = forkpty(&master_fd, NULL, NULL, NULL);
5986 if (pid == 0) {
5987 /* child: this clobbers and resets the import lock. */
5988 PyOS_AfterFork();
5989 } else {
5990 /* parent: release the import lock. */
5991 result = _PyImport_ReleaseLock();
5992 }
5993 if (pid == -1)
5994 return posix_error();
5995 if (result < 0) {
5996 /* Don't clobber the OSError if the fork failed. */
5997 PyErr_SetString(PyExc_RuntimeError,
5998 "not holding the import lock");
5999 return NULL;
6000 }
6001 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00006002}
Larry Hastings2f936352014-08-05 14:04:04 +10006003#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006004
Ross Lagerwall7807c352011-03-17 20:20:30 +02006005
Guido van Rossumad0ee831995-03-01 10:34:45 +00006006#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006007/*[clinic input]
6008os.getegid
6009
6010Return the current process's effective group id.
6011[clinic start generated code]*/
6012
Larry Hastings2f936352014-08-05 14:04:04 +10006013static PyObject *
6014os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006015/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006016{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006017 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006018}
Larry Hastings2f936352014-08-05 14:04:04 +10006019#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006020
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006021
Guido van Rossumad0ee831995-03-01 10:34:45 +00006022#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006023/*[clinic input]
6024os.geteuid
6025
6026Return the current process's effective user id.
6027[clinic start generated code]*/
6028
Larry Hastings2f936352014-08-05 14:04:04 +10006029static PyObject *
6030os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006031/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006032{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006033 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006034}
Larry Hastings2f936352014-08-05 14:04:04 +10006035#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006037
Guido van Rossumad0ee831995-03-01 10:34:45 +00006038#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006039/*[clinic input]
6040os.getgid
6041
6042Return the current process's group id.
6043[clinic start generated code]*/
6044
Larry Hastings2f936352014-08-05 14:04:04 +10006045static PyObject *
6046os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006047/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006048{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006049 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006050}
Larry Hastings2f936352014-08-05 14:04:04 +10006051#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006052
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006053
Larry Hastings2f936352014-08-05 14:04:04 +10006054/*[clinic input]
6055os.getpid
6056
6057Return the current process id.
6058[clinic start generated code]*/
6059
Larry Hastings2f936352014-08-05 14:04:04 +10006060static PyObject *
6061os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006062/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006063{
Victor Stinner8c62be82010-05-06 00:08:46 +00006064 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006065}
6066
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006067#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006068
6069/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006070PyDoc_STRVAR(posix_getgrouplist__doc__,
6071"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6072Returns a list of groups to which a user belongs.\n\n\
6073 user: username to lookup\n\
6074 group: base group id of the user");
6075
6076static PyObject *
6077posix_getgrouplist(PyObject *self, PyObject *args)
6078{
6079#ifdef NGROUPS_MAX
6080#define MAX_GROUPS NGROUPS_MAX
6081#else
6082 /* defined to be 16 on Solaris7, so this should be a small number */
6083#define MAX_GROUPS 64
6084#endif
6085
6086 const char *user;
6087 int i, ngroups;
6088 PyObject *list;
6089#ifdef __APPLE__
6090 int *groups, basegid;
6091#else
6092 gid_t *groups, basegid;
6093#endif
6094 ngroups = MAX_GROUPS;
6095
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006096#ifdef __APPLE__
6097 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006098 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006099#else
6100 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6101 _Py_Gid_Converter, &basegid))
6102 return NULL;
6103#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006104
6105#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006106 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006107#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006108 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006109#endif
6110 if (groups == NULL)
6111 return PyErr_NoMemory();
6112
6113 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6114 PyMem_Del(groups);
6115 return posix_error();
6116 }
6117
6118 list = PyList_New(ngroups);
6119 if (list == NULL) {
6120 PyMem_Del(groups);
6121 return NULL;
6122 }
6123
6124 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006125#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006126 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006127#else
6128 PyObject *o = _PyLong_FromGid(groups[i]);
6129#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006130 if (o == NULL) {
6131 Py_DECREF(list);
6132 PyMem_Del(groups);
6133 return NULL;
6134 }
6135 PyList_SET_ITEM(list, i, o);
6136 }
6137
6138 PyMem_Del(groups);
6139
6140 return list;
6141}
Larry Hastings2f936352014-08-05 14:04:04 +10006142#endif /* HAVE_GETGROUPLIST */
6143
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006144
Fred Drakec9680921999-12-13 16:37:25 +00006145#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006146/*[clinic input]
6147os.getgroups
6148
6149Return list of supplemental group IDs for the process.
6150[clinic start generated code]*/
6151
Larry Hastings2f936352014-08-05 14:04:04 +10006152static PyObject *
6153os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006154/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006155{
6156 PyObject *result = NULL;
6157
Fred Drakec9680921999-12-13 16:37:25 +00006158#ifdef NGROUPS_MAX
6159#define MAX_GROUPS NGROUPS_MAX
6160#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006161 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006162#define MAX_GROUPS 64
6163#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006164 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006165
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006166 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006167 * This is a helper variable to store the intermediate result when
6168 * that happens.
6169 *
6170 * To keep the code readable the OSX behaviour is unconditional,
6171 * according to the POSIX spec this should be safe on all unix-y
6172 * systems.
6173 */
6174 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006175 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006176
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006177#ifdef __APPLE__
6178 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6179 * there are more groups than can fit in grouplist. Therefore, on OS X
6180 * always first call getgroups with length 0 to get the actual number
6181 * of groups.
6182 */
6183 n = getgroups(0, NULL);
6184 if (n < 0) {
6185 return posix_error();
6186 } else if (n <= MAX_GROUPS) {
6187 /* groups will fit in existing array */
6188 alt_grouplist = grouplist;
6189 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006190 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006191 if (alt_grouplist == NULL) {
6192 errno = EINVAL;
6193 return posix_error();
6194 }
6195 }
6196
6197 n = getgroups(n, alt_grouplist);
6198 if (n == -1) {
6199 if (alt_grouplist != grouplist) {
6200 PyMem_Free(alt_grouplist);
6201 }
6202 return posix_error();
6203 }
6204#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006205 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006206 if (n < 0) {
6207 if (errno == EINVAL) {
6208 n = getgroups(0, NULL);
6209 if (n == -1) {
6210 return posix_error();
6211 }
6212 if (n == 0) {
6213 /* Avoid malloc(0) */
6214 alt_grouplist = grouplist;
6215 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006216 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006217 if (alt_grouplist == NULL) {
6218 errno = EINVAL;
6219 return posix_error();
6220 }
6221 n = getgroups(n, alt_grouplist);
6222 if (n == -1) {
6223 PyMem_Free(alt_grouplist);
6224 return posix_error();
6225 }
6226 }
6227 } else {
6228 return posix_error();
6229 }
6230 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006231#endif
6232
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006233 result = PyList_New(n);
6234 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006235 int i;
6236 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006237 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006238 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006239 Py_DECREF(result);
6240 result = NULL;
6241 break;
Fred Drakec9680921999-12-13 16:37:25 +00006242 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006243 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006244 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006245 }
6246
6247 if (alt_grouplist != grouplist) {
6248 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006249 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006250
Fred Drakec9680921999-12-13 16:37:25 +00006251 return result;
6252}
Larry Hastings2f936352014-08-05 14:04:04 +10006253#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006254
Antoine Pitroub7572f02009-12-02 20:46:48 +00006255#ifdef HAVE_INITGROUPS
6256PyDoc_STRVAR(posix_initgroups__doc__,
6257"initgroups(username, gid) -> None\n\n\
6258Call the system initgroups() to initialize the group access list with all of\n\
6259the groups of which the specified username is a member, plus the specified\n\
6260group id.");
6261
Larry Hastings2f936352014-08-05 14:04:04 +10006262/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006263static PyObject *
6264posix_initgroups(PyObject *self, PyObject *args)
6265{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006266 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006268 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006269#ifdef __APPLE__
6270 int gid;
6271#else
6272 gid_t gid;
6273#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006274
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006275#ifdef __APPLE__
6276 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6277 PyUnicode_FSConverter, &oname,
6278 &gid))
6279#else
6280 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6281 PyUnicode_FSConverter, &oname,
6282 _Py_Gid_Converter, &gid))
6283#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006284 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006285 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006286
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006287 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006288 Py_DECREF(oname);
6289 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006290 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006291
Victor Stinner8c62be82010-05-06 00:08:46 +00006292 Py_INCREF(Py_None);
6293 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006294}
Larry Hastings2f936352014-08-05 14:04:04 +10006295#endif /* HAVE_INITGROUPS */
6296
Antoine Pitroub7572f02009-12-02 20:46:48 +00006297
Martin v. Löwis606edc12002-06-13 21:09:11 +00006298#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006299/*[clinic input]
6300os.getpgid
6301
6302 pid: pid_t
6303
6304Call the system call getpgid(), and return the result.
6305[clinic start generated code]*/
6306
Larry Hastings2f936352014-08-05 14:04:04 +10006307static PyObject *
6308os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006309/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006310{
6311 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006312 if (pgid < 0)
6313 return posix_error();
6314 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006315}
6316#endif /* HAVE_GETPGID */
6317
6318
Guido van Rossumb6775db1994-08-01 11:34:53 +00006319#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006320/*[clinic input]
6321os.getpgrp
6322
6323Return the current process group id.
6324[clinic start generated code]*/
6325
Larry Hastings2f936352014-08-05 14:04:04 +10006326static PyObject *
6327os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006328/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006329{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006330#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006331 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006332#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006333 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006334#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006335}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006336#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006337
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006338
Guido van Rossumb6775db1994-08-01 11:34:53 +00006339#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006340/*[clinic input]
6341os.setpgrp
6342
6343Make the current process the leader of its process group.
6344[clinic start generated code]*/
6345
Larry Hastings2f936352014-08-05 14:04:04 +10006346static PyObject *
6347os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006348/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006349{
Guido van Rossum64933891994-10-20 21:56:42 +00006350#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006351 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006352#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006353 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006354#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006355 return posix_error();
6356 Py_INCREF(Py_None);
6357 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006358}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006359#endif /* HAVE_SETPGRP */
6360
Guido van Rossumad0ee831995-03-01 10:34:45 +00006361#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006362
6363#ifdef MS_WINDOWS
6364#include <tlhelp32.h>
6365
6366static PyObject*
6367win32_getppid()
6368{
6369 HANDLE snapshot;
6370 pid_t mypid;
6371 PyObject* result = NULL;
6372 BOOL have_record;
6373 PROCESSENTRY32 pe;
6374
6375 mypid = getpid(); /* This function never fails */
6376
6377 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6378 if (snapshot == INVALID_HANDLE_VALUE)
6379 return PyErr_SetFromWindowsErr(GetLastError());
6380
6381 pe.dwSize = sizeof(pe);
6382 have_record = Process32First(snapshot, &pe);
6383 while (have_record) {
6384 if (mypid == (pid_t)pe.th32ProcessID) {
6385 /* We could cache the ulong value in a static variable. */
6386 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6387 break;
6388 }
6389
6390 have_record = Process32Next(snapshot, &pe);
6391 }
6392
6393 /* If our loop exits and our pid was not found (result will be NULL)
6394 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6395 * error anyway, so let's raise it. */
6396 if (!result)
6397 result = PyErr_SetFromWindowsErr(GetLastError());
6398
6399 CloseHandle(snapshot);
6400
6401 return result;
6402}
6403#endif /*MS_WINDOWS*/
6404
Larry Hastings2f936352014-08-05 14:04:04 +10006405
6406/*[clinic input]
6407os.getppid
6408
6409Return the parent's process id.
6410
6411If the parent process has already exited, Windows machines will still
6412return its id; others systems will return the id of the 'init' process (1).
6413[clinic start generated code]*/
6414
Larry Hastings2f936352014-08-05 14:04:04 +10006415static PyObject *
6416os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006417/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006418{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006419#ifdef MS_WINDOWS
6420 return win32_getppid();
6421#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006423#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006424}
6425#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006426
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006427
Fred Drake12c6e2d1999-12-14 21:25:03 +00006428#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006429/*[clinic input]
6430os.getlogin
6431
6432Return the actual login name.
6433[clinic start generated code]*/
6434
Larry Hastings2f936352014-08-05 14:04:04 +10006435static PyObject *
6436os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006437/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006438{
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006440#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006441 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006442 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006443
6444 if (GetUserNameW(user_name, &num_chars)) {
6445 /* num_chars is the number of unicode chars plus null terminator */
6446 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006447 }
6448 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006449 result = PyErr_SetFromWindowsErr(GetLastError());
6450#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 char *name;
6452 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006453
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 errno = 0;
6455 name = getlogin();
6456 if (name == NULL) {
6457 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006458 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006459 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006460 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006461 }
6462 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006463 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006464 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006465#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006466 return result;
6467}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006468#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006469
Larry Hastings2f936352014-08-05 14:04:04 +10006470
Guido van Rossumad0ee831995-03-01 10:34:45 +00006471#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006472/*[clinic input]
6473os.getuid
6474
6475Return the current process's user id.
6476[clinic start generated code]*/
6477
Larry Hastings2f936352014-08-05 14:04:04 +10006478static PyObject *
6479os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006480/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006481{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006482 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006483}
Larry Hastings2f936352014-08-05 14:04:04 +10006484#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006485
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006486
Brian Curtineb24d742010-04-12 17:16:38 +00006487#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006488#define HAVE_KILL
6489#endif /* MS_WINDOWS */
6490
6491#ifdef HAVE_KILL
6492/*[clinic input]
6493os.kill
6494
6495 pid: pid_t
6496 signal: Py_ssize_t
6497 /
6498
6499Kill a process with a signal.
6500[clinic start generated code]*/
6501
Larry Hastings2f936352014-08-05 14:04:04 +10006502static PyObject *
6503os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006504/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006505#ifndef MS_WINDOWS
6506{
6507 if (kill(pid, (int)signal) == -1)
6508 return posix_error();
6509 Py_RETURN_NONE;
6510}
6511#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006512{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006513 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006514 DWORD sig = (DWORD)signal;
6515 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006516 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006517
Victor Stinner8c62be82010-05-06 00:08:46 +00006518 /* Console processes which share a common console can be sent CTRL+C or
6519 CTRL+BREAK events, provided they handle said events. */
6520 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006521 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 err = GetLastError();
6523 PyErr_SetFromWindowsErr(err);
6524 }
6525 else
6526 Py_RETURN_NONE;
6527 }
Brian Curtineb24d742010-04-12 17:16:38 +00006528
Victor Stinner8c62be82010-05-06 00:08:46 +00006529 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6530 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006531 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006532 if (handle == NULL) {
6533 err = GetLastError();
6534 return PyErr_SetFromWindowsErr(err);
6535 }
Brian Curtineb24d742010-04-12 17:16:38 +00006536
Victor Stinner8c62be82010-05-06 00:08:46 +00006537 if (TerminateProcess(handle, sig) == 0) {
6538 err = GetLastError();
6539 result = PyErr_SetFromWindowsErr(err);
6540 } else {
6541 Py_INCREF(Py_None);
6542 result = Py_None;
6543 }
Brian Curtineb24d742010-04-12 17:16:38 +00006544
Victor Stinner8c62be82010-05-06 00:08:46 +00006545 CloseHandle(handle);
6546 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006547}
Larry Hastings2f936352014-08-05 14:04:04 +10006548#endif /* !MS_WINDOWS */
6549#endif /* HAVE_KILL */
6550
6551
6552#ifdef HAVE_KILLPG
6553/*[clinic input]
6554os.killpg
6555
6556 pgid: pid_t
6557 signal: int
6558 /
6559
6560Kill a process group with a signal.
6561[clinic start generated code]*/
6562
Larry Hastings2f936352014-08-05 14:04:04 +10006563static PyObject *
6564os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006565/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006566{
6567 /* XXX some man pages make the `pgid` parameter an int, others
6568 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6569 take the same type. Moreover, pid_t is always at least as wide as
6570 int (else compilation of this module fails), which is safe. */
6571 if (killpg(pgid, signal) == -1)
6572 return posix_error();
6573 Py_RETURN_NONE;
6574}
6575#endif /* HAVE_KILLPG */
6576
Brian Curtineb24d742010-04-12 17:16:38 +00006577
Guido van Rossumc0125471996-06-28 18:55:32 +00006578#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006579#ifdef HAVE_SYS_LOCK_H
6580#include <sys/lock.h>
6581#endif
6582
Larry Hastings2f936352014-08-05 14:04:04 +10006583/*[clinic input]
6584os.plock
6585 op: int
6586 /
6587
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006588Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006589[clinic start generated code]*/
6590
Larry Hastings2f936352014-08-05 14:04:04 +10006591static PyObject *
6592os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006593/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006594{
Victor Stinner8c62be82010-05-06 00:08:46 +00006595 if (plock(op) == -1)
6596 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006597 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006598}
Larry Hastings2f936352014-08-05 14:04:04 +10006599#endif /* HAVE_PLOCK */
6600
Guido van Rossumc0125471996-06-28 18:55:32 +00006601
Guido van Rossumb6775db1994-08-01 11:34:53 +00006602#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006603/*[clinic input]
6604os.setuid
6605
6606 uid: uid_t
6607 /
6608
6609Set the current process's user id.
6610[clinic start generated code]*/
6611
Larry Hastings2f936352014-08-05 14:04:04 +10006612static PyObject *
6613os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006614/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006615{
Victor Stinner8c62be82010-05-06 00:08:46 +00006616 if (setuid(uid) < 0)
6617 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006618 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006619}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006620#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006621
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006622
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006623#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006624/*[clinic input]
6625os.seteuid
6626
6627 euid: uid_t
6628 /
6629
6630Set the current process's effective user id.
6631[clinic start generated code]*/
6632
Larry Hastings2f936352014-08-05 14:04:04 +10006633static PyObject *
6634os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006635/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006636{
6637 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006638 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006639 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006640}
6641#endif /* HAVE_SETEUID */
6642
Larry Hastings2f936352014-08-05 14:04:04 +10006643
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006644#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006645/*[clinic input]
6646os.setegid
6647
6648 egid: gid_t
6649 /
6650
6651Set the current process's effective group id.
6652[clinic start generated code]*/
6653
Larry Hastings2f936352014-08-05 14:04:04 +10006654static PyObject *
6655os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006656/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006657{
6658 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006659 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006660 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006661}
6662#endif /* HAVE_SETEGID */
6663
Larry Hastings2f936352014-08-05 14:04:04 +10006664
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006665#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006666/*[clinic input]
6667os.setreuid
6668
6669 ruid: uid_t
6670 euid: uid_t
6671 /
6672
6673Set the current process's real and effective user ids.
6674[clinic start generated code]*/
6675
Larry Hastings2f936352014-08-05 14:04:04 +10006676static PyObject *
6677os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006678/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006679{
Victor Stinner8c62be82010-05-06 00:08:46 +00006680 if (setreuid(ruid, euid) < 0) {
6681 return posix_error();
6682 } else {
6683 Py_INCREF(Py_None);
6684 return Py_None;
6685 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006686}
6687#endif /* HAVE_SETREUID */
6688
Larry Hastings2f936352014-08-05 14:04:04 +10006689
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006690#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006691/*[clinic input]
6692os.setregid
6693
6694 rgid: gid_t
6695 egid: gid_t
6696 /
6697
6698Set the current process's real and effective group ids.
6699[clinic start generated code]*/
6700
Larry Hastings2f936352014-08-05 14:04:04 +10006701static PyObject *
6702os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006703/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006704{
6705 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006706 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006707 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006708}
6709#endif /* HAVE_SETREGID */
6710
Larry Hastings2f936352014-08-05 14:04:04 +10006711
Guido van Rossumb6775db1994-08-01 11:34:53 +00006712#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006713/*[clinic input]
6714os.setgid
6715 gid: gid_t
6716 /
6717
6718Set the current process's group id.
6719[clinic start generated code]*/
6720
Larry Hastings2f936352014-08-05 14:04:04 +10006721static PyObject *
6722os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006723/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006724{
Victor Stinner8c62be82010-05-06 00:08:46 +00006725 if (setgid(gid) < 0)
6726 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006727 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006728}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006729#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006730
Larry Hastings2f936352014-08-05 14:04:04 +10006731
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006732#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006733/*[clinic input]
6734os.setgroups
6735
6736 groups: object
6737 /
6738
6739Set the groups of the current process to list.
6740[clinic start generated code]*/
6741
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006742static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006743os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006744/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006745{
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 int i, len;
6747 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006748
Victor Stinner8c62be82010-05-06 00:08:46 +00006749 if (!PySequence_Check(groups)) {
6750 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6751 return NULL;
6752 }
6753 len = PySequence_Size(groups);
6754 if (len > MAX_GROUPS) {
6755 PyErr_SetString(PyExc_ValueError, "too many groups");
6756 return NULL;
6757 }
6758 for(i = 0; i < len; i++) {
6759 PyObject *elem;
6760 elem = PySequence_GetItem(groups, i);
6761 if (!elem)
6762 return NULL;
6763 if (!PyLong_Check(elem)) {
6764 PyErr_SetString(PyExc_TypeError,
6765 "groups must be integers");
6766 Py_DECREF(elem);
6767 return NULL;
6768 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006769 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006770 Py_DECREF(elem);
6771 return NULL;
6772 }
6773 }
6774 Py_DECREF(elem);
6775 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006776
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 if (setgroups(len, grouplist) < 0)
6778 return posix_error();
6779 Py_INCREF(Py_None);
6780 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006781}
6782#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006783
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006784#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6785static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006786wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006787{
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 PyObject *result;
6789 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006790 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006791
Victor Stinner8c62be82010-05-06 00:08:46 +00006792 if (pid == -1)
6793 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006794
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 if (struct_rusage == NULL) {
6796 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6797 if (m == NULL)
6798 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006799 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006800 Py_DECREF(m);
6801 if (struct_rusage == NULL)
6802 return NULL;
6803 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006804
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6806 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6807 if (!result)
6808 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006809
6810#ifndef doubletime
6811#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6812#endif
6813
Victor Stinner8c62be82010-05-06 00:08:46 +00006814 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006815 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006816 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006817 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006818#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6820 SET_INT(result, 2, ru->ru_maxrss);
6821 SET_INT(result, 3, ru->ru_ixrss);
6822 SET_INT(result, 4, ru->ru_idrss);
6823 SET_INT(result, 5, ru->ru_isrss);
6824 SET_INT(result, 6, ru->ru_minflt);
6825 SET_INT(result, 7, ru->ru_majflt);
6826 SET_INT(result, 8, ru->ru_nswap);
6827 SET_INT(result, 9, ru->ru_inblock);
6828 SET_INT(result, 10, ru->ru_oublock);
6829 SET_INT(result, 11, ru->ru_msgsnd);
6830 SET_INT(result, 12, ru->ru_msgrcv);
6831 SET_INT(result, 13, ru->ru_nsignals);
6832 SET_INT(result, 14, ru->ru_nvcsw);
6833 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006834#undef SET_INT
6835
Victor Stinner8c62be82010-05-06 00:08:46 +00006836 if (PyErr_Occurred()) {
6837 Py_DECREF(result);
6838 return NULL;
6839 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006840
Victor Stinner8c62be82010-05-06 00:08:46 +00006841 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006842}
6843#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6844
Larry Hastings2f936352014-08-05 14:04:04 +10006845
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006846#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006847/*[clinic input]
6848os.wait3
6849
6850 options: int
6851Wait for completion of a child process.
6852
6853Returns a tuple of information about the child process:
6854 (pid, status, rusage)
6855[clinic start generated code]*/
6856
Larry Hastings2f936352014-08-05 14:04:04 +10006857static PyObject *
6858os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006859/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006860{
Victor Stinner8c62be82010-05-06 00:08:46 +00006861 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006862 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006863 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006864 WAIT_TYPE status;
6865 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006867 do {
6868 Py_BEGIN_ALLOW_THREADS
6869 pid = wait3(&status, options, &ru);
6870 Py_END_ALLOW_THREADS
6871 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6872 if (pid < 0)
6873 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006874
Victor Stinner4195b5c2012-02-08 23:03:19 +01006875 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006876}
6877#endif /* HAVE_WAIT3 */
6878
Larry Hastings2f936352014-08-05 14:04:04 +10006879
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006881/*[clinic input]
6882
6883os.wait4
6884
6885 pid: pid_t
6886 options: int
6887
6888Wait for completion of a specific child process.
6889
6890Returns a tuple of information about the child process:
6891 (pid, status, rusage)
6892[clinic start generated code]*/
6893
Larry Hastings2f936352014-08-05 14:04:04 +10006894static PyObject *
6895os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006896/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006897{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006898 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006899 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006900 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006901 WAIT_TYPE status;
6902 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006904 do {
6905 Py_BEGIN_ALLOW_THREADS
6906 res = wait4(pid, &status, options, &ru);
6907 Py_END_ALLOW_THREADS
6908 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6909 if (res < 0)
6910 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006911
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006912 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006913}
6914#endif /* HAVE_WAIT4 */
6915
Larry Hastings2f936352014-08-05 14:04:04 +10006916
Ross Lagerwall7807c352011-03-17 20:20:30 +02006917#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006918/*[clinic input]
6919os.waitid
6920
6921 idtype: idtype_t
6922 Must be one of be P_PID, P_PGID or P_ALL.
6923 id: id_t
6924 The id to wait on.
6925 options: int
6926 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6927 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6928 /
6929
6930Returns the result of waiting for a process or processes.
6931
6932Returns either waitid_result or None if WNOHANG is specified and there are
6933no children in a waitable state.
6934[clinic start generated code]*/
6935
Larry Hastings2f936352014-08-05 14:04:04 +10006936static PyObject *
6937os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006938/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006939{
6940 PyObject *result;
6941 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006942 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006943 siginfo_t si;
6944 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006945
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006946 do {
6947 Py_BEGIN_ALLOW_THREADS
6948 res = waitid(idtype, id, &si, options);
6949 Py_END_ALLOW_THREADS
6950 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6951 if (res < 0)
6952 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006953
6954 if (si.si_pid == 0)
6955 Py_RETURN_NONE;
6956
6957 result = PyStructSequence_New(&WaitidResultType);
6958 if (!result)
6959 return NULL;
6960
6961 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006962 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006963 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6964 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6965 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6966 if (PyErr_Occurred()) {
6967 Py_DECREF(result);
6968 return NULL;
6969 }
6970
6971 return result;
6972}
Larry Hastings2f936352014-08-05 14:04:04 +10006973#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006974
Larry Hastings2f936352014-08-05 14:04:04 +10006975
6976#if defined(HAVE_WAITPID)
6977/*[clinic input]
6978os.waitpid
6979 pid: pid_t
6980 options: int
6981 /
6982
6983Wait for completion of a given child process.
6984
6985Returns a tuple of information regarding the child process:
6986 (pid, status)
6987
6988The options argument is ignored on Windows.
6989[clinic start generated code]*/
6990
Larry Hastings2f936352014-08-05 14:04:04 +10006991static PyObject *
6992os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006993/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006994{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006995 pid_t res;
6996 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006997 WAIT_TYPE status;
6998 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006999
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007000 do {
7001 Py_BEGIN_ALLOW_THREADS
7002 res = waitpid(pid, &status, options);
7003 Py_END_ALLOW_THREADS
7004 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7005 if (res < 0)
7006 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007007
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007008 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00007009}
Tim Petersab034fa2002-02-01 11:27:43 +00007010#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007011/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007012/*[clinic input]
7013os.waitpid
7014 pid: Py_intptr_t
7015 options: int
7016 /
7017
7018Wait for completion of a given process.
7019
7020Returns a tuple of information regarding the process:
7021 (pid, status << 8)
7022
7023The options argument is ignored on Windows.
7024[clinic start generated code]*/
7025
Larry Hastings2f936352014-08-05 14:04:04 +10007026static PyObject *
7027os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007028/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007029{
7030 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007031 Py_intptr_t res;
7032 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007033
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007034 do {
7035 Py_BEGIN_ALLOW_THREADS
7036 res = _cwait(&status, pid, options);
7037 Py_END_ALLOW_THREADS
7038 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007039 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007040 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007041
Victor Stinner8c62be82010-05-06 00:08:46 +00007042 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007043 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007044}
Larry Hastings2f936352014-08-05 14:04:04 +10007045#endif
7046
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007047
Guido van Rossumad0ee831995-03-01 10:34:45 +00007048#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007049/*[clinic input]
7050os.wait
7051
7052Wait for completion of a child process.
7053
7054Returns a tuple of information about the child process:
7055 (pid, status)
7056[clinic start generated code]*/
7057
Larry Hastings2f936352014-08-05 14:04:04 +10007058static PyObject *
7059os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007060/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007061{
Victor Stinner8c62be82010-05-06 00:08:46 +00007062 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007063 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007064 WAIT_TYPE status;
7065 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007066
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007067 do {
7068 Py_BEGIN_ALLOW_THREADS
7069 pid = wait(&status);
7070 Py_END_ALLOW_THREADS
7071 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7072 if (pid < 0)
7073 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007074
Victor Stinner8c62be82010-05-06 00:08:46 +00007075 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007076}
Larry Hastings2f936352014-08-05 14:04:04 +10007077#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007078
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007079
Larry Hastings9cf065c2012-06-22 16:30:09 -07007080#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7081PyDoc_STRVAR(readlink__doc__,
7082"readlink(path, *, dir_fd=None) -> path\n\n\
7083Return a string representing the path to which the symbolic link points.\n\
7084\n\
7085If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7086 and path should be relative; path will then be relative to that directory.\n\
7087dir_fd may not be implemented on your platform.\n\
7088 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007089#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007090
Guido van Rossumb6775db1994-08-01 11:34:53 +00007091#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007092
Larry Hastings2f936352014-08-05 14:04:04 +10007093/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007094static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007096{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097 path_t path;
7098 int dir_fd = DEFAULT_DIR_FD;
7099 char buffer[MAXPATHLEN];
7100 ssize_t length;
7101 PyObject *return_value = NULL;
7102 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007103
Larry Hastings9cf065c2012-06-22 16:30:09 -07007104 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007105 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7107 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007108 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007109 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007110
Victor Stinner8c62be82010-05-06 00:08:46 +00007111 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007112#ifdef HAVE_READLINKAT
7113 if (dir_fd != DEFAULT_DIR_FD)
7114 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007115 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116#endif
7117 length = readlink(path.narrow, buffer, sizeof(buffer));
7118 Py_END_ALLOW_THREADS
7119
7120 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007121 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007122 goto exit;
7123 }
7124
7125 if (PyUnicode_Check(path.object))
7126 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7127 else
7128 return_value = PyBytes_FromStringAndSize(buffer, length);
7129exit:
7130 path_cleanup(&path);
7131 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007132}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007133
Guido van Rossumb6775db1994-08-01 11:34:53 +00007134#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007135
Larry Hastings2f936352014-08-05 14:04:04 +10007136#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7137
7138static PyObject *
7139win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7140{
7141 wchar_t *path;
7142 DWORD n_bytes_returned;
7143 DWORD io_result;
7144 PyObject *po, *result;
7145 int dir_fd;
7146 HANDLE reparse_point_handle;
7147
7148 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7149 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7150 wchar_t *print_name;
7151
7152 static char *keywords[] = {"path", "dir_fd", NULL};
7153
7154 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7155 &po,
7156 dir_fd_unavailable, &dir_fd
7157 ))
7158 return NULL;
7159
7160 path = PyUnicode_AsUnicode(po);
7161 if (path == NULL)
7162 return NULL;
7163
7164 /* First get a handle to the reparse point */
7165 Py_BEGIN_ALLOW_THREADS
7166 reparse_point_handle = CreateFileW(
7167 path,
7168 0,
7169 0,
7170 0,
7171 OPEN_EXISTING,
7172 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7173 0);
7174 Py_END_ALLOW_THREADS
7175
7176 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7177 return win32_error_object("readlink", po);
7178
7179 Py_BEGIN_ALLOW_THREADS
7180 /* New call DeviceIoControl to read the reparse point */
7181 io_result = DeviceIoControl(
7182 reparse_point_handle,
7183 FSCTL_GET_REPARSE_POINT,
7184 0, 0, /* in buffer */
7185 target_buffer, sizeof(target_buffer),
7186 &n_bytes_returned,
7187 0 /* we're not using OVERLAPPED_IO */
7188 );
7189 CloseHandle(reparse_point_handle);
7190 Py_END_ALLOW_THREADS
7191
7192 if (io_result==0)
7193 return win32_error_object("readlink", po);
7194
7195 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7196 {
7197 PyErr_SetString(PyExc_ValueError,
7198 "not a symbolic link");
7199 return NULL;
7200 }
7201 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7202 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7203
7204 result = PyUnicode_FromWideChar(print_name,
7205 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7206 return result;
7207}
7208
7209#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7210
7211
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007212
Larry Hastings9cf065c2012-06-22 16:30:09 -07007213#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007214
7215#if defined(MS_WINDOWS)
7216
7217/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7218static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7219static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007220
Larry Hastings9cf065c2012-06-22 16:30:09 -07007221static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007222check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007223{
7224 HINSTANCE hKernel32;
7225 /* only recheck */
7226 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7227 return 1;
7228 hKernel32 = GetModuleHandleW(L"KERNEL32");
7229 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7230 "CreateSymbolicLinkW");
7231 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7232 "CreateSymbolicLinkA");
7233 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7234}
7235
Victor Stinner31b3b922013-06-05 01:49:17 +02007236/* Remove the last portion of the path */
7237static void
7238_dirnameW(WCHAR *path)
7239{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007240 WCHAR *ptr;
7241
7242 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007243 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007244 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007245 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007246 }
7247 *ptr = 0;
7248}
7249
Victor Stinner31b3b922013-06-05 01:49:17 +02007250/* Remove the last portion of the path */
7251static void
7252_dirnameA(char *path)
7253{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254 char *ptr;
7255
7256 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007257 for(ptr = path + strlen(path); ptr != path; ptr--) {
7258 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007260 }
7261 *ptr = 0;
7262}
7263
Victor Stinner31b3b922013-06-05 01:49:17 +02007264/* Is this path absolute? */
7265static int
7266_is_absW(const WCHAR *path)
7267{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7269
7270}
7271
Victor Stinner31b3b922013-06-05 01:49:17 +02007272/* Is this path absolute? */
7273static int
7274_is_absA(const char *path)
7275{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007276 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7277
7278}
7279
Victor Stinner31b3b922013-06-05 01:49:17 +02007280/* join root and rest with a backslash */
7281static void
7282_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7283{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007284 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007285
Victor Stinner31b3b922013-06-05 01:49:17 +02007286 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007287 wcscpy(dest_path, rest);
7288 return;
7289 }
7290
7291 root_len = wcslen(root);
7292
7293 wcscpy(dest_path, root);
7294 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007295 dest_path[root_len] = L'\\';
7296 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007297 }
7298 wcscpy(dest_path+root_len, rest);
7299}
7300
Victor Stinner31b3b922013-06-05 01:49:17 +02007301/* join root and rest with a backslash */
7302static void
7303_joinA(char *dest_path, const char *root, const char *rest)
7304{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007305 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007306
Victor Stinner31b3b922013-06-05 01:49:17 +02007307 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308 strcpy(dest_path, rest);
7309 return;
7310 }
7311
7312 root_len = strlen(root);
7313
7314 strcpy(dest_path, root);
7315 if(root_len) {
7316 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007317 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007318 }
7319 strcpy(dest_path+root_len, rest);
7320}
7321
Victor Stinner31b3b922013-06-05 01:49:17 +02007322/* Return True if the path at src relative to dest is a directory */
7323static int
7324_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007325{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007326 WIN32_FILE_ATTRIBUTE_DATA src_info;
7327 WCHAR dest_parent[MAX_PATH];
7328 WCHAR src_resolved[MAX_PATH] = L"";
7329
7330 /* dest_parent = os.path.dirname(dest) */
7331 wcscpy(dest_parent, dest);
7332 _dirnameW(dest_parent);
7333 /* src_resolved = os.path.join(dest_parent, src) */
7334 _joinW(src_resolved, dest_parent, src);
7335 return (
7336 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7337 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7338 );
7339}
7340
Victor Stinner31b3b922013-06-05 01:49:17 +02007341/* Return True if the path at src relative to dest is a directory */
7342static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02007343_check_dirA(const char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007344{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007345 WIN32_FILE_ATTRIBUTE_DATA src_info;
7346 char dest_parent[MAX_PATH];
7347 char src_resolved[MAX_PATH] = "";
7348
7349 /* dest_parent = os.path.dirname(dest) */
7350 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007351 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007352 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007353 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007354 return (
7355 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7356 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7357 );
7358}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007359#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007360
Larry Hastings2f936352014-08-05 14:04:04 +10007361
7362/*[clinic input]
7363os.symlink
7364 src: path_t
7365 dst: path_t
7366 target_is_directory: bool = False
7367 *
7368 dir_fd: dir_fd(requires='symlinkat')=None
7369
7370# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7371
7372Create a symbolic link pointing to src named dst.
7373
7374target_is_directory is required on Windows if the target is to be
7375 interpreted as a directory. (On Windows, symlink requires
7376 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7377 target_is_directory is ignored on non-Windows platforms.
7378
7379If dir_fd is not None, it should be a file descriptor open to a directory,
7380 and path should be relative; path will then be relative to that directory.
7381dir_fd may not be implemented on your platform.
7382 If it is unavailable, using it will raise a NotImplementedError.
7383
7384[clinic start generated code]*/
7385
Larry Hastings2f936352014-08-05 14:04:04 +10007386static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04007387os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst,
7388 int target_is_directory, int dir_fd)
7389/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007390{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007391#ifdef MS_WINDOWS
7392 DWORD result;
7393#else
7394 int result;
7395#endif
7396
Larry Hastings9cf065c2012-06-22 16:30:09 -07007397#ifdef MS_WINDOWS
7398 if (!check_CreateSymbolicLink()) {
7399 PyErr_SetString(PyExc_NotImplementedError,
7400 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007401 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007402 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 if (!win32_can_symlink) {
7404 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007405 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007406 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407#endif
7408
Larry Hastings2f936352014-08-05 14:04:04 +10007409 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007410 PyErr_SetString(PyExc_ValueError,
7411 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007412 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007413 }
7414
7415#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007416
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007418 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007419 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007420 target_is_directory |= _check_dirW(src->wide, dst->wide);
7421 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007423 }
7424 else {
7425 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007426 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7427 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007428 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007429 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007430 Py_END_ALLOW_THREADS
7431
Larry Hastings2f936352014-08-05 14:04:04 +10007432 if (!result)
7433 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434
7435#else
7436
7437 Py_BEGIN_ALLOW_THREADS
7438#if HAVE_SYMLINKAT
7439 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007440 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007441 else
7442#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007443 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007444 Py_END_ALLOW_THREADS
7445
Larry Hastings2f936352014-08-05 14:04:04 +10007446 if (result)
7447 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007448#endif
7449
Larry Hastings2f936352014-08-05 14:04:04 +10007450 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007451}
7452#endif /* HAVE_SYMLINK */
7453
Larry Hastings9cf065c2012-06-22 16:30:09 -07007454
Brian Curtind40e6f72010-07-08 21:39:08 +00007455
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007456
Larry Hastings605a62d2012-06-24 04:33:36 -07007457static PyStructSequence_Field times_result_fields[] = {
7458 {"user", "user time"},
7459 {"system", "system time"},
7460 {"children_user", "user time of children"},
7461 {"children_system", "system time of children"},
7462 {"elapsed", "elapsed time since an arbitrary point in the past"},
7463 {NULL}
7464};
7465
7466PyDoc_STRVAR(times_result__doc__,
7467"times_result: Result from os.times().\n\n\
7468This object may be accessed either as a tuple of\n\
7469 (user, system, children_user, children_system, elapsed),\n\
7470or via the attributes user, system, children_user, children_system,\n\
7471and elapsed.\n\
7472\n\
7473See os.times for more information.");
7474
7475static PyStructSequence_Desc times_result_desc = {
7476 "times_result", /* name */
7477 times_result__doc__, /* doc */
7478 times_result_fields,
7479 5
7480};
7481
7482static PyTypeObject TimesResultType;
7483
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007484#ifdef MS_WINDOWS
7485#define HAVE_TIMES /* mandatory, for the method table */
7486#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007487
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007488#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007489
7490static PyObject *
7491build_times_result(double user, double system,
7492 double children_user, double children_system,
7493 double elapsed)
7494{
7495 PyObject *value = PyStructSequence_New(&TimesResultType);
7496 if (value == NULL)
7497 return NULL;
7498
7499#define SET(i, field) \
7500 { \
7501 PyObject *o = PyFloat_FromDouble(field); \
7502 if (!o) { \
7503 Py_DECREF(value); \
7504 return NULL; \
7505 } \
7506 PyStructSequence_SET_ITEM(value, i, o); \
7507 } \
7508
7509 SET(0, user);
7510 SET(1, system);
7511 SET(2, children_user);
7512 SET(3, children_system);
7513 SET(4, elapsed);
7514
7515#undef SET
7516
7517 return value;
7518}
7519
Larry Hastings605a62d2012-06-24 04:33:36 -07007520
Larry Hastings2f936352014-08-05 14:04:04 +10007521#ifndef MS_WINDOWS
7522#define NEED_TICKS_PER_SECOND
7523static long ticks_per_second = -1;
7524#endif /* MS_WINDOWS */
7525
7526/*[clinic input]
7527os.times
7528
7529Return a collection containing process timing information.
7530
7531The object returned behaves like a named tuple with these fields:
7532 (utime, stime, cutime, cstime, elapsed_time)
7533All fields are floating point numbers.
7534[clinic start generated code]*/
7535
Larry Hastings2f936352014-08-05 14:04:04 +10007536static PyObject *
7537os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007538/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007539#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007540{
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 FILETIME create, exit, kernel, user;
7542 HANDLE hProc;
7543 hProc = GetCurrentProcess();
7544 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7545 /* The fields of a FILETIME structure are the hi and lo part
7546 of a 64-bit value expressed in 100 nanosecond units.
7547 1e7 is one second in such units; 1e-7 the inverse.
7548 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7549 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007550 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007551 (double)(user.dwHighDateTime*429.4967296 +
7552 user.dwLowDateTime*1e-7),
7553 (double)(kernel.dwHighDateTime*429.4967296 +
7554 kernel.dwLowDateTime*1e-7),
7555 (double)0,
7556 (double)0,
7557 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007558}
Larry Hastings2f936352014-08-05 14:04:04 +10007559#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007560{
Larry Hastings2f936352014-08-05 14:04:04 +10007561
7562
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007563 struct tms t;
7564 clock_t c;
7565 errno = 0;
7566 c = times(&t);
7567 if (c == (clock_t) -1)
7568 return posix_error();
7569 return build_times_result(
7570 (double)t.tms_utime / ticks_per_second,
7571 (double)t.tms_stime / ticks_per_second,
7572 (double)t.tms_cutime / ticks_per_second,
7573 (double)t.tms_cstime / ticks_per_second,
7574 (double)c / ticks_per_second);
7575}
Larry Hastings2f936352014-08-05 14:04:04 +10007576#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007577#endif /* HAVE_TIMES */
7578
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007579
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007580#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007581/*[clinic input]
7582os.getsid
7583
7584 pid: pid_t
7585 /
7586
7587Call the system call getsid(pid) and return the result.
7588[clinic start generated code]*/
7589
Larry Hastings2f936352014-08-05 14:04:04 +10007590static PyObject *
7591os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007592/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007593{
Victor Stinner8c62be82010-05-06 00:08:46 +00007594 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007595 sid = getsid(pid);
7596 if (sid < 0)
7597 return posix_error();
7598 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007599}
7600#endif /* HAVE_GETSID */
7601
7602
Guido van Rossumb6775db1994-08-01 11:34:53 +00007603#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007604/*[clinic input]
7605os.setsid
7606
7607Call the system call setsid().
7608[clinic start generated code]*/
7609
Larry Hastings2f936352014-08-05 14:04:04 +10007610static PyObject *
7611os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007612/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007613{
Victor Stinner8c62be82010-05-06 00:08:46 +00007614 if (setsid() < 0)
7615 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007616 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007617}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007618#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007619
Larry Hastings2f936352014-08-05 14:04:04 +10007620
Guido van Rossumb6775db1994-08-01 11:34:53 +00007621#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007622/*[clinic input]
7623os.setpgid
7624
7625 pid: pid_t
7626 pgrp: pid_t
7627 /
7628
7629Call the system call setpgid(pid, pgrp).
7630[clinic start generated code]*/
7631
Larry Hastings2f936352014-08-05 14:04:04 +10007632static PyObject *
7633os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007634/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007635{
Victor Stinner8c62be82010-05-06 00:08:46 +00007636 if (setpgid(pid, pgrp) < 0)
7637 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007638 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007639}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007640#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007641
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007642
Guido van Rossumb6775db1994-08-01 11:34:53 +00007643#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007644/*[clinic input]
7645os.tcgetpgrp
7646
7647 fd: int
7648 /
7649
7650Return the process group associated with the terminal specified by fd.
7651[clinic start generated code]*/
7652
Larry Hastings2f936352014-08-05 14:04:04 +10007653static PyObject *
7654os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007655/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007656{
7657 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007658 if (pgid < 0)
7659 return posix_error();
7660 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007661}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007662#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007663
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007664
Guido van Rossumb6775db1994-08-01 11:34:53 +00007665#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007666/*[clinic input]
7667os.tcsetpgrp
7668
7669 fd: int
7670 pgid: pid_t
7671 /
7672
7673Set the process group associated with the terminal specified by fd.
7674[clinic start generated code]*/
7675
Larry Hastings2f936352014-08-05 14:04:04 +10007676static PyObject *
7677os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007678/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007679{
Victor Stinner8c62be82010-05-06 00:08:46 +00007680 if (tcsetpgrp(fd, pgid) < 0)
7681 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007682 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007683}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007684#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007685
Guido van Rossum687dd131993-05-17 08:34:16 +00007686/* Functions acting on file descriptors */
7687
Victor Stinnerdaf45552013-08-28 00:53:59 +02007688#ifdef O_CLOEXEC
7689extern int _Py_open_cloexec_works;
7690#endif
7691
Larry Hastings2f936352014-08-05 14:04:04 +10007692
7693/*[clinic input]
7694os.open -> int
7695 path: path_t
7696 flags: int
7697 mode: int = 0o777
7698 *
7699 dir_fd: dir_fd(requires='openat') = None
7700
7701# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7702
7703Open a file for low level IO. Returns a file descriptor (integer).
7704
7705If dir_fd is not None, it should be a file descriptor open to a directory,
7706 and path should be relative; path will then be relative to that directory.
7707dir_fd may not be implemented on your platform.
7708 If it is unavailable, using it will raise a NotImplementedError.
7709[clinic start generated code]*/
7710
Larry Hastings2f936352014-08-05 14:04:04 +10007711static int
Larry Hastings89964c42015-04-14 18:07:59 -04007712os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode,
7713 int dir_fd)
7714/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007715{
7716 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007717 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007718
Victor Stinnerdaf45552013-08-28 00:53:59 +02007719#ifdef O_CLOEXEC
7720 int *atomic_flag_works = &_Py_open_cloexec_works;
7721#elif !defined(MS_WINDOWS)
7722 int *atomic_flag_works = NULL;
7723#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007724
Victor Stinnerdaf45552013-08-28 00:53:59 +02007725#ifdef MS_WINDOWS
7726 flags |= O_NOINHERIT;
7727#elif defined(O_CLOEXEC)
7728 flags |= O_CLOEXEC;
7729#endif
7730
Steve Dower8fc89802015-04-12 00:26:27 -04007731 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007732 do {
7733 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007734#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007735 if (path->wide)
7736 fd = _wopen(path->wide, flags, mode);
7737 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738#endif
7739#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007740 if (dir_fd != DEFAULT_DIR_FD)
7741 fd = openat(dir_fd, path->narrow, flags, mode);
7742 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007744 fd = open(path->narrow, flags, mode);
7745 Py_END_ALLOW_THREADS
7746 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007747 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007748
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007749 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007750 if (!async_err)
7751 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007752 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007753 }
7754
Victor Stinnerdaf45552013-08-28 00:53:59 +02007755#ifndef MS_WINDOWS
7756 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7757 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007758 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007759 }
7760#endif
7761
Larry Hastings2f936352014-08-05 14:04:04 +10007762 return fd;
7763}
7764
7765
7766/*[clinic input]
7767os.close
7768
7769 fd: int
7770
7771Close a file descriptor.
7772[clinic start generated code]*/
7773
Barry Warsaw53699e91996-12-10 23:23:01 +00007774static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007775os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007776/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007777{
Larry Hastings2f936352014-08-05 14:04:04 +10007778 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 if (!_PyVerify_fd(fd))
7780 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007781 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7782 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7783 * for more details.
7784 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007785 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007786 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007787 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007788 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007789 Py_END_ALLOW_THREADS
7790 if (res < 0)
7791 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007792 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007793}
7794
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007795
Larry Hastings2f936352014-08-05 14:04:04 +10007796/*[clinic input]
7797os.closerange
7798
7799 fd_low: int
7800 fd_high: int
7801 /
7802
7803Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7804[clinic start generated code]*/
7805
Larry Hastings2f936352014-08-05 14:04:04 +10007806static PyObject *
7807os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007808/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007809{
7810 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007811 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007812 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007813 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007814 if (_PyVerify_fd(i))
7815 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007816 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007817 Py_END_ALLOW_THREADS
7818 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007819}
7820
7821
Larry Hastings2f936352014-08-05 14:04:04 +10007822/*[clinic input]
7823os.dup -> int
7824
7825 fd: int
7826 /
7827
7828Return a duplicate of a file descriptor.
7829[clinic start generated code]*/
7830
Larry Hastings2f936352014-08-05 14:04:04 +10007831static int
7832os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007833/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007834{
7835 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007836}
7837
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007838
Larry Hastings2f936352014-08-05 14:04:04 +10007839/*[clinic input]
7840os.dup2
7841 fd: int
7842 fd2: int
7843 inheritable: bool=True
7844
7845Duplicate file descriptor.
7846[clinic start generated code]*/
7847
Larry Hastings2f936352014-08-05 14:04:04 +10007848static PyObject *
7849os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007850/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007851{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007852 int res;
7853#if defined(HAVE_DUP3) && \
7854 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7855 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7856 int dup3_works = -1;
7857#endif
7858
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 if (!_PyVerify_fd_dup2(fd, fd2))
7860 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007861
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007862 /* dup2() can fail with EINTR if the target FD is already open, because it
7863 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7864 * upon close(), and therefore below.
7865 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007866#ifdef MS_WINDOWS
7867 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007868 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007869 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007870 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007871 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007872 if (res < 0)
7873 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007874
7875 /* Character files like console cannot be make non-inheritable */
7876 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7877 close(fd2);
7878 return NULL;
7879 }
7880
7881#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7882 Py_BEGIN_ALLOW_THREADS
7883 if (!inheritable)
7884 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7885 else
7886 res = dup2(fd, fd2);
7887 Py_END_ALLOW_THREADS
7888 if (res < 0)
7889 return posix_error();
7890
7891#else
7892
7893#ifdef HAVE_DUP3
7894 if (!inheritable && dup3_works != 0) {
7895 Py_BEGIN_ALLOW_THREADS
7896 res = dup3(fd, fd2, O_CLOEXEC);
7897 Py_END_ALLOW_THREADS
7898 if (res < 0) {
7899 if (dup3_works == -1)
7900 dup3_works = (errno != ENOSYS);
7901 if (dup3_works)
7902 return posix_error();
7903 }
7904 }
7905
7906 if (inheritable || dup3_works == 0)
7907 {
7908#endif
7909 Py_BEGIN_ALLOW_THREADS
7910 res = dup2(fd, fd2);
7911 Py_END_ALLOW_THREADS
7912 if (res < 0)
7913 return posix_error();
7914
7915 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7916 close(fd2);
7917 return NULL;
7918 }
7919#ifdef HAVE_DUP3
7920 }
7921#endif
7922
7923#endif
7924
Larry Hastings2f936352014-08-05 14:04:04 +10007925 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007926}
7927
Larry Hastings2f936352014-08-05 14:04:04 +10007928
Ross Lagerwall7807c352011-03-17 20:20:30 +02007929#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007930/*[clinic input]
7931os.lockf
7932
7933 fd: int
7934 An open file descriptor.
7935 command: int
7936 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7937 length: Py_off_t
7938 The number of bytes to lock, starting at the current position.
7939 /
7940
7941Apply, test or remove a POSIX lock on an open file descriptor.
7942
7943[clinic start generated code]*/
7944
Larry Hastings2f936352014-08-05 14:04:04 +10007945static PyObject *
7946os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007947/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007948{
7949 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007950
7951 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007952 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007953 Py_END_ALLOW_THREADS
7954
7955 if (res < 0)
7956 return posix_error();
7957
7958 Py_RETURN_NONE;
7959}
Larry Hastings2f936352014-08-05 14:04:04 +10007960#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007961
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007962
Larry Hastings2f936352014-08-05 14:04:04 +10007963/*[clinic input]
7964os.lseek -> Py_off_t
7965
7966 fd: int
7967 position: Py_off_t
7968 how: int
7969 /
7970
7971Set the position of a file descriptor. Return the new position.
7972
7973Return the new cursor position in number of bytes
7974relative to the beginning of the file.
7975[clinic start generated code]*/
7976
Larry Hastings2f936352014-08-05 14:04:04 +10007977static Py_off_t
7978os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007979/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007980{
7981 Py_off_t result;
7982
7983 if (!_PyVerify_fd(fd)) {
7984 posix_error();
7985 return -1;
7986 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007987#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7989 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007990 case 0: how = SEEK_SET; break;
7991 case 1: how = SEEK_CUR; break;
7992 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007994#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007995
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007997 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007998
Larry Hastings2f936352014-08-05 14:04:04 +10007999 if (!_PyVerify_fd(fd)) {
8000 posix_error();
8001 return -1;
8002 }
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008004 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02008005#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008006 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008007#else
Larry Hastings2f936352014-08-05 14:04:04 +10008008 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00008009#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008010 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008011 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008012 if (result < 0)
8013 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008014
Larry Hastings2f936352014-08-05 14:04:04 +10008015 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008016}
8017
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008018
Larry Hastings2f936352014-08-05 14:04:04 +10008019/*[clinic input]
8020os.read
8021 fd: int
8022 length: Py_ssize_t
8023 /
8024
8025Read from a file descriptor. Returns a bytes object.
8026[clinic start generated code]*/
8027
Larry Hastings2f936352014-08-05 14:04:04 +10008028static PyObject *
8029os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008030/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008031{
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 Py_ssize_t n;
8033 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008034
8035 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008036 errno = EINVAL;
8037 return posix_error();
8038 }
Larry Hastings2f936352014-08-05 14:04:04 +10008039
8040#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008041 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008042 if (length > INT_MAX)
8043 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008044#endif
8045
8046 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 if (buffer == NULL)
8048 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008049
Victor Stinner66aab0c2015-03-19 22:53:20 +01008050 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8051 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008052 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008053 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008054 }
Larry Hastings2f936352014-08-05 14:04:04 +10008055
8056 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008057 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008058
Victor Stinner8c62be82010-05-06 00:08:46 +00008059 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008060}
8061
Ross Lagerwall7807c352011-03-17 20:20:30 +02008062#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8063 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008064static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008065iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8066{
8067 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008068 Py_ssize_t blen, total = 0;
8069
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008070 *iov = PyMem_New(struct iovec, cnt);
8071 if (*iov == NULL) {
8072 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008073 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008074 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008075
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008076 *buf = PyMem_New(Py_buffer, cnt);
8077 if (*buf == NULL) {
8078 PyMem_Del(*iov);
8079 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008080 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081 }
8082
8083 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008084 PyObject *item = PySequence_GetItem(seq, i);
8085 if (item == NULL)
8086 goto fail;
8087 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8088 Py_DECREF(item);
8089 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008090 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008091 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008092 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008093 blen = (*buf)[i].len;
8094 (*iov)[i].iov_len = blen;
8095 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008096 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008097 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008098
8099fail:
8100 PyMem_Del(*iov);
8101 for (j = 0; j < i; j++) {
8102 PyBuffer_Release(&(*buf)[j]);
8103 }
8104 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008105 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008106}
8107
8108static void
8109iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8110{
8111 int i;
8112 PyMem_Del(iov);
8113 for (i = 0; i < cnt; i++) {
8114 PyBuffer_Release(&buf[i]);
8115 }
8116 PyMem_Del(buf);
8117}
8118#endif
8119
Larry Hastings2f936352014-08-05 14:04:04 +10008120
Ross Lagerwall7807c352011-03-17 20:20:30 +02008121#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008122/*[clinic input]
8123os.readv -> Py_ssize_t
8124
8125 fd: int
8126 buffers: object
8127 /
8128
8129Read from a file descriptor fd into an iterable of buffers.
8130
8131The buffers should be mutable buffers accepting bytes.
8132readv will transfer data into each buffer until it is full
8133and then move on to the next buffer in the sequence to hold
8134the rest of the data.
8135
8136readv returns the total number of bytes read,
8137which may be less than the total capacity of all the buffers.
8138[clinic start generated code]*/
8139
Larry Hastings2f936352014-08-05 14:04:04 +10008140static Py_ssize_t
8141os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008142/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008143{
8144 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008146 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008147 struct iovec *iov;
8148 Py_buffer *buf;
8149
Larry Hastings2f936352014-08-05 14:04:04 +10008150 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151 PyErr_SetString(PyExc_TypeError,
8152 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008153 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008154 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008155
Larry Hastings2f936352014-08-05 14:04:04 +10008156 cnt = PySequence_Size(buffers);
8157
8158 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8159 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008160
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008161 do {
8162 Py_BEGIN_ALLOW_THREADS
8163 n = readv(fd, iov, cnt);
8164 Py_END_ALLOW_THREADS
8165 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008166
8167 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008168 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008169 if (!async_err)
8170 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008171 return -1;
8172 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008173
Larry Hastings2f936352014-08-05 14:04:04 +10008174 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175}
Larry Hastings2f936352014-08-05 14:04:04 +10008176#endif /* HAVE_READV */
8177
Ross Lagerwall7807c352011-03-17 20:20:30 +02008178
8179#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008180/*[clinic input]
8181# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8182os.pread
8183
8184 fd: int
8185 length: int
8186 offset: Py_off_t
8187 /
8188
8189Read a number of bytes from a file descriptor starting at a particular offset.
8190
8191Read length bytes from file descriptor fd, starting at offset bytes from
8192the beginning of the file. The file offset remains unchanged.
8193[clinic start generated code]*/
8194
Larry Hastings2f936352014-08-05 14:04:04 +10008195static PyObject *
8196os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008197/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008198{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008199 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008200 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008201 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008202
Larry Hastings2f936352014-08-05 14:04:04 +10008203 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008204 errno = EINVAL;
8205 return posix_error();
8206 }
Larry Hastings2f936352014-08-05 14:04:04 +10008207 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208 if (buffer == NULL)
8209 return NULL;
8210 if (!_PyVerify_fd(fd)) {
8211 Py_DECREF(buffer);
8212 return posix_error();
8213 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008214
8215 do {
8216 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008217 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008218 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008219 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008220 Py_END_ALLOW_THREADS
8221 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8222
Ross Lagerwall7807c352011-03-17 20:20:30 +02008223 if (n < 0) {
8224 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008225 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008226 }
Larry Hastings2f936352014-08-05 14:04:04 +10008227 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008228 _PyBytes_Resize(&buffer, n);
8229 return buffer;
8230}
Larry Hastings2f936352014-08-05 14:04:04 +10008231#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008232
Larry Hastings2f936352014-08-05 14:04:04 +10008233
8234/*[clinic input]
8235os.write -> Py_ssize_t
8236
8237 fd: int
8238 data: Py_buffer
8239 /
8240
8241Write a bytes object to a file descriptor.
8242[clinic start generated code]*/
8243
Larry Hastings2f936352014-08-05 14:04:04 +10008244static Py_ssize_t
8245os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008246/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008247{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008248 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008249}
8250
8251#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008252PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008253"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008254sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008256Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008257
Larry Hastings2f936352014-08-05 14:04:04 +10008258/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008259static PyObject *
8260posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8261{
8262 int in, out;
8263 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008264 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008265 off_t offset;
8266
8267#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8268#ifndef __APPLE__
8269 Py_ssize_t len;
8270#endif
8271 PyObject *headers = NULL, *trailers = NULL;
8272 Py_buffer *hbuf, *tbuf;
8273 off_t sbytes;
8274 struct sf_hdtr sf;
8275 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008276 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008277 static char *keywords[] = {"out", "in",
8278 "offset", "count",
8279 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008281 sf.headers = NULL;
8282 sf.trailers = NULL;
8283
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008284#ifdef __APPLE__
8285 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008286 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008287#else
8288 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008289 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008290#endif
8291 &headers, &trailers, &flags))
8292 return NULL;
8293 if (headers != NULL) {
8294 if (!PySequence_Check(headers)) {
8295 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008296 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008297 return NULL;
8298 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008299 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008300 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008301 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008302 (i = iov_setup(&(sf.headers), &hbuf,
8303 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008305#ifdef __APPLE__
8306 sbytes += i;
8307#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308 }
8309 }
8310 if (trailers != NULL) {
8311 if (!PySequence_Check(trailers)) {
8312 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008313 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314 return NULL;
8315 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008316 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008317 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008318 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008319 (i = iov_setup(&(sf.trailers), &tbuf,
8320 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008322#ifdef __APPLE__
8323 sbytes += i;
8324#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325 }
8326 }
8327
Steve Dower8fc89802015-04-12 00:26:27 -04008328 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008329 do {
8330 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008331#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008332 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008333#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008334 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008335#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008336 Py_END_ALLOW_THREADS
8337 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008338 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008339
8340 if (sf.headers != NULL)
8341 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8342 if (sf.trailers != NULL)
8343 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8344
8345 if (ret < 0) {
8346 if ((errno == EAGAIN) || (errno == EBUSY)) {
8347 if (sbytes != 0) {
8348 // some data has been sent
8349 goto done;
8350 }
8351 else {
8352 // no data has been sent; upper application is supposed
8353 // to retry on EAGAIN or EBUSY
8354 return posix_error();
8355 }
8356 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008357 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008358 }
8359 goto done;
8360
8361done:
8362 #if !defined(HAVE_LARGEFILE_SUPPORT)
8363 return Py_BuildValue("l", sbytes);
8364 #else
8365 return Py_BuildValue("L", sbytes);
8366 #endif
8367
8368#else
8369 Py_ssize_t count;
8370 PyObject *offobj;
8371 static char *keywords[] = {"out", "in",
8372 "offset", "count", NULL};
8373 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8374 keywords, &out, &in, &offobj, &count))
8375 return NULL;
8376#ifdef linux
8377 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008378 do {
8379 Py_BEGIN_ALLOW_THREADS
8380 ret = sendfile(out, in, NULL, count);
8381 Py_END_ALLOW_THREADS
8382 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008383 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008384 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008385 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 }
8387#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008388 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008389 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008390
8391 do {
8392 Py_BEGIN_ALLOW_THREADS
8393 ret = sendfile(out, in, &offset, count);
8394 Py_END_ALLOW_THREADS
8395 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008396 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008397 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008398 return Py_BuildValue("n", ret);
8399#endif
8400}
Larry Hastings2f936352014-08-05 14:04:04 +10008401#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008402
Larry Hastings2f936352014-08-05 14:04:04 +10008403
8404/*[clinic input]
8405os.fstat
8406
8407 fd : int
8408
8409Perform a stat system call on the given file descriptor.
8410
8411Like stat(), but for an open file descriptor.
8412Equivalent to os.stat(fd).
8413[clinic start generated code]*/
8414
Larry Hastings2f936352014-08-05 14:04:04 +10008415static PyObject *
8416os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008417/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008418{
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 STRUCT_STAT st;
8420 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008421 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008422
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008423 do {
8424 Py_BEGIN_ALLOW_THREADS
8425 res = FSTAT(fd, &st);
8426 Py_END_ALLOW_THREADS
8427 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008428 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008429#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008430 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008431#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008432 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008433#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008434 }
Tim Peters5aa91602002-01-30 05:46:57 +00008435
Victor Stinner4195b5c2012-02-08 23:03:19 +01008436 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008437}
8438
Larry Hastings2f936352014-08-05 14:04:04 +10008439
8440/*[clinic input]
8441os.isatty -> bool
8442 fd: int
8443 /
8444
8445Return True if the fd is connected to a terminal.
8446
8447Return True if the file descriptor is an open file descriptor
8448connected to the slave end of a terminal.
8449[clinic start generated code]*/
8450
Larry Hastings2f936352014-08-05 14:04:04 +10008451static int
8452os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008453/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008454{
Steve Dower8fc89802015-04-12 00:26:27 -04008455 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008456 if (!_PyVerify_fd(fd))
8457 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008458 _Py_BEGIN_SUPPRESS_IPH
8459 return_value = isatty(fd);
8460 _Py_END_SUPPRESS_IPH
8461 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008462}
8463
8464
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008465#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008466/*[clinic input]
8467os.pipe
8468
8469Create a pipe.
8470
8471Returns a tuple of two file descriptors:
8472 (read_fd, write_fd)
8473[clinic start generated code]*/
8474
Larry Hastings2f936352014-08-05 14:04:04 +10008475static PyObject *
8476os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008477/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008478{
Victor Stinner8c62be82010-05-06 00:08:46 +00008479 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008480#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008481 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008482 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008483 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008484#else
8485 int res;
8486#endif
8487
8488#ifdef MS_WINDOWS
8489 attr.nLength = sizeof(attr);
8490 attr.lpSecurityDescriptor = NULL;
8491 attr.bInheritHandle = FALSE;
8492
8493 Py_BEGIN_ALLOW_THREADS
8494 ok = CreatePipe(&read, &write, &attr, 0);
8495 if (ok) {
8496 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8497 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8498 if (fds[0] == -1 || fds[1] == -1) {
8499 CloseHandle(read);
8500 CloseHandle(write);
8501 ok = 0;
8502 }
8503 }
8504 Py_END_ALLOW_THREADS
8505
Victor Stinner8c62be82010-05-06 00:08:46 +00008506 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008507 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008508#else
8509
8510#ifdef HAVE_PIPE2
8511 Py_BEGIN_ALLOW_THREADS
8512 res = pipe2(fds, O_CLOEXEC);
8513 Py_END_ALLOW_THREADS
8514
8515 if (res != 0 && errno == ENOSYS)
8516 {
8517#endif
8518 Py_BEGIN_ALLOW_THREADS
8519 res = pipe(fds);
8520 Py_END_ALLOW_THREADS
8521
8522 if (res == 0) {
8523 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8524 close(fds[0]);
8525 close(fds[1]);
8526 return NULL;
8527 }
8528 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8529 close(fds[0]);
8530 close(fds[1]);
8531 return NULL;
8532 }
8533 }
8534#ifdef HAVE_PIPE2
8535 }
8536#endif
8537
8538 if (res != 0)
8539 return PyErr_SetFromErrno(PyExc_OSError);
8540#endif /* !MS_WINDOWS */
8541 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008542}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008543#endif /* HAVE_PIPE */
8544
Larry Hastings2f936352014-08-05 14:04:04 +10008545
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008546#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008547/*[clinic input]
8548os.pipe2
8549
8550 flags: int
8551 /
8552
8553Create a pipe with flags set atomically.
8554
8555Returns a tuple of two file descriptors:
8556 (read_fd, write_fd)
8557
8558flags can be constructed by ORing together one or more of these values:
8559O_NONBLOCK, O_CLOEXEC.
8560[clinic start generated code]*/
8561
Larry Hastings2f936352014-08-05 14:04:04 +10008562static PyObject *
8563os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008564/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008565{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008566 int fds[2];
8567 int res;
8568
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008569 res = pipe2(fds, flags);
8570 if (res != 0)
8571 return posix_error();
8572 return Py_BuildValue("(ii)", fds[0], fds[1]);
8573}
8574#endif /* HAVE_PIPE2 */
8575
Larry Hastings2f936352014-08-05 14:04:04 +10008576
Ross Lagerwall7807c352011-03-17 20:20:30 +02008577#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008578/*[clinic input]
8579os.writev -> Py_ssize_t
8580 fd: int
8581 buffers: object
8582 /
8583
8584Iterate over buffers, and write the contents of each to a file descriptor.
8585
8586Returns the total number of bytes written.
8587buffers must be a sequence of bytes-like objects.
8588[clinic start generated code]*/
8589
Larry Hastings2f936352014-08-05 14:04:04 +10008590static Py_ssize_t
8591os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008592/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008593{
8594 int cnt;
8595 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008596 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008597 struct iovec *iov;
8598 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008599
8600 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008601 PyErr_SetString(PyExc_TypeError,
8602 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008603 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008604 }
Larry Hastings2f936352014-08-05 14:04:04 +10008605 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008606
Larry Hastings2f936352014-08-05 14:04:04 +10008607 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8608 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008609 }
8610
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008611 do {
8612 Py_BEGIN_ALLOW_THREADS
8613 result = writev(fd, iov, cnt);
8614 Py_END_ALLOW_THREADS
8615 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008616
8617 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008618 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008619 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008620
Georg Brandl306336b2012-06-24 12:55:33 +02008621 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008622}
Larry Hastings2f936352014-08-05 14:04:04 +10008623#endif /* HAVE_WRITEV */
8624
8625
8626#ifdef HAVE_PWRITE
8627/*[clinic input]
8628os.pwrite -> Py_ssize_t
8629
8630 fd: int
8631 buffer: Py_buffer
8632 offset: Py_off_t
8633 /
8634
8635Write bytes to a file descriptor starting at a particular offset.
8636
8637Write buffer to fd, starting at offset bytes from the beginning of
8638the file. Returns the number of bytes writte. Does not change the
8639current file offset.
8640[clinic start generated code]*/
8641
Larry Hastings2f936352014-08-05 14:04:04 +10008642static Py_ssize_t
Larry Hastings89964c42015-04-14 18:07:59 -04008643os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
8644 Py_off_t offset)
8645/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008646{
8647 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008649
8650 if (!_PyVerify_fd(fd)) {
8651 posix_error();
8652 return -1;
8653 }
8654
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008655 do {
8656 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008657 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008658 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008659 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008660 Py_END_ALLOW_THREADS
8661 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008662
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008663 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008664 posix_error();
8665 return size;
8666}
8667#endif /* HAVE_PWRITE */
8668
8669
8670#ifdef HAVE_MKFIFO
8671/*[clinic input]
8672os.mkfifo
8673
8674 path: path_t
8675 mode: int=0o666
8676 *
8677 dir_fd: dir_fd(requires='mkfifoat')=None
8678
8679Create a "fifo" (a POSIX named pipe).
8680
8681If dir_fd is not None, it should be a file descriptor open to a directory,
8682 and path should be relative; path will then be relative to that directory.
8683dir_fd may not be implemented on your platform.
8684 If it is unavailable, using it will raise a NotImplementedError.
8685[clinic start generated code]*/
8686
Larry Hastings2f936352014-08-05 14:04:04 +10008687static PyObject *
8688os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008689/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008690{
8691 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008692 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008693
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008694 do {
8695 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008696#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008697 if (dir_fd != DEFAULT_DIR_FD)
8698 result = mkfifoat(dir_fd, path->narrow, mode);
8699 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008700#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008701 result = mkfifo(path->narrow, mode);
8702 Py_END_ALLOW_THREADS
8703 } while (result != 0 && errno == EINTR &&
8704 !(async_err = PyErr_CheckSignals()));
8705 if (result != 0)
8706 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008707
8708 Py_RETURN_NONE;
8709}
8710#endif /* HAVE_MKFIFO */
8711
8712
8713#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8714/*[clinic input]
8715os.mknod
8716
8717 path: path_t
8718 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008719 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008720 *
8721 dir_fd: dir_fd(requires='mknodat')=None
8722
8723Create a node in the file system.
8724
8725Create a node in the file system (file, device special file or named pipe)
8726at path. mode specifies both the permissions to use and the
8727type of node to be created, being combined (bitwise OR) with one of
8728S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8729device defines the newly created device special file (probably using
8730os.makedev()). Otherwise device is ignored.
8731
8732If dir_fd is not None, it should be a file descriptor open to a directory,
8733 and path should be relative; path will then be relative to that directory.
8734dir_fd may not be implemented on your platform.
8735 If it is unavailable, using it will raise a NotImplementedError.
8736[clinic start generated code]*/
8737
Larry Hastings2f936352014-08-05 14:04:04 +10008738static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008739os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
8740 int dir_fd)
8741/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008742{
8743 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008744 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008745
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008746 do {
8747 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008748#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008749 if (dir_fd != DEFAULT_DIR_FD)
8750 result = mknodat(dir_fd, path->narrow, mode, device);
8751 else
Larry Hastings2f936352014-08-05 14:04:04 +10008752#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008753 result = mknod(path->narrow, mode, device);
8754 Py_END_ALLOW_THREADS
8755 } while (result != 0 && errno == EINTR &&
8756 !(async_err = PyErr_CheckSignals()));
8757 if (result != 0)
8758 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008759
8760 Py_RETURN_NONE;
8761}
8762#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8763
8764
8765#ifdef HAVE_DEVICE_MACROS
8766/*[clinic input]
8767os.major -> unsigned_int
8768
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008769 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008770 /
8771
8772Extracts a device major number from a raw device number.
8773[clinic start generated code]*/
8774
Larry Hastings2f936352014-08-05 14:04:04 +10008775static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008776os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008777/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008778{
8779 return major(device);
8780}
8781
8782
8783/*[clinic input]
8784os.minor -> unsigned_int
8785
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008786 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008787 /
8788
8789Extracts a device minor number from a raw device number.
8790[clinic start generated code]*/
8791
Larry Hastings2f936352014-08-05 14:04:04 +10008792static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008793os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008794/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008795{
8796 return minor(device);
8797}
8798
8799
8800/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008801os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008802
8803 major: int
8804 minor: int
8805 /
8806
8807Composes a raw device number from the major and minor device numbers.
8808[clinic start generated code]*/
8809
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008810static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008811os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008812/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008813{
8814 return makedev(major, minor);
8815}
8816#endif /* HAVE_DEVICE_MACROS */
8817
8818
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008819#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008820/*[clinic input]
8821os.ftruncate
8822
8823 fd: int
8824 length: Py_off_t
8825 /
8826
8827Truncate a file, specified by file descriptor, to a specific length.
8828[clinic start generated code]*/
8829
Larry Hastings2f936352014-08-05 14:04:04 +10008830static PyObject *
8831os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008832/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008833{
8834 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008835 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008836
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008837 if (!_PyVerify_fd(fd))
8838 return posix_error();
8839
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008840 do {
8841 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008842 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008843#ifdef MS_WINDOWS
8844 result = _chsize_s(fd, length);
8845#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008846 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008847#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008848 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008849 Py_END_ALLOW_THREADS
8850 } while (result != 0 && errno == EINTR &&
8851 !(async_err = PyErr_CheckSignals()));
8852 if (result != 0)
8853 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008854 Py_RETURN_NONE;
8855}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008856#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008857
8858
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008859#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008860/*[clinic input]
8861os.truncate
8862 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8863 length: Py_off_t
8864
8865Truncate a file, specified by path, to a specific length.
8866
8867On some platforms, path may also be specified as an open file descriptor.
8868 If this functionality is unavailable, using it raises an exception.
8869[clinic start generated code]*/
8870
Larry Hastings2f936352014-08-05 14:04:04 +10008871static PyObject *
8872os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008873/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008874{
8875 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008876#ifdef MS_WINDOWS
8877 int fd;
8878#endif
8879
8880 if (path->fd != -1)
8881 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008882
8883 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008884 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008885#ifdef MS_WINDOWS
8886 if (path->wide)
8887 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008888 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008889 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008890 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008891 result = -1;
8892 else {
8893 result = _chsize_s(fd, length);
8894 close(fd);
8895 if (result < 0)
8896 errno = result;
8897 }
8898#else
8899 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008900#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008901 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008902 Py_END_ALLOW_THREADS
8903 if (result < 0)
8904 return path_error(path);
8905
8906 Py_RETURN_NONE;
8907}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008908#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008909
Ross Lagerwall7807c352011-03-17 20:20:30 +02008910
Victor Stinnerd6b17692014-09-30 12:20:05 +02008911/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8912 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8913 defined, which is the case in Python on AIX. AIX bug report:
8914 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8915#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8916# define POSIX_FADVISE_AIX_BUG
8917#endif
8918
Victor Stinnerec39e262014-09-30 12:35:58 +02008919
Victor Stinnerd6b17692014-09-30 12:20:05 +02008920#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008921/*[clinic input]
8922os.posix_fallocate
8923
8924 fd: int
8925 offset: Py_off_t
8926 length: Py_off_t
8927 /
8928
8929Ensure a file has allocated at least a particular number of bytes on disk.
8930
8931Ensure that the file specified by fd encompasses a range of bytes
8932starting at offset bytes from the beginning and continuing for length bytes.
8933[clinic start generated code]*/
8934
Larry Hastings2f936352014-08-05 14:04:04 +10008935static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008936os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset,
8937 Py_off_t length)
8938/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008939{
8940 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008941 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008942
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008943 do {
8944 Py_BEGIN_ALLOW_THREADS
8945 result = posix_fallocate(fd, offset, length);
8946 Py_END_ALLOW_THREADS
8947 } while (result != 0 && errno == EINTR &&
8948 !(async_err = PyErr_CheckSignals()));
8949 if (result != 0)
8950 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008951 Py_RETURN_NONE;
8952}
Victor Stinnerec39e262014-09-30 12:35:58 +02008953#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008954
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955
Victor Stinnerd6b17692014-09-30 12:20:05 +02008956#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008957/*[clinic input]
8958os.posix_fadvise
8959
8960 fd: int
8961 offset: Py_off_t
8962 length: Py_off_t
8963 advice: int
8964 /
8965
8966Announce an intention to access data in a specific pattern.
8967
8968Announce an intention to access data in a specific pattern, thus allowing
8969the kernel to make optimizations.
8970The advice applies to the region of the file specified by fd starting at
8971offset and continuing for length bytes.
8972advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8973POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8974POSIX_FADV_DONTNEED.
8975[clinic start generated code]*/
8976
Larry Hastings2f936352014-08-05 14:04:04 +10008977static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008978os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset,
8979 Py_off_t length, int advice)
8980/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008981{
8982 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008983 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008984
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008985 do {
8986 Py_BEGIN_ALLOW_THREADS
8987 result = posix_fadvise(fd, offset, length, advice);
8988 Py_END_ALLOW_THREADS
8989 } while (result != 0 && errno == EINTR &&
8990 !(async_err = PyErr_CheckSignals()));
8991 if (result != 0)
8992 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008993 Py_RETURN_NONE;
8994}
Victor Stinnerec39e262014-09-30 12:35:58 +02008995#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008996
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008997#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008998
Fred Drake762e2061999-08-26 17:23:54 +00008999/* Save putenv() parameters as values here, so we can collect them when they
9000 * get re-set with another call for the same key. */
9001static PyObject *posix_putenv_garbage;
9002
Larry Hastings2f936352014-08-05 14:04:04 +10009003static void
9004posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009005{
Larry Hastings2f936352014-08-05 14:04:04 +10009006 /* Install the first arg and newstr in posix_putenv_garbage;
9007 * this will cause previous value to be collected. This has to
9008 * happen after the real putenv() call because the old value
9009 * was still accessible until then. */
9010 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9011 /* really not much we can do; just leak */
9012 PyErr_Clear();
9013 else
9014 Py_DECREF(value);
9015}
9016
9017
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009018#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009019/*[clinic input]
9020os.putenv
9021
9022 name: unicode
9023 value: unicode
9024 /
9025
9026Change or add an environment variable.
9027[clinic start generated code]*/
9028
Larry Hastings2f936352014-08-05 14:04:04 +10009029static PyObject *
9030os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009031/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009032{
9033 wchar_t *env;
9034
9035 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9036 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009037 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009038 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009039 }
Larry Hastings2f936352014-08-05 14:04:04 +10009040 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009041 PyErr_Format(PyExc_ValueError,
9042 "the environment variable is longer than %u characters",
9043 _MAX_ENV);
9044 goto error;
9045 }
9046
Larry Hastings2f936352014-08-05 14:04:04 +10009047 env = PyUnicode_AsUnicode(unicode);
9048 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009049 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009050 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009051 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009052 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009053 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009054
Larry Hastings2f936352014-08-05 14:04:04 +10009055 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009056 Py_RETURN_NONE;
9057
9058error:
Larry Hastings2f936352014-08-05 14:04:04 +10009059 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009060 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009061}
Larry Hastings2f936352014-08-05 14:04:04 +10009062#else /* MS_WINDOWS */
9063/*[clinic input]
9064os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009065
Larry Hastings2f936352014-08-05 14:04:04 +10009066 name: FSConverter
9067 value: FSConverter
9068 /
9069
9070Change or add an environment variable.
9071[clinic start generated code]*/
9072
Larry Hastings2f936352014-08-05 14:04:04 +10009073static PyObject *
9074os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009075/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009076{
9077 PyObject *bytes = NULL;
9078 char *env;
9079 char *name_string = PyBytes_AsString(name);
9080 char *value_string = PyBytes_AsString(value);
9081
9082 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9083 if (bytes == NULL) {
9084 PyErr_NoMemory();
9085 return NULL;
9086 }
9087
9088 env = PyBytes_AS_STRING(bytes);
9089 if (putenv(env)) {
9090 Py_DECREF(bytes);
9091 return posix_error();
9092 }
9093
9094 posix_putenv_garbage_setitem(name, bytes);
9095 Py_RETURN_NONE;
9096}
9097#endif /* MS_WINDOWS */
9098#endif /* HAVE_PUTENV */
9099
9100
9101#ifdef HAVE_UNSETENV
9102/*[clinic input]
9103os.unsetenv
9104 name: FSConverter
9105 /
9106
9107Delete an environment variable.
9108[clinic start generated code]*/
9109
Larry Hastings2f936352014-08-05 14:04:04 +10009110static PyObject *
9111os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009112/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009113{
Victor Stinner984890f2011-11-24 13:53:38 +01009114#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009115 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009116#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009117
Victor Stinner984890f2011-11-24 13:53:38 +01009118#ifdef HAVE_BROKEN_UNSETENV
9119 unsetenv(PyBytes_AS_STRING(name));
9120#else
Victor Stinner65170952011-11-22 22:16:17 +01009121 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009122 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009123 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009124#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009125
Victor Stinner8c62be82010-05-06 00:08:46 +00009126 /* Remove the key from posix_putenv_garbage;
9127 * this will cause it to be collected. This has to
9128 * happen after the real unsetenv() call because the
9129 * old value was still accessible until then.
9130 */
Victor Stinner65170952011-11-22 22:16:17 +01009131 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009132 /* really not much we can do; just leak */
9133 PyErr_Clear();
9134 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009135 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009136}
Larry Hastings2f936352014-08-05 14:04:04 +10009137#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009138
Larry Hastings2f936352014-08-05 14:04:04 +10009139
9140/*[clinic input]
9141os.strerror
9142
9143 code: int
9144 /
9145
9146Translate an error code to a message string.
9147[clinic start generated code]*/
9148
Larry Hastings2f936352014-08-05 14:04:04 +10009149static PyObject *
9150os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009151/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009152{
9153 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009154 if (message == NULL) {
9155 PyErr_SetString(PyExc_ValueError,
9156 "strerror() argument out of range");
9157 return NULL;
9158 }
Victor Stinner1b579672011-12-17 05:47:23 +01009159 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009160}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009161
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009162
Guido van Rossumc9641791998-08-04 15:26:23 +00009163#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009164#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009165/*[clinic input]
9166os.WCOREDUMP -> bool
9167
9168 status: int
9169 /
9170
9171Return True if the process returning status was dumped to a core file.
9172[clinic start generated code]*/
9173
Larry Hastings2f936352014-08-05 14:04:04 +10009174static int
9175os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009176/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009177{
9178 WAIT_TYPE wait_status;
9179 WAIT_STATUS_INT(wait_status) = status;
9180 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009181}
9182#endif /* WCOREDUMP */
9183
Larry Hastings2f936352014-08-05 14:04:04 +10009184
Fred Drake106c1a02002-04-23 15:58:02 +00009185#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009186/*[clinic input]
9187os.WIFCONTINUED -> bool
9188
9189 status: int
9190
9191Return True if a particular process was continued from a job control stop.
9192
9193Return True if the process returning status was continued from a
9194job control stop.
9195[clinic start generated code]*/
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197static int
9198os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009199/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009200{
9201 WAIT_TYPE wait_status;
9202 WAIT_STATUS_INT(wait_status) = status;
9203 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009204}
9205#endif /* WIFCONTINUED */
9206
Larry Hastings2f936352014-08-05 14:04:04 +10009207
Guido van Rossumc9641791998-08-04 15:26:23 +00009208#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009209/*[clinic input]
9210os.WIFSTOPPED -> bool
9211
9212 status: int
9213
9214Return True if the process returning status was stopped.
9215[clinic start generated code]*/
9216
Larry Hastings2f936352014-08-05 14:04:04 +10009217static int
9218os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009219/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009220{
9221 WAIT_TYPE wait_status;
9222 WAIT_STATUS_INT(wait_status) = status;
9223 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009224}
9225#endif /* WIFSTOPPED */
9226
Larry Hastings2f936352014-08-05 14:04:04 +10009227
Guido van Rossumc9641791998-08-04 15:26:23 +00009228#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009229/*[clinic input]
9230os.WIFSIGNALED -> bool
9231
9232 status: int
9233
9234Return True if the process returning status was terminated by a signal.
9235[clinic start generated code]*/
9236
Larry Hastings2f936352014-08-05 14:04:04 +10009237static int
9238os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009239/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009240{
9241 WAIT_TYPE wait_status;
9242 WAIT_STATUS_INT(wait_status) = status;
9243 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009244}
9245#endif /* WIFSIGNALED */
9246
Larry Hastings2f936352014-08-05 14:04:04 +10009247
Guido van Rossumc9641791998-08-04 15:26:23 +00009248#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009249/*[clinic input]
9250os.WIFEXITED -> bool
9251
9252 status: int
9253
9254Return True if the process returning status exited via the exit() system call.
9255[clinic start generated code]*/
9256
Larry Hastings2f936352014-08-05 14:04:04 +10009257static int
9258os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009259/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009260{
9261 WAIT_TYPE wait_status;
9262 WAIT_STATUS_INT(wait_status) = status;
9263 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009264}
9265#endif /* WIFEXITED */
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009268#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009269/*[clinic input]
9270os.WEXITSTATUS -> int
9271
9272 status: int
9273
9274Return the process return code from status.
9275[clinic start generated code]*/
9276
Larry Hastings2f936352014-08-05 14:04:04 +10009277static int
9278os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009279/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009280{
9281 WAIT_TYPE wait_status;
9282 WAIT_STATUS_INT(wait_status) = status;
9283 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009284}
9285#endif /* WEXITSTATUS */
9286
Larry Hastings2f936352014-08-05 14:04:04 +10009287
Guido van Rossumc9641791998-08-04 15:26:23 +00009288#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009289/*[clinic input]
9290os.WTERMSIG -> int
9291
9292 status: int
9293
9294Return the signal that terminated the process that provided the status value.
9295[clinic start generated code]*/
9296
Larry Hastings2f936352014-08-05 14:04:04 +10009297static int
9298os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009299/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009300{
9301 WAIT_TYPE wait_status;
9302 WAIT_STATUS_INT(wait_status) = status;
9303 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009304}
9305#endif /* WTERMSIG */
9306
Larry Hastings2f936352014-08-05 14:04:04 +10009307
Guido van Rossumc9641791998-08-04 15:26:23 +00009308#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009309/*[clinic input]
9310os.WSTOPSIG -> int
9311
9312 status: int
9313
9314Return the signal that stopped the process that provided the status value.
9315[clinic start generated code]*/
9316
Larry Hastings2f936352014-08-05 14:04:04 +10009317static int
9318os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009319/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009320{
9321 WAIT_TYPE wait_status;
9322 WAIT_STATUS_INT(wait_status) = status;
9323 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009324}
9325#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009326#endif /* HAVE_SYS_WAIT_H */
9327
9328
Thomas Wouters477c8d52006-05-27 19:21:47 +00009329#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009330#ifdef _SCO_DS
9331/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9332 needed definitions in sys/statvfs.h */
9333#define _SVID3
9334#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009335#include <sys/statvfs.h>
9336
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009337static PyObject*
9338_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9340 if (v == NULL)
9341 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009342
9343#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009344 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9345 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9346 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9347 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9348 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9349 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9350 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9351 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9352 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9353 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009354#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009355 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9356 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9357 PyStructSequence_SET_ITEM(v, 2,
9358 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9359 PyStructSequence_SET_ITEM(v, 3,
9360 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9361 PyStructSequence_SET_ITEM(v, 4,
9362 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9363 PyStructSequence_SET_ITEM(v, 5,
9364 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9365 PyStructSequence_SET_ITEM(v, 6,
9366 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9367 PyStructSequence_SET_ITEM(v, 7,
9368 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9369 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9370 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009371#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009372 if (PyErr_Occurred()) {
9373 Py_DECREF(v);
9374 return NULL;
9375 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009376
Victor Stinner8c62be82010-05-06 00:08:46 +00009377 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009378}
9379
Larry Hastings2f936352014-08-05 14:04:04 +10009380
9381/*[clinic input]
9382os.fstatvfs
9383 fd: int
9384 /
9385
9386Perform an fstatvfs system call on the given fd.
9387
9388Equivalent to statvfs(fd).
9389[clinic start generated code]*/
9390
Larry Hastings2f936352014-08-05 14:04:04 +10009391static PyObject *
9392os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009393/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009394{
9395 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009396 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009397 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009398
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009399 do {
9400 Py_BEGIN_ALLOW_THREADS
9401 result = fstatvfs(fd, &st);
9402 Py_END_ALLOW_THREADS
9403 } while (result != 0 && errno == EINTR &&
9404 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009405 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009406 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009407
Victor Stinner8c62be82010-05-06 00:08:46 +00009408 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009409}
Larry Hastings2f936352014-08-05 14:04:04 +10009410#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009411
9412
Thomas Wouters477c8d52006-05-27 19:21:47 +00009413#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009414#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009415/*[clinic input]
9416os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009417
Larry Hastings2f936352014-08-05 14:04:04 +10009418 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9419
9420Perform a statvfs system call on the given path.
9421
9422path may always be specified as a string.
9423On some platforms, path may also be specified as an open file descriptor.
9424 If this functionality is unavailable, using it raises an exception.
9425[clinic start generated code]*/
9426
Larry Hastings2f936352014-08-05 14:04:04 +10009427static PyObject *
9428os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009429/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009430{
9431 int result;
9432 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009433
9434 Py_BEGIN_ALLOW_THREADS
9435#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009436 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009437#ifdef __APPLE__
9438 /* handle weak-linking on Mac OS X 10.3 */
9439 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009440 fd_specified("statvfs", path->fd);
9441 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009442 }
9443#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009444 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009445 }
9446 else
9447#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009448 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009449 Py_END_ALLOW_THREADS
9450
9451 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009452 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009453 }
9454
Larry Hastings2f936352014-08-05 14:04:04 +10009455 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009456}
Larry Hastings2f936352014-08-05 14:04:04 +10009457#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9458
Guido van Rossum94f6f721999-01-06 18:42:14 +00009459
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009460#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009461/*[clinic input]
9462os._getdiskusage
9463
9464 path: Py_UNICODE
9465
9466Return disk usage statistics about the given path as a (total, free) tuple.
9467[clinic start generated code]*/
9468
Larry Hastings2f936352014-08-05 14:04:04 +10009469static PyObject *
9470os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009471/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009472{
9473 BOOL retval;
9474 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009475
9476 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009477 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009478 Py_END_ALLOW_THREADS
9479 if (retval == 0)
9480 return PyErr_SetFromWindowsErr(0);
9481
9482 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9483}
Larry Hastings2f936352014-08-05 14:04:04 +10009484#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009485
9486
Fred Drakec9680921999-12-13 16:37:25 +00009487/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9488 * It maps strings representing configuration variable names to
9489 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009490 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009491 * rarely-used constants. There are three separate tables that use
9492 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009493 *
9494 * This code is always included, even if none of the interfaces that
9495 * need it are included. The #if hackery needed to avoid it would be
9496 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009497 */
9498struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009499 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009500 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009501};
9502
Fred Drake12c6e2d1999-12-14 21:25:03 +00009503static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009504conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009505 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009506{
Christian Heimes217cfd12007-12-02 14:31:20 +00009507 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009508 int value = _PyLong_AsInt(arg);
9509 if (value == -1 && PyErr_Occurred())
9510 return 0;
9511 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009512 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009513 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009514 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009515 /* look up the value in the table using a binary search */
9516 size_t lo = 0;
9517 size_t mid;
9518 size_t hi = tablesize;
9519 int cmp;
9520 const char *confname;
9521 if (!PyUnicode_Check(arg)) {
9522 PyErr_SetString(PyExc_TypeError,
9523 "configuration names must be strings or integers");
9524 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009526 confname = _PyUnicode_AsString(arg);
9527 if (confname == NULL)
9528 return 0;
9529 while (lo < hi) {
9530 mid = (lo + hi) / 2;
9531 cmp = strcmp(confname, table[mid].name);
9532 if (cmp < 0)
9533 hi = mid;
9534 else if (cmp > 0)
9535 lo = mid + 1;
9536 else {
9537 *valuep = table[mid].value;
9538 return 1;
9539 }
9540 }
9541 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9542 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009544}
9545
9546
9547#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9548static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009549#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009551#endif
9552#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009554#endif
Fred Drakec9680921999-12-13 16:37:25 +00009555#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
9582#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009583 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009584#endif
9585#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009586 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009587#endif
9588#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009589 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009590#endif
9591#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009592 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009593#endif
9594#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009595 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009596#endif
9597#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009598 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009599#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009600#ifdef _PC_ACL_ENABLED
9601 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9602#endif
9603#ifdef _PC_MIN_HOLE_SIZE
9604 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9605#endif
9606#ifdef _PC_ALLOC_SIZE_MIN
9607 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9608#endif
9609#ifdef _PC_REC_INCR_XFER_SIZE
9610 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9611#endif
9612#ifdef _PC_REC_MAX_XFER_SIZE
9613 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9614#endif
9615#ifdef _PC_REC_MIN_XFER_SIZE
9616 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9617#endif
9618#ifdef _PC_REC_XFER_ALIGN
9619 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9620#endif
9621#ifdef _PC_SYMLINK_MAX
9622 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9623#endif
9624#ifdef _PC_XATTR_ENABLED
9625 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9626#endif
9627#ifdef _PC_XATTR_EXISTS
9628 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9629#endif
9630#ifdef _PC_TIMESTAMP_RESOLUTION
9631 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9632#endif
Fred Drakec9680921999-12-13 16:37:25 +00009633};
9634
Fred Drakec9680921999-12-13 16:37:25 +00009635static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009636conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009637{
9638 return conv_confname(arg, valuep, posix_constants_pathconf,
9639 sizeof(posix_constants_pathconf)
9640 / sizeof(struct constdef));
9641}
9642#endif
9643
Larry Hastings2f936352014-08-05 14:04:04 +10009644
Fred Drakec9680921999-12-13 16:37:25 +00009645#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009646/*[clinic input]
9647os.fpathconf -> long
9648
9649 fd: int
9650 name: path_confname
9651 /
9652
9653Return the configuration limit name for the file descriptor fd.
9654
9655If there is no limit, return -1.
9656[clinic start generated code]*/
9657
Larry Hastings2f936352014-08-05 14:04:04 +10009658static long
9659os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009660/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009661{
9662 long limit;
9663
9664 errno = 0;
9665 limit = fpathconf(fd, name);
9666 if (limit == -1 && errno != 0)
9667 posix_error();
9668
9669 return limit;
9670}
9671#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009672
9673
9674#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009675/*[clinic input]
9676os.pathconf -> long
9677 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9678 name: path_confname
9679
9680Return the configuration limit name for the file or directory path.
9681
9682If there is no limit, return -1.
9683On some platforms, path may also be specified as an open file descriptor.
9684 If this functionality is unavailable, using it raises an exception.
9685[clinic start generated code]*/
9686
Larry Hastings2f936352014-08-05 14:04:04 +10009687static long
9688os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009689/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009690{
Victor Stinner8c62be82010-05-06 00:08:46 +00009691 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009692
Victor Stinner8c62be82010-05-06 00:08:46 +00009693 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009694#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009695 if (path->fd != -1)
9696 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009697 else
9698#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009699 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 if (limit == -1 && errno != 0) {
9701 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009702 /* could be a path or name problem */
9703 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009704 else
Larry Hastings2f936352014-08-05 14:04:04 +10009705 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 }
Larry Hastings2f936352014-08-05 14:04:04 +10009707
9708 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009709}
Larry Hastings2f936352014-08-05 14:04:04 +10009710#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009711
9712#ifdef HAVE_CONFSTR
9713static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009714#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009717#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009719#endif
9720#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009722#endif
Fred Draked86ed291999-12-15 15:34:33 +00009723#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009725#endif
9726#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009728#endif
9729#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009731#endif
9732#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009734#endif
Fred Drakec9680921999-12-13 16:37:25 +00009735#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
9741#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009743#endif
9744#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
9747#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009749#endif
9750#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009752#endif
9753#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009755#endif
9756#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009758#endif
Fred Draked86ed291999-12-15 15:34:33 +00009759#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009761#endif
Fred Drakec9680921999-12-13 16:37:25 +00009762#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
Fred Draked86ed291999-12-15 15:34:33 +00009765#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009767#endif
9768#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009770#endif
9771#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009773#endif
9774#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009776#endif
Fred Drakec9680921999-12-13 16:37:25 +00009777#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
9807#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009809#endif
9810#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009812#endif
9813#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009815#endif
9816#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009818#endif
9819#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009821#endif
9822#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009824#endif
Fred Draked86ed291999-12-15 15:34:33 +00009825#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009827#endif
9828#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009830#endif
9831#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009833#endif
9834#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009836#endif
9837#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009839#endif
9840#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009842#endif
9843#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009845#endif
9846#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009847 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009848#endif
9849#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009850 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009851#endif
9852#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009853 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009854#endif
9855#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009856 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009857#endif
9858#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009859 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009860#endif
9861#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009862 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009863#endif
Fred Drakec9680921999-12-13 16:37:25 +00009864};
9865
9866static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009867conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009868{
9869 return conv_confname(arg, valuep, posix_constants_confstr,
9870 sizeof(posix_constants_confstr)
9871 / sizeof(struct constdef));
9872}
9873
Larry Hastings2f936352014-08-05 14:04:04 +10009874
9875/*[clinic input]
9876os.confstr
9877
9878 name: confstr_confname
9879 /
9880
9881Return a string-valued system configuration variable.
9882[clinic start generated code]*/
9883
Larry Hastings2f936352014-08-05 14:04:04 +10009884static PyObject *
9885os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009886/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009887{
9888 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009889 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009890 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009891
Victor Stinnercb043522010-09-10 23:49:04 +00009892 errno = 0;
9893 len = confstr(name, buffer, sizeof(buffer));
9894 if (len == 0) {
9895 if (errno) {
9896 posix_error();
9897 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009898 }
9899 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009900 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009901 }
9902 }
Victor Stinnercb043522010-09-10 23:49:04 +00009903
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009904 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009905 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009906 char *buf = PyMem_Malloc(len);
9907 if (buf == NULL)
9908 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009909 len2 = confstr(name, buf, len);
9910 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009911 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009912 PyMem_Free(buf);
9913 }
9914 else
9915 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009916 return result;
9917}
Larry Hastings2f936352014-08-05 14:04:04 +10009918#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009919
9920
9921#ifdef HAVE_SYSCONF
9922static struct constdef posix_constants_sysconf[] = {
9923#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
9935#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009937#endif
9938#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009940#endif
9941#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
9944#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
Fred Draked86ed291999-12-15 15:34:33 +00009953#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009955#endif
9956#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009958#endif
Fred Drakec9680921999-12-13 16:37:25 +00009959#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009961#endif
Fred Drakec9680921999-12-13 16:37:25 +00009962#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
Fred Draked86ed291999-12-15 15:34:33 +00009977#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009979#endif
Fred Drakec9680921999-12-13 16:37:25 +00009980#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
Fred Draked86ed291999-12-15 15:34:33 +00009995#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009997#endif
Fred Drakec9680921999-12-13 16:37:25 +00009998#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
10049#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010051#endif
10052#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
10061#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010063#endif
10064#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
Fred Draked86ed291999-12-15 15:34:33 +000010067#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010069#endif
Fred Drakec9680921999-12-13 16:37:25 +000010070#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010072#endif
10073#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
Fred Draked86ed291999-12-15 15:34:33 +000010079#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010081#endif
Fred Drakec9680921999-12-13 16:37:25 +000010082#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
Fred Draked86ed291999-12-15 15:34:33 +000010085#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010087#endif
10088#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010090#endif
Fred Drakec9680921999-12-13 16:37:25 +000010091#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
Fred Draked86ed291999-12-15 15:34:33 +000010103#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010105#endif
Fred Drakec9680921999-12-13 16:37:25 +000010106#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
10109#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010111#endif
10112#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
10118#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010120#endif
10121#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
Fred Draked86ed291999-12-15 15:34:33 +000010127#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010129#endif
Fred Drakec9680921999-12-13 16:37:25 +000010130#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
Fred Draked86ed291999-12-15 15:34:33 +000010136#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010138#endif
Fred Drakec9680921999-12-13 16:37:25 +000010139#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
10148#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010150#endif
10151#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010153#endif
10154#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
Fred Draked86ed291999-12-15 15:34:33 +000010166#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010168#endif
10169#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010171#endif
Fred Drakec9680921999-12-13 16:37:25 +000010172#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
10259#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010261#endif
10262#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
Fred Draked86ed291999-12-15 15:34:33 +000010277#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010279#endif
Fred Drakec9680921999-12-13 16:37:25 +000010280#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010398 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010399#endif
10400#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010401 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010402#endif
10403#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010404 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010405#endif
10406#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010407 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010408#endif
10409#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010410 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010411#endif
10412#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010413 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010414#endif
10415};
10416
10417static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010418conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010419{
10420 return conv_confname(arg, valuep, posix_constants_sysconf,
10421 sizeof(posix_constants_sysconf)
10422 / sizeof(struct constdef));
10423}
10424
Larry Hastings2f936352014-08-05 14:04:04 +100010425
10426/*[clinic input]
10427os.sysconf -> long
10428 name: sysconf_confname
10429 /
10430
10431Return an integer-valued system configuration variable.
10432[clinic start generated code]*/
10433
Larry Hastings2f936352014-08-05 14:04:04 +100010434static long
10435os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010436/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010437{
10438 long value;
10439
10440 errno = 0;
10441 value = sysconf(name);
10442 if (value == -1 && errno != 0)
10443 posix_error();
10444 return value;
10445}
10446#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010447
10448
Fred Drakebec628d1999-12-15 18:31:10 +000010449/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010450 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010451 * the exported dictionaries that are used to publish information about the
10452 * names available on the host platform.
10453 *
10454 * Sorting the table at runtime ensures that the table is properly ordered
10455 * when used, even for platforms we're not able to test on. It also makes
10456 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010457 */
Fred Drakebec628d1999-12-15 18:31:10 +000010458
10459static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010460cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010461{
10462 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010464 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010466
10467 return strcmp(c1->name, c2->name);
10468}
10469
10470static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010471setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010472 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010473{
Fred Drakebec628d1999-12-15 18:31:10 +000010474 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010475 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010476
10477 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10478 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010479 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010480 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010481
Barry Warsaw3155db32000-04-13 15:20:40 +000010482 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010483 PyObject *o = PyLong_FromLong(table[i].value);
10484 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10485 Py_XDECREF(o);
10486 Py_DECREF(d);
10487 return -1;
10488 }
10489 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010490 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010491 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010492}
10493
Fred Drakebec628d1999-12-15 18:31:10 +000010494/* Return -1 on failure, 0 on success. */
10495static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010496setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010497{
10498#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010499 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010500 sizeof(posix_constants_pathconf)
10501 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010502 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010503 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010504#endif
10505#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010506 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010507 sizeof(posix_constants_confstr)
10508 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010509 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010510 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010511#endif
10512#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010513 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010514 sizeof(posix_constants_sysconf)
10515 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010516 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010517 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010518#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010519 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010520}
Fred Draked86ed291999-12-15 15:34:33 +000010521
10522
Larry Hastings2f936352014-08-05 14:04:04 +100010523/*[clinic input]
10524os.abort
10525
10526Abort the interpreter immediately.
10527
10528This function 'dumps core' or otherwise fails in the hardest way possible
10529on the hosting operating system. This function never returns.
10530[clinic start generated code]*/
10531
Larry Hastings2f936352014-08-05 14:04:04 +100010532static PyObject *
10533os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010534/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010535{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010536 abort();
10537 /*NOTREACHED*/
10538 Py_FatalError("abort() called from Python code didn't abort!");
10539 return NULL;
10540}
Fred Drakebec628d1999-12-15 18:31:10 +000010541
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010542#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010543/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010544PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010545"startfile(filepath [, operation])\n\
10546\n\
10547Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010548\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010549When \"operation\" is not specified or \"open\", this acts like\n\
10550double-clicking the file in Explorer, or giving the file name as an\n\
10551argument to the DOS \"start\" command: the file is opened with whatever\n\
10552application (if any) its extension is associated.\n\
10553When another \"operation\" is given, it specifies what should be done with\n\
10554the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010555\n\
10556startfile returns as soon as the associated application is launched.\n\
10557There is no option to wait for the application to close, and no way\n\
10558to retrieve the application's exit status.\n\
10559\n\
10560The filepath is relative to the current directory. If you want to use\n\
10561an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010562the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010563
Steve Dower7d0e0c92015-01-24 08:18:24 -080010564/* Grab ShellExecute dynamically from shell32 */
10565static int has_ShellExecute = -1;
10566static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10567 LPCSTR, INT);
10568static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10569 LPCWSTR, INT);
10570static int
10571check_ShellExecute()
10572{
10573 HINSTANCE hShell32;
10574
10575 /* only recheck */
10576 if (-1 == has_ShellExecute) {
10577 Py_BEGIN_ALLOW_THREADS
10578 hShell32 = LoadLibraryW(L"SHELL32");
10579 Py_END_ALLOW_THREADS
10580 if (hShell32) {
10581 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10582 "ShellExecuteA");
10583 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10584 "ShellExecuteW");
10585 has_ShellExecute = Py_ShellExecuteA &&
10586 Py_ShellExecuteW;
10587 } else {
10588 has_ShellExecute = 0;
10589 }
10590 }
10591 return has_ShellExecute;
10592}
10593
10594
Tim Petersf58a7aa2000-09-22 10:05:54 +000010595static PyObject *
10596win32_startfile(PyObject *self, PyObject *args)
10597{
Victor Stinner8c62be82010-05-06 00:08:46 +000010598 PyObject *ofilepath;
10599 char *filepath;
10600 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010601 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010603
Victor Stinnereb5657a2011-09-30 01:44:27 +020010604 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010605
10606 if(!check_ShellExecute()) {
10607 /* If the OS doesn't have ShellExecute, return a
10608 NotImplementedError. */
10609 return PyErr_Format(PyExc_NotImplementedError,
10610 "startfile not available on this platform");
10611 }
10612
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 if (!PyArg_ParseTuple(args, "U|s:startfile",
10614 &unipath, &operation)) {
10615 PyErr_Clear();
10616 goto normal;
10617 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010618
Victor Stinner8c62be82010-05-06 00:08:46 +000010619 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010620 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010622 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 PyErr_Clear();
10624 operation = NULL;
10625 goto normal;
10626 }
10627 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010628
Victor Stinnereb5657a2011-09-30 01:44:27 +020010629 wpath = PyUnicode_AsUnicode(unipath);
10630 if (wpath == NULL)
10631 goto normal;
10632 if (uoperation) {
10633 woperation = PyUnicode_AsUnicode(uoperation);
10634 if (woperation == NULL)
10635 goto normal;
10636 }
10637 else
10638 woperation = NULL;
10639
Victor Stinner8c62be82010-05-06 00:08:46 +000010640 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010641 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10642 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010643 Py_END_ALLOW_THREADS
10644
Victor Stinnereb5657a2011-09-30 01:44:27 +020010645 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010646 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010647 win32_error_object("startfile", unipath);
10648 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 }
10650 Py_INCREF(Py_None);
10651 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010652
10653normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010654 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10655 PyUnicode_FSConverter, &ofilepath,
10656 &operation))
10657 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010658 if (win32_warn_bytes_api()) {
10659 Py_DECREF(ofilepath);
10660 return NULL;
10661 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010662 filepath = PyBytes_AsString(ofilepath);
10663 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010664 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10665 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010666 Py_END_ALLOW_THREADS
10667 if (rc <= (HINSTANCE)32) {
10668 PyObject *errval = win32_error("startfile", filepath);
10669 Py_DECREF(ofilepath);
10670 return errval;
10671 }
10672 Py_DECREF(ofilepath);
10673 Py_INCREF(Py_None);
10674 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010675}
Larry Hastings2f936352014-08-05 14:04:04 +100010676#endif /* MS_WINDOWS */
10677
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010678
Martin v. Löwis438b5342002-12-27 10:16:42 +000010679#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010680/*[clinic input]
10681os.getloadavg
10682
10683Return average recent system load information.
10684
10685Return the number of processes in the system run queue averaged over
10686the last 1, 5, and 15 minutes as a tuple of three floats.
10687Raises OSError if the load average was unobtainable.
10688[clinic start generated code]*/
10689
Larry Hastings2f936352014-08-05 14:04:04 +100010690static PyObject *
10691os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010692/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010693{
10694 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010695 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010696 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10697 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010698 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010699 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010700}
Larry Hastings2f936352014-08-05 14:04:04 +100010701#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010702
Larry Hastings2f936352014-08-05 14:04:04 +100010703
10704/*[clinic input]
10705os.device_encoding
10706 fd: int
10707
10708Return a string describing the encoding of a terminal's file descriptor.
10709
10710The file descriptor must be attached to a terminal.
10711If the device is not a terminal, return None.
10712[clinic start generated code]*/
10713
Larry Hastings2f936352014-08-05 14:04:04 +100010714static PyObject *
10715os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010716/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010717{
Brett Cannonefb00c02012-02-29 18:31:31 -050010718 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010719}
10720
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010721
Larry Hastings2f936352014-08-05 14:04:04 +100010722#ifdef HAVE_SETRESUID
10723/*[clinic input]
10724os.setresuid
10725
10726 ruid: uid_t
10727 euid: uid_t
10728 suid: uid_t
10729 /
10730
10731Set the current process's real, effective, and saved user ids.
10732[clinic start generated code]*/
10733
Larry Hastings2f936352014-08-05 14:04:04 +100010734static PyObject *
10735os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010736/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010737{
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 if (setresuid(ruid, euid, suid) < 0)
10739 return posix_error();
10740 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010741}
Larry Hastings2f936352014-08-05 14:04:04 +100010742#endif /* HAVE_SETRESUID */
10743
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010744
10745#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010746/*[clinic input]
10747os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010748
Larry Hastings2f936352014-08-05 14:04:04 +100010749 rgid: gid_t
10750 egid: gid_t
10751 sgid: gid_t
10752 /
10753
10754Set the current process's real, effective, and saved group ids.
10755[clinic start generated code]*/
10756
Larry Hastings2f936352014-08-05 14:04:04 +100010757static PyObject *
10758os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010759/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010760{
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 if (setresgid(rgid, egid, sgid) < 0)
10762 return posix_error();
10763 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010764}
Larry Hastings2f936352014-08-05 14:04:04 +100010765#endif /* HAVE_SETRESGID */
10766
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010767
10768#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010769/*[clinic input]
10770os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010771
Larry Hastings2f936352014-08-05 14:04:04 +100010772Return a tuple of the current process's real, effective, and saved user ids.
10773[clinic start generated code]*/
10774
Larry Hastings2f936352014-08-05 14:04:04 +100010775static PyObject *
10776os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010777/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010778{
Victor Stinner8c62be82010-05-06 00:08:46 +000010779 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010780 if (getresuid(&ruid, &euid, &suid) < 0)
10781 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010782 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10783 _PyLong_FromUid(euid),
10784 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010785}
Larry Hastings2f936352014-08-05 14:04:04 +100010786#endif /* HAVE_GETRESUID */
10787
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010788
10789#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010790/*[clinic input]
10791os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010792
Larry Hastings2f936352014-08-05 14:04:04 +100010793Return a tuple of the current process's real, effective, and saved group ids.
10794[clinic start generated code]*/
10795
Larry Hastings2f936352014-08-05 14:04:04 +100010796static PyObject *
10797os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010798/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010799{
10800 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010801 if (getresgid(&rgid, &egid, &sgid) < 0)
10802 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010803 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10804 _PyLong_FromGid(egid),
10805 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010806}
Larry Hastings2f936352014-08-05 14:04:04 +100010807#endif /* HAVE_GETRESGID */
10808
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010809
Benjamin Peterson9428d532011-09-14 11:45:52 -040010810#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010811/*[clinic input]
10812os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010813
Larry Hastings2f936352014-08-05 14:04:04 +100010814 path: path_t(allow_fd=True)
10815 attribute: path_t
10816 *
10817 follow_symlinks: bool = True
10818
10819Return the value of extended attribute attribute on path.
10820
10821path may be either a string or an open file descriptor.
10822If follow_symlinks is False, and the last element of the path is a symbolic
10823 link, getxattr will examine the symbolic link itself instead of the file
10824 the link points to.
10825
10826[clinic start generated code]*/
10827
Larry Hastings2f936352014-08-05 14:04:04 +100010828static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010829os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10830 int follow_symlinks)
10831/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010832{
10833 Py_ssize_t i;
10834 PyObject *buffer = NULL;
10835
10836 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10837 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010838
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 for (i = 0; ; i++) {
10840 void *ptr;
10841 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010842 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 Py_ssize_t buffer_size = buffer_sizes[i];
10844 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010845 path_error(path);
10846 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010847 }
10848 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10849 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010850 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010851 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010852
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010854 if (path->fd >= 0)
10855 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010856 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010857 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858 else
Larry Hastings2f936352014-08-05 14:04:04 +100010859 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010861
Larry Hastings9cf065c2012-06-22 16:30:09 -070010862 if (result < 0) {
10863 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010864 if (errno == ERANGE)
10865 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010866 path_error(path);
10867 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010868 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010869
Larry Hastings9cf065c2012-06-22 16:30:09 -070010870 if (result != buffer_size) {
10871 /* Can only shrink. */
10872 _PyBytes_Resize(&buffer, result);
10873 }
10874 break;
10875 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010876
Larry Hastings9cf065c2012-06-22 16:30:09 -070010877 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010878}
10879
Larry Hastings2f936352014-08-05 14:04:04 +100010880
10881/*[clinic input]
10882os.setxattr
10883
10884 path: path_t(allow_fd=True)
10885 attribute: path_t
10886 value: Py_buffer
10887 flags: int = 0
10888 *
10889 follow_symlinks: bool = True
10890
10891Set extended attribute attribute on path to value.
10892
10893path may be either a string or an open file descriptor.
10894If follow_symlinks is False, and the last element of the path is a symbolic
10895 link, setxattr will modify the symbolic link itself instead of the file
10896 the link points to.
10897
10898[clinic start generated code]*/
10899
Benjamin Peterson799bd802011-08-31 22:15:17 -040010900static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010901os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10902 Py_buffer *value, int flags, int follow_symlinks)
10903/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904{
Larry Hastings2f936352014-08-05 14:04:04 +100010905 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010906
Larry Hastings2f936352014-08-05 14:04:04 +100010907 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010909
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010911 if (path->fd > -1)
10912 result = fsetxattr(path->fd, attribute->narrow,
10913 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010914 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010915 result = setxattr(path->narrow, attribute->narrow,
10916 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010917 else
Larry Hastings2f936352014-08-05 14:04:04 +100010918 result = lsetxattr(path->narrow, attribute->narrow,
10919 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010920 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010921
Larry Hastings9cf065c2012-06-22 16:30:09 -070010922 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010923 path_error(path);
10924 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010925 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010926
Larry Hastings2f936352014-08-05 14:04:04 +100010927 Py_RETURN_NONE;
10928}
10929
10930
10931/*[clinic input]
10932os.removexattr
10933
10934 path: path_t(allow_fd=True)
10935 attribute: path_t
10936 *
10937 follow_symlinks: bool = True
10938
10939Remove extended attribute attribute on path.
10940
10941path may be either a string or an open file descriptor.
10942If follow_symlinks is False, and the last element of the path is a symbolic
10943 link, removexattr will modify the symbolic link itself instead of the file
10944 the link points to.
10945
10946[clinic start generated code]*/
10947
Larry Hastings2f936352014-08-05 14:04:04 +100010948static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010949os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10950 int follow_symlinks)
10951/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010952{
10953 ssize_t result;
10954
10955 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10956 return NULL;
10957
10958 Py_BEGIN_ALLOW_THREADS;
10959 if (path->fd > -1)
10960 result = fremovexattr(path->fd, attribute->narrow);
10961 else if (follow_symlinks)
10962 result = removexattr(path->narrow, attribute->narrow);
10963 else
10964 result = lremovexattr(path->narrow, attribute->narrow);
10965 Py_END_ALLOW_THREADS;
10966
10967 if (result) {
10968 return path_error(path);
10969 }
10970
10971 Py_RETURN_NONE;
10972}
10973
10974
10975/*[clinic input]
10976os.listxattr
10977
10978 path: path_t(allow_fd=True, nullable=True) = None
10979 *
10980 follow_symlinks: bool = True
10981
10982Return a list of extended attributes on path.
10983
10984path may be either None, a string, or an open file descriptor.
10985if path is None, listxattr will examine the current directory.
10986If follow_symlinks is False, and the last element of the path is a symbolic
10987 link, listxattr will examine the symbolic link itself instead of the file
10988 the link points to.
10989[clinic start generated code]*/
10990
Larry Hastings2f936352014-08-05 14:04:04 +100010991static PyObject *
10992os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010993/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010994{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 Py_ssize_t i;
10996 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010997 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010998 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010999
Larry Hastings2f936352014-08-05 14:04:04 +100011000 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011002
Larry Hastings2f936352014-08-05 14:04:04 +100011003 name = path->narrow ? path->narrow : ".";
11004
Larry Hastings9cf065c2012-06-22 16:30:09 -070011005 for (i = 0; ; i++) {
11006 char *start, *trace, *end;
11007 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020011008 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070011009 Py_ssize_t buffer_size = buffer_sizes[i];
11010 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011011 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011012 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 break;
11014 }
11015 buffer = PyMem_MALLOC(buffer_size);
11016 if (!buffer) {
11017 PyErr_NoMemory();
11018 break;
11019 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011020
Larry Hastings9cf065c2012-06-22 16:30:09 -070011021 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011022 if (path->fd > -1)
11023 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 else if (follow_symlinks)
11025 length = listxattr(name, buffer, buffer_size);
11026 else
11027 length = llistxattr(name, buffer, buffer_size);
11028 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029
Larry Hastings9cf065c2012-06-22 16:30:09 -070011030 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011031 if (errno == ERANGE) {
11032 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011033 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011034 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011035 }
Larry Hastings2f936352014-08-05 14:04:04 +100011036 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011037 break;
11038 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011039
Larry Hastings9cf065c2012-06-22 16:30:09 -070011040 result = PyList_New(0);
11041 if (!result) {
11042 goto exit;
11043 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011044
Larry Hastings9cf065c2012-06-22 16:30:09 -070011045 end = buffer + length;
11046 for (trace = start = buffer; trace != end; trace++) {
11047 if (!*trace) {
11048 int error;
11049 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11050 trace - start);
11051 if (!attribute) {
11052 Py_DECREF(result);
11053 result = NULL;
11054 goto exit;
11055 }
11056 error = PyList_Append(result, attribute);
11057 Py_DECREF(attribute);
11058 if (error) {
11059 Py_DECREF(result);
11060 result = NULL;
11061 goto exit;
11062 }
11063 start = trace + 1;
11064 }
11065 }
11066 break;
11067 }
11068exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011069 if (buffer)
11070 PyMem_FREE(buffer);
11071 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011072}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011073#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011074
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011075
Larry Hastings2f936352014-08-05 14:04:04 +100011076/*[clinic input]
11077os.urandom
11078
11079 size: Py_ssize_t
11080 /
11081
11082Return a bytes object containing random bytes suitable for cryptographic use.
11083[clinic start generated code]*/
11084
Larry Hastings2f936352014-08-05 14:04:04 +100011085static PyObject *
11086os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011087/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011088{
11089 PyObject *bytes;
11090 int result;
11091
Georg Brandl2fb477c2012-02-21 00:33:36 +010011092 if (size < 0)
11093 return PyErr_Format(PyExc_ValueError,
11094 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011095 bytes = PyBytes_FromStringAndSize(NULL, size);
11096 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011097 return NULL;
11098
Larry Hastings2f936352014-08-05 14:04:04 +100011099 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11100 PyBytes_GET_SIZE(bytes));
11101 if (result == -1) {
11102 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011103 return NULL;
11104 }
Larry Hastings2f936352014-08-05 14:04:04 +100011105 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011106}
11107
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011108/* Terminal size querying */
11109
11110static PyTypeObject TerminalSizeType;
11111
11112PyDoc_STRVAR(TerminalSize_docstring,
11113 "A tuple of (columns, lines) for holding terminal window size");
11114
11115static PyStructSequence_Field TerminalSize_fields[] = {
11116 {"columns", "width of the terminal window in characters"},
11117 {"lines", "height of the terminal window in characters"},
11118 {NULL, NULL}
11119};
11120
11121static PyStructSequence_Desc TerminalSize_desc = {
11122 "os.terminal_size",
11123 TerminalSize_docstring,
11124 TerminalSize_fields,
11125 2,
11126};
11127
11128#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011129/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011130PyDoc_STRVAR(termsize__doc__,
11131 "Return the size of the terminal window as (columns, lines).\n" \
11132 "\n" \
11133 "The optional argument fd (default standard output) specifies\n" \
11134 "which file descriptor should be queried.\n" \
11135 "\n" \
11136 "If the file descriptor is not connected to a terminal, an OSError\n" \
11137 "is thrown.\n" \
11138 "\n" \
11139 "This function will only be defined if an implementation is\n" \
11140 "available for this system.\n" \
11141 "\n" \
11142 "shutil.get_terminal_size is the high-level function which should \n" \
11143 "normally be used, os.get_terminal_size is the low-level implementation.");
11144
11145static PyObject*
11146get_terminal_size(PyObject *self, PyObject *args)
11147{
11148 int columns, lines;
11149 PyObject *termsize;
11150
11151 int fd = fileno(stdout);
11152 /* Under some conditions stdout may not be connected and
11153 * fileno(stdout) may point to an invalid file descriptor. For example
11154 * GUI apps don't have valid standard streams by default.
11155 *
11156 * If this happens, and the optional fd argument is not present,
11157 * the ioctl below will fail returning EBADF. This is what we want.
11158 */
11159
11160 if (!PyArg_ParseTuple(args, "|i", &fd))
11161 return NULL;
11162
11163#ifdef TERMSIZE_USE_IOCTL
11164 {
11165 struct winsize w;
11166 if (ioctl(fd, TIOCGWINSZ, &w))
11167 return PyErr_SetFromErrno(PyExc_OSError);
11168 columns = w.ws_col;
11169 lines = w.ws_row;
11170 }
11171#endif /* TERMSIZE_USE_IOCTL */
11172
11173#ifdef TERMSIZE_USE_CONIO
11174 {
11175 DWORD nhandle;
11176 HANDLE handle;
11177 CONSOLE_SCREEN_BUFFER_INFO csbi;
11178 switch (fd) {
11179 case 0: nhandle = STD_INPUT_HANDLE;
11180 break;
11181 case 1: nhandle = STD_OUTPUT_HANDLE;
11182 break;
11183 case 2: nhandle = STD_ERROR_HANDLE;
11184 break;
11185 default:
11186 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11187 }
11188 handle = GetStdHandle(nhandle);
11189 if (handle == NULL)
11190 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11191 if (handle == INVALID_HANDLE_VALUE)
11192 return PyErr_SetFromWindowsErr(0);
11193
11194 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11195 return PyErr_SetFromWindowsErr(0);
11196
11197 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11198 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11199 }
11200#endif /* TERMSIZE_USE_CONIO */
11201
11202 termsize = PyStructSequence_New(&TerminalSizeType);
11203 if (termsize == NULL)
11204 return NULL;
11205 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11206 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11207 if (PyErr_Occurred()) {
11208 Py_DECREF(termsize);
11209 return NULL;
11210 }
11211 return termsize;
11212}
11213#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11214
Larry Hastings2f936352014-08-05 14:04:04 +100011215
11216/*[clinic input]
11217os.cpu_count
11218
Charles-François Natali80d62e62015-08-13 20:37:08 +010011219Return the number of CPUs in the system; return None if indeterminable.
11220
11221This number is not equivalent to the number of CPUs the current process can
11222use. The number of usable CPUs can be obtained with
11223``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011224[clinic start generated code]*/
11225
Larry Hastings2f936352014-08-05 14:04:04 +100011226static PyObject *
11227os_cpu_count_impl(PyModuleDef *module)
Charles-François Natali80d62e62015-08-13 20:37:08 +010011228/*[clinic end generated code: output=c59ee7f6bce832b8 input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011229{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011230 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011231#ifdef MS_WINDOWS
11232 SYSTEM_INFO sysinfo;
11233 GetSystemInfo(&sysinfo);
11234 ncpu = sysinfo.dwNumberOfProcessors;
11235#elif defined(__hpux)
11236 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11237#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11238 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011239#elif defined(__DragonFly__) || \
11240 defined(__OpenBSD__) || \
11241 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011242 defined(__NetBSD__) || \
11243 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011244 int mib[2];
11245 size_t len = sizeof(ncpu);
11246 mib[0] = CTL_HW;
11247 mib[1] = HW_NCPU;
11248 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11249 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011250#endif
11251 if (ncpu >= 1)
11252 return PyLong_FromLong(ncpu);
11253 else
11254 Py_RETURN_NONE;
11255}
11256
Victor Stinnerdaf45552013-08-28 00:53:59 +020011257
Larry Hastings2f936352014-08-05 14:04:04 +100011258/*[clinic input]
11259os.get_inheritable -> bool
11260
11261 fd: int
11262 /
11263
11264Get the close-on-exe flag of the specified file descriptor.
11265[clinic start generated code]*/
11266
Larry Hastings2f936352014-08-05 14:04:04 +100011267static int
11268os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011269/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011270{
Steve Dower8fc89802015-04-12 00:26:27 -040011271 int return_value;
11272 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011273 posix_error();
11274 return -1;
11275 }
11276
Steve Dower8fc89802015-04-12 00:26:27 -040011277 _Py_BEGIN_SUPPRESS_IPH
11278 return_value = _Py_get_inheritable(fd);
11279 _Py_END_SUPPRESS_IPH
11280 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011281}
11282
11283
11284/*[clinic input]
11285os.set_inheritable
11286 fd: int
11287 inheritable: int
11288 /
11289
11290Set the inheritable flag of the specified file descriptor.
11291[clinic start generated code]*/
11292
Larry Hastings2f936352014-08-05 14:04:04 +100011293static PyObject *
11294os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011295/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011296{
Steve Dower8fc89802015-04-12 00:26:27 -040011297 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011298 if (!_PyVerify_fd(fd))
11299 return posix_error();
11300
Steve Dower8fc89802015-04-12 00:26:27 -040011301 _Py_BEGIN_SUPPRESS_IPH
11302 result = _Py_set_inheritable(fd, inheritable, NULL);
11303 _Py_END_SUPPRESS_IPH
11304 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011305 return NULL;
11306 Py_RETURN_NONE;
11307}
11308
11309
11310#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011311/*[clinic input]
11312os.get_handle_inheritable -> bool
11313 handle: Py_intptr_t
11314 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011315
Larry Hastings2f936352014-08-05 14:04:04 +100011316Get the close-on-exe flag of the specified file descriptor.
11317[clinic start generated code]*/
11318
Larry Hastings2f936352014-08-05 14:04:04 +100011319static int
11320os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011321/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011322{
11323 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011324
11325 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11326 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011327 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011328 }
11329
Larry Hastings2f936352014-08-05 14:04:04 +100011330 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011331}
11332
Victor Stinnerdaf45552013-08-28 00:53:59 +020011333
Larry Hastings2f936352014-08-05 14:04:04 +100011334/*[clinic input]
11335os.set_handle_inheritable
11336 handle: Py_intptr_t
11337 inheritable: bool
11338 /
11339
11340Set the inheritable flag of the specified handle.
11341[clinic start generated code]*/
11342
Larry Hastings2f936352014-08-05 14:04:04 +100011343static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040011344os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle,
11345 int inheritable)
11346/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011347{
11348 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011349 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11350 PyErr_SetFromWindowsErr(0);
11351 return NULL;
11352 }
11353 Py_RETURN_NONE;
11354}
Larry Hastings2f936352014-08-05 14:04:04 +100011355#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011356
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011357#ifndef MS_WINDOWS
11358PyDoc_STRVAR(get_blocking__doc__,
11359 "get_blocking(fd) -> bool\n" \
11360 "\n" \
11361 "Get the blocking mode of the file descriptor:\n" \
11362 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11363
11364static PyObject*
11365posix_get_blocking(PyObject *self, PyObject *args)
11366{
11367 int fd;
11368 int blocking;
11369
11370 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11371 return NULL;
11372
11373 if (!_PyVerify_fd(fd))
11374 return posix_error();
11375
Steve Dower8fc89802015-04-12 00:26:27 -040011376 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011377 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011378 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011379 if (blocking < 0)
11380 return NULL;
11381 return PyBool_FromLong(blocking);
11382}
11383
11384PyDoc_STRVAR(set_blocking__doc__,
11385 "set_blocking(fd, blocking)\n" \
11386 "\n" \
11387 "Set the blocking mode of the specified file descriptor.\n" \
11388 "Set the O_NONBLOCK flag if blocking is False,\n" \
11389 "clear the O_NONBLOCK flag otherwise.");
11390
11391static PyObject*
11392posix_set_blocking(PyObject *self, PyObject *args)
11393{
Steve Dower8fc89802015-04-12 00:26:27 -040011394 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011395
11396 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11397 return NULL;
11398
11399 if (!_PyVerify_fd(fd))
11400 return posix_error();
11401
Steve Dower8fc89802015-04-12 00:26:27 -040011402 _Py_BEGIN_SUPPRESS_IPH
11403 result = _Py_set_blocking(fd, blocking);
11404 _Py_END_SUPPRESS_IPH
11405 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011406 return NULL;
11407 Py_RETURN_NONE;
11408}
11409#endif /* !MS_WINDOWS */
11410
11411
Victor Stinner6036e442015-03-08 01:58:04 +010011412PyDoc_STRVAR(posix_scandir__doc__,
11413"scandir(path='.') -> iterator of DirEntry objects for given path");
11414
11415static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11416
11417typedef struct {
11418 PyObject_HEAD
11419 PyObject *name;
11420 PyObject *path;
11421 PyObject *stat;
11422 PyObject *lstat;
11423#ifdef MS_WINDOWS
11424 struct _Py_stat_struct win32_lstat;
11425 __int64 win32_file_index;
11426 int got_file_index;
11427#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011428#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011429 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011430#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011431 ino_t d_ino;
11432#endif
11433} DirEntry;
11434
11435static void
11436DirEntry_dealloc(DirEntry *entry)
11437{
11438 Py_XDECREF(entry->name);
11439 Py_XDECREF(entry->path);
11440 Py_XDECREF(entry->stat);
11441 Py_XDECREF(entry->lstat);
11442 Py_TYPE(entry)->tp_free((PyObject *)entry);
11443}
11444
11445/* Forward reference */
11446static int
11447DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11448
11449/* Set exception and return -1 on error, 0 for False, 1 for True */
11450static int
11451DirEntry_is_symlink(DirEntry *self)
11452{
11453#ifdef MS_WINDOWS
11454 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011455#elif defined(HAVE_DIRENT_D_TYPE)
11456 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011457 if (self->d_type != DT_UNKNOWN)
11458 return self->d_type == DT_LNK;
11459 else
11460 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011461#else
11462 /* POSIX without d_type */
11463 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011464#endif
11465}
11466
11467static PyObject *
11468DirEntry_py_is_symlink(DirEntry *self)
11469{
11470 int result;
11471
11472 result = DirEntry_is_symlink(self);
11473 if (result == -1)
11474 return NULL;
11475 return PyBool_FromLong(result);
11476}
11477
11478static PyObject *
11479DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11480{
11481 int result;
11482 struct _Py_stat_struct st;
11483
11484#ifdef MS_WINDOWS
11485 wchar_t *path;
11486
11487 path = PyUnicode_AsUnicode(self->path);
11488 if (!path)
11489 return NULL;
11490
11491 if (follow_symlinks)
11492 result = win32_stat_w(path, &st);
11493 else
11494 result = win32_lstat_w(path, &st);
11495
11496 if (result != 0) {
11497 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11498 0, self->path);
11499 }
11500#else /* POSIX */
11501 PyObject *bytes;
11502 char *path;
11503
11504 if (!PyUnicode_FSConverter(self->path, &bytes))
11505 return NULL;
11506 path = PyBytes_AS_STRING(bytes);
11507
11508 if (follow_symlinks)
11509 result = STAT(path, &st);
11510 else
11511 result = LSTAT(path, &st);
11512 Py_DECREF(bytes);
11513
11514 if (result != 0)
11515 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11516#endif
11517
11518 return _pystat_fromstructstat(&st);
11519}
11520
11521static PyObject *
11522DirEntry_get_lstat(DirEntry *self)
11523{
11524 if (!self->lstat) {
11525#ifdef MS_WINDOWS
11526 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11527#else /* POSIX */
11528 self->lstat = DirEntry_fetch_stat(self, 0);
11529#endif
11530 }
11531 Py_XINCREF(self->lstat);
11532 return self->lstat;
11533}
11534
11535static PyObject *
11536DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11537{
11538 if (!follow_symlinks)
11539 return DirEntry_get_lstat(self);
11540
11541 if (!self->stat) {
11542 int result = DirEntry_is_symlink(self);
11543 if (result == -1)
11544 return NULL;
11545 else if (result)
11546 self->stat = DirEntry_fetch_stat(self, 1);
11547 else
11548 self->stat = DirEntry_get_lstat(self);
11549 }
11550
11551 Py_XINCREF(self->stat);
11552 return self->stat;
11553}
11554
11555static PyObject *
11556DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11557{
11558 int follow_symlinks = 1;
11559
11560 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11561 follow_symlinks_keywords, &follow_symlinks))
11562 return NULL;
11563
11564 return DirEntry_get_stat(self, follow_symlinks);
11565}
11566
11567/* Set exception and return -1 on error, 0 for False, 1 for True */
11568static int
11569DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11570{
11571 PyObject *stat = NULL;
11572 PyObject *st_mode = NULL;
11573 long mode;
11574 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011575#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011576 int is_symlink;
11577 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011578#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011579#ifdef MS_WINDOWS
11580 unsigned long dir_bits;
11581#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011582 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011583
11584#ifdef MS_WINDOWS
11585 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11586 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011587#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011588 is_symlink = self->d_type == DT_LNK;
11589 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11590#endif
11591
Victor Stinner35a97c02015-03-08 02:59:09 +010011592#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011593 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011594#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011595 stat = DirEntry_get_stat(self, follow_symlinks);
11596 if (!stat) {
11597 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11598 /* If file doesn't exist (anymore), then return False
11599 (i.e., say it's not a file/directory) */
11600 PyErr_Clear();
11601 return 0;
11602 }
11603 goto error;
11604 }
11605 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11606 if (!st_mode)
11607 goto error;
11608
11609 mode = PyLong_AsLong(st_mode);
11610 if (mode == -1 && PyErr_Occurred())
11611 goto error;
11612 Py_CLEAR(st_mode);
11613 Py_CLEAR(stat);
11614 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011615#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011616 }
11617 else if (is_symlink) {
11618 assert(mode_bits != S_IFLNK);
11619 result = 0;
11620 }
11621 else {
11622 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11623#ifdef MS_WINDOWS
11624 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11625 if (mode_bits == S_IFDIR)
11626 result = dir_bits != 0;
11627 else
11628 result = dir_bits == 0;
11629#else /* POSIX */
11630 if (mode_bits == S_IFDIR)
11631 result = self->d_type == DT_DIR;
11632 else
11633 result = self->d_type == DT_REG;
11634#endif
11635 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011636#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011637
11638 return result;
11639
11640error:
11641 Py_XDECREF(st_mode);
11642 Py_XDECREF(stat);
11643 return -1;
11644}
11645
11646static PyObject *
11647DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11648{
11649 int result;
11650
11651 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11652 if (result == -1)
11653 return NULL;
11654 return PyBool_FromLong(result);
11655}
11656
11657static PyObject *
11658DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11659{
11660 int follow_symlinks = 1;
11661
11662 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11663 follow_symlinks_keywords, &follow_symlinks))
11664 return NULL;
11665
11666 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11667}
11668
11669static PyObject *
11670DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11671{
11672 int follow_symlinks = 1;
11673
11674 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11675 follow_symlinks_keywords, &follow_symlinks))
11676 return NULL;
11677
11678 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11679}
11680
11681static PyObject *
11682DirEntry_inode(DirEntry *self)
11683{
11684#ifdef MS_WINDOWS
11685 if (!self->got_file_index) {
11686 wchar_t *path;
11687 struct _Py_stat_struct stat;
11688
11689 path = PyUnicode_AsUnicode(self->path);
11690 if (!path)
11691 return NULL;
11692
11693 if (win32_lstat_w(path, &stat) != 0) {
11694 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11695 0, self->path);
11696 }
11697
11698 self->win32_file_index = stat.st_ino;
11699 self->got_file_index = 1;
11700 }
11701 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11702#else /* POSIX */
11703#ifdef HAVE_LARGEFILE_SUPPORT
11704 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11705#else
11706 return PyLong_FromLong((long)self->d_ino);
11707#endif
11708#endif
11709}
11710
11711static PyObject *
11712DirEntry_repr(DirEntry *self)
11713{
11714 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11715}
11716
11717static PyMemberDef DirEntry_members[] = {
11718 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11719 "the entry's base filename, relative to scandir() \"path\" argument"},
11720 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11721 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11722 {NULL}
11723};
11724
11725static PyMethodDef DirEntry_methods[] = {
11726 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11727 "return True if the entry is a directory; cached per entry"
11728 },
11729 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11730 "return True if the entry is a file; cached per entry"
11731 },
11732 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11733 "return True if the entry is a symbolic link; cached per entry"
11734 },
11735 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11736 "return stat_result object for the entry; cached per entry"
11737 },
11738 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11739 "return inode of the entry; cached per entry",
11740 },
11741 {NULL}
11742};
11743
Benjamin Peterson5646de42015-04-12 17:56:34 -040011744static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011745 PyVarObject_HEAD_INIT(NULL, 0)
11746 MODNAME ".DirEntry", /* tp_name */
11747 sizeof(DirEntry), /* tp_basicsize */
11748 0, /* tp_itemsize */
11749 /* methods */
11750 (destructor)DirEntry_dealloc, /* tp_dealloc */
11751 0, /* tp_print */
11752 0, /* tp_getattr */
11753 0, /* tp_setattr */
11754 0, /* tp_compare */
11755 (reprfunc)DirEntry_repr, /* tp_repr */
11756 0, /* tp_as_number */
11757 0, /* tp_as_sequence */
11758 0, /* tp_as_mapping */
11759 0, /* tp_hash */
11760 0, /* tp_call */
11761 0, /* tp_str */
11762 0, /* tp_getattro */
11763 0, /* tp_setattro */
11764 0, /* tp_as_buffer */
11765 Py_TPFLAGS_DEFAULT, /* tp_flags */
11766 0, /* tp_doc */
11767 0, /* tp_traverse */
11768 0, /* tp_clear */
11769 0, /* tp_richcompare */
11770 0, /* tp_weaklistoffset */
11771 0, /* tp_iter */
11772 0, /* tp_iternext */
11773 DirEntry_methods, /* tp_methods */
11774 DirEntry_members, /* tp_members */
11775};
11776
11777#ifdef MS_WINDOWS
11778
11779static wchar_t *
11780join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11781{
11782 Py_ssize_t path_len;
11783 Py_ssize_t size;
11784 wchar_t *result;
11785 wchar_t ch;
11786
11787 if (!path_wide) { /* Default arg: "." */
11788 path_wide = L".";
11789 path_len = 1;
11790 }
11791 else {
11792 path_len = wcslen(path_wide);
11793 }
11794
11795 /* The +1's are for the path separator and the NUL */
11796 size = path_len + 1 + wcslen(filename) + 1;
11797 result = PyMem_New(wchar_t, size);
11798 if (!result) {
11799 PyErr_NoMemory();
11800 return NULL;
11801 }
11802 wcscpy(result, path_wide);
11803 if (path_len > 0) {
11804 ch = result[path_len - 1];
11805 if (ch != SEP && ch != ALTSEP && ch != L':')
11806 result[path_len++] = SEP;
11807 wcscpy(result + path_len, filename);
11808 }
11809 return result;
11810}
11811
11812static PyObject *
11813DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11814{
11815 DirEntry *entry;
11816 BY_HANDLE_FILE_INFORMATION file_info;
11817 ULONG reparse_tag;
11818 wchar_t *joined_path;
11819
11820 entry = PyObject_New(DirEntry, &DirEntryType);
11821 if (!entry)
11822 return NULL;
11823 entry->name = NULL;
11824 entry->path = NULL;
11825 entry->stat = NULL;
11826 entry->lstat = NULL;
11827 entry->got_file_index = 0;
11828
11829 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11830 if (!entry->name)
11831 goto error;
11832
11833 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11834 if (!joined_path)
11835 goto error;
11836
11837 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11838 PyMem_Free(joined_path);
11839 if (!entry->path)
11840 goto error;
11841
11842 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11843 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11844
11845 return (PyObject *)entry;
11846
11847error:
11848 Py_DECREF(entry);
11849 return NULL;
11850}
11851
11852#else /* POSIX */
11853
11854static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011855join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011856{
11857 Py_ssize_t path_len;
11858 Py_ssize_t size;
11859 char *result;
11860
11861 if (!path_narrow) { /* Default arg: "." */
11862 path_narrow = ".";
11863 path_len = 1;
11864 }
11865 else {
11866 path_len = strlen(path_narrow);
11867 }
11868
11869 if (filename_len == -1)
11870 filename_len = strlen(filename);
11871
11872 /* The +1's are for the path separator and the NUL */
11873 size = path_len + 1 + filename_len + 1;
11874 result = PyMem_New(char, size);
11875 if (!result) {
11876 PyErr_NoMemory();
11877 return NULL;
11878 }
11879 strcpy(result, path_narrow);
11880 if (path_len > 0 && result[path_len - 1] != '/')
11881 result[path_len++] = '/';
11882 strcpy(result + path_len, filename);
11883 return result;
11884}
11885
11886static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011887DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011888 ino_t d_ino
11889#ifdef HAVE_DIRENT_D_TYPE
11890 , unsigned char d_type
11891#endif
11892 )
Victor Stinner6036e442015-03-08 01:58:04 +010011893{
11894 DirEntry *entry;
11895 char *joined_path;
11896
11897 entry = PyObject_New(DirEntry, &DirEntryType);
11898 if (!entry)
11899 return NULL;
11900 entry->name = NULL;
11901 entry->path = NULL;
11902 entry->stat = NULL;
11903 entry->lstat = NULL;
11904
11905 joined_path = join_path_filename(path->narrow, name, name_len);
11906 if (!joined_path)
11907 goto error;
11908
11909 if (!path->narrow || !PyBytes_Check(path->object)) {
11910 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11911 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11912 }
11913 else {
11914 entry->name = PyBytes_FromStringAndSize(name, name_len);
11915 entry->path = PyBytes_FromString(joined_path);
11916 }
11917 PyMem_Free(joined_path);
11918 if (!entry->name || !entry->path)
11919 goto error;
11920
Victor Stinner35a97c02015-03-08 02:59:09 +010011921#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011922 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011923#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011924 entry->d_ino = d_ino;
11925
11926 return (PyObject *)entry;
11927
11928error:
11929 Py_XDECREF(entry);
11930 return NULL;
11931}
11932
11933#endif
11934
11935
11936typedef struct {
11937 PyObject_HEAD
11938 path_t path;
11939#ifdef MS_WINDOWS
11940 HANDLE handle;
11941 WIN32_FIND_DATAW file_data;
11942 int first_time;
11943#else /* POSIX */
11944 DIR *dirp;
11945#endif
11946} ScandirIterator;
11947
11948#ifdef MS_WINDOWS
11949
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011950static int
11951ScandirIterator_is_closed(ScandirIterator *iterator)
11952{
11953 return iterator->handle == INVALID_HANDLE_VALUE;
11954}
11955
Victor Stinner6036e442015-03-08 01:58:04 +010011956static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011957ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010011958{
11959 if (iterator->handle == INVALID_HANDLE_VALUE)
11960 return;
11961
11962 Py_BEGIN_ALLOW_THREADS
11963 FindClose(iterator->handle);
11964 Py_END_ALLOW_THREADS
11965 iterator->handle = INVALID_HANDLE_VALUE;
11966}
11967
11968static PyObject *
11969ScandirIterator_iternext(ScandirIterator *iterator)
11970{
11971 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11972 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011973 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011974
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020011975 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011976 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011977 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011978
11979 while (1) {
11980 if (!iterator->first_time) {
11981 Py_BEGIN_ALLOW_THREADS
11982 success = FindNextFileW(iterator->handle, file_data);
11983 Py_END_ALLOW_THREADS
11984 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011985 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011986 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011987 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011988 break;
11989 }
11990 }
11991 iterator->first_time = 0;
11992
11993 /* Skip over . and .. */
11994 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011995 wcscmp(file_data->cFileName, L"..") != 0) {
11996 entry = DirEntry_from_find_data(&iterator->path, file_data);
11997 if (!entry)
11998 break;
11999 return entry;
12000 }
Victor Stinner6036e442015-03-08 01:58:04 +010012001
12002 /* Loop till we get a non-dot directory or finish iterating */
12003 }
12004
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012005 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012006 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012007 return NULL;
12008}
12009
12010#else /* POSIX */
12011
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012012static int
12013ScandirIterator_is_closed(ScandirIterator *iterator)
12014{
12015 return !iterator->dirp;
12016}
12017
Victor Stinner6036e442015-03-08 01:58:04 +010012018static void
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012019ScandirIterator_closedir(ScandirIterator *iterator)
Victor Stinner6036e442015-03-08 01:58:04 +010012020{
12021 if (!iterator->dirp)
12022 return;
12023
12024 Py_BEGIN_ALLOW_THREADS
12025 closedir(iterator->dirp);
12026 Py_END_ALLOW_THREADS
12027 iterator->dirp = NULL;
12028 return;
12029}
12030
12031static PyObject *
12032ScandirIterator_iternext(ScandirIterator *iterator)
12033{
12034 struct dirent *direntp;
12035 Py_ssize_t name_len;
12036 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012037 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012038
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012039 /* Happens if the iterator is iterated twice, or closed explicitly */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012040 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012041 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012042
12043 while (1) {
12044 errno = 0;
12045 Py_BEGIN_ALLOW_THREADS
12046 direntp = readdir(iterator->dirp);
12047 Py_END_ALLOW_THREADS
12048
12049 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012050 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012051 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012052 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012053 break;
12054 }
12055
12056 /* Skip over . and .. */
12057 name_len = NAMLEN(direntp);
12058 is_dot = direntp->d_name[0] == '.' &&
12059 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12060 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012061 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012062 name_len, direntp->d_ino
12063#ifdef HAVE_DIRENT_D_TYPE
12064 , direntp->d_type
12065#endif
12066 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012067 if (!entry)
12068 break;
12069 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012070 }
12071
12072 /* Loop till we get a non-dot directory or finish iterating */
12073 }
12074
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012075 /* Error or no more files */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012076 ScandirIterator_closedir(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012077 return NULL;
12078}
12079
12080#endif
12081
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012082static PyObject *
12083ScandirIterator_close(ScandirIterator *self, PyObject *args)
12084{
12085 ScandirIterator_closedir(self);
12086 Py_RETURN_NONE;
12087}
12088
12089static PyObject *
12090ScandirIterator_enter(PyObject *self, PyObject *args)
12091{
12092 Py_INCREF(self);
12093 return self;
12094}
12095
12096static PyObject *
12097ScandirIterator_exit(ScandirIterator *self, PyObject *args)
12098{
12099 ScandirIterator_closedir(self);
12100 Py_RETURN_NONE;
12101}
12102
Victor Stinner6036e442015-03-08 01:58:04 +010012103static void
12104ScandirIterator_dealloc(ScandirIterator *iterator)
12105{
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012106 if (!ScandirIterator_is_closed(iterator)) {
12107 PyObject *exc, *val, *tb;
12108 Py_ssize_t old_refcount = Py_REFCNT(iterator);
12109 /* Py_INCREF/Py_DECREF cannot be used, because the refcount is
12110 * likely zero, Py_DECREF would call again the destructor.
12111 */
12112 ++Py_REFCNT(iterator);
12113 PyErr_Fetch(&exc, &val, &tb);
12114 if (PyErr_WarnFormat(PyExc_ResourceWarning, 1,
12115 "unclosed scandir iterator %R", iterator)) {
12116 /* Spurious errors can appear at shutdown */
12117 if (PyErr_ExceptionMatches(PyExc_Warning))
12118 PyErr_WriteUnraisable((PyObject *) iterator);
12119 }
12120 PyErr_Restore(exc, val, tb);
12121 Py_REFCNT(iterator) = old_refcount;
12122
12123 ScandirIterator_closedir(iterator);
12124 }
Victor Stinner6036e442015-03-08 01:58:04 +010012125 Py_XDECREF(iterator->path.object);
12126 path_cleanup(&iterator->path);
12127 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12128}
12129
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012130static PyMethodDef ScandirIterator_methods[] = {
12131 {"__enter__", (PyCFunction)ScandirIterator_enter, METH_NOARGS},
12132 {"__exit__", (PyCFunction)ScandirIterator_exit, METH_VARARGS},
12133 {"close", (PyCFunction)ScandirIterator_close, METH_NOARGS},
12134 {NULL}
12135};
12136
Benjamin Peterson5646de42015-04-12 17:56:34 -040012137static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012138 PyVarObject_HEAD_INIT(NULL, 0)
12139 MODNAME ".ScandirIterator", /* tp_name */
12140 sizeof(ScandirIterator), /* tp_basicsize */
12141 0, /* tp_itemsize */
12142 /* methods */
12143 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12144 0, /* tp_print */
12145 0, /* tp_getattr */
12146 0, /* tp_setattr */
12147 0, /* tp_compare */
12148 0, /* tp_repr */
12149 0, /* tp_as_number */
12150 0, /* tp_as_sequence */
12151 0, /* tp_as_mapping */
12152 0, /* tp_hash */
12153 0, /* tp_call */
12154 0, /* tp_str */
12155 0, /* tp_getattro */
12156 0, /* tp_setattro */
12157 0, /* tp_as_buffer */
12158 Py_TPFLAGS_DEFAULT, /* tp_flags */
12159 0, /* tp_doc */
12160 0, /* tp_traverse */
12161 0, /* tp_clear */
12162 0, /* tp_richcompare */
12163 0, /* tp_weaklistoffset */
12164 PyObject_SelfIter, /* tp_iter */
12165 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
Serhiy Storchakaffe96ae2016-02-11 13:21:30 +020012166 ScandirIterator_methods, /* tp_methods */
Victor Stinner6036e442015-03-08 01:58:04 +010012167};
12168
12169static PyObject *
12170posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12171{
12172 ScandirIterator *iterator;
12173 static char *keywords[] = {"path", NULL};
12174#ifdef MS_WINDOWS
12175 wchar_t *path_strW;
12176#else
12177 char *path;
12178#endif
12179
12180 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12181 if (!iterator)
12182 return NULL;
12183 memset(&iterator->path, 0, sizeof(path_t));
12184 iterator->path.function_name = "scandir";
12185 iterator->path.nullable = 1;
12186
12187#ifdef MS_WINDOWS
12188 iterator->handle = INVALID_HANDLE_VALUE;
12189#else
12190 iterator->dirp = NULL;
12191#endif
12192
12193 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12194 path_converter, &iterator->path))
12195 goto error;
12196
12197 /* path_converter doesn't keep path.object around, so do it
12198 manually for the lifetime of the iterator here (the refcount
12199 is decremented in ScandirIterator_dealloc)
12200 */
12201 Py_XINCREF(iterator->path.object);
12202
12203#ifdef MS_WINDOWS
12204 if (iterator->path.narrow) {
12205 PyErr_SetString(PyExc_TypeError,
12206 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12207 goto error;
12208 }
12209 iterator->first_time = 1;
12210
12211 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12212 if (!path_strW)
12213 goto error;
12214
12215 Py_BEGIN_ALLOW_THREADS
12216 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12217 Py_END_ALLOW_THREADS
12218
12219 PyMem_Free(path_strW);
12220
12221 if (iterator->handle == INVALID_HANDLE_VALUE) {
12222 path_error(&iterator->path);
12223 goto error;
12224 }
12225#else /* POSIX */
12226 if (iterator->path.narrow)
12227 path = iterator->path.narrow;
12228 else
12229 path = ".";
12230
12231 errno = 0;
12232 Py_BEGIN_ALLOW_THREADS
12233 iterator->dirp = opendir(path);
12234 Py_END_ALLOW_THREADS
12235
12236 if (!iterator->dirp) {
12237 path_error(&iterator->path);
12238 goto error;
12239 }
12240#endif
12241
12242 return (PyObject *)iterator;
12243
12244error:
12245 Py_DECREF(iterator);
12246 return NULL;
12247}
12248
12249
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012250#include "clinic/posixmodule.c.h"
12251
Larry Hastings7726ac92014-01-31 22:03:12 -080012252/*[clinic input]
12253dump buffer
12254[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012255/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012256
Larry Hastings31826802013-10-19 00:09:25 -070012257
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012258static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012259
12260 OS_STAT_METHODDEF
12261 OS_ACCESS_METHODDEF
12262 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012263 OS_CHDIR_METHODDEF
12264 OS_CHFLAGS_METHODDEF
12265 OS_CHMOD_METHODDEF
12266 OS_FCHMOD_METHODDEF
12267 OS_LCHMOD_METHODDEF
12268 OS_CHOWN_METHODDEF
12269 OS_FCHOWN_METHODDEF
12270 OS_LCHOWN_METHODDEF
12271 OS_LCHFLAGS_METHODDEF
12272 OS_CHROOT_METHODDEF
12273 OS_CTERMID_METHODDEF
12274 OS_GETCWD_METHODDEF
12275 OS_GETCWDB_METHODDEF
12276 OS_LINK_METHODDEF
12277 OS_LISTDIR_METHODDEF
12278 OS_LSTAT_METHODDEF
12279 OS_MKDIR_METHODDEF
12280 OS_NICE_METHODDEF
12281 OS_GETPRIORITY_METHODDEF
12282 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012283#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012284 {"readlink", (PyCFunction)posix_readlink,
12285 METH_VARARGS | METH_KEYWORDS,
12286 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012287#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012288#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012289 {"readlink", (PyCFunction)win_readlink,
12290 METH_VARARGS | METH_KEYWORDS,
12291 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012292#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012293 OS_RENAME_METHODDEF
12294 OS_REPLACE_METHODDEF
12295 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012296 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012297 OS_SYMLINK_METHODDEF
12298 OS_SYSTEM_METHODDEF
12299 OS_UMASK_METHODDEF
12300 OS_UNAME_METHODDEF
12301 OS_UNLINK_METHODDEF
12302 OS_REMOVE_METHODDEF
12303 OS_UTIME_METHODDEF
12304 OS_TIMES_METHODDEF
12305 OS__EXIT_METHODDEF
12306 OS_EXECV_METHODDEF
12307 OS_EXECVE_METHODDEF
12308 OS_SPAWNV_METHODDEF
12309 OS_SPAWNVE_METHODDEF
12310 OS_FORK1_METHODDEF
12311 OS_FORK_METHODDEF
12312 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12313 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12314 OS_SCHED_GETPARAM_METHODDEF
12315 OS_SCHED_GETSCHEDULER_METHODDEF
12316 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12317 OS_SCHED_SETPARAM_METHODDEF
12318 OS_SCHED_SETSCHEDULER_METHODDEF
12319 OS_SCHED_YIELD_METHODDEF
12320 OS_SCHED_SETAFFINITY_METHODDEF
12321 OS_SCHED_GETAFFINITY_METHODDEF
12322 OS_OPENPTY_METHODDEF
12323 OS_FORKPTY_METHODDEF
12324 OS_GETEGID_METHODDEF
12325 OS_GETEUID_METHODDEF
12326 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012327#ifdef HAVE_GETGROUPLIST
12328 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12329#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012330 OS_GETGROUPS_METHODDEF
12331 OS_GETPID_METHODDEF
12332 OS_GETPGRP_METHODDEF
12333 OS_GETPPID_METHODDEF
12334 OS_GETUID_METHODDEF
12335 OS_GETLOGIN_METHODDEF
12336 OS_KILL_METHODDEF
12337 OS_KILLPG_METHODDEF
12338 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012339#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012340 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012341#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012342 OS_SETUID_METHODDEF
12343 OS_SETEUID_METHODDEF
12344 OS_SETREUID_METHODDEF
12345 OS_SETGID_METHODDEF
12346 OS_SETEGID_METHODDEF
12347 OS_SETREGID_METHODDEF
12348 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012349#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012350 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012351#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012352 OS_GETPGID_METHODDEF
12353 OS_SETPGRP_METHODDEF
12354 OS_WAIT_METHODDEF
12355 OS_WAIT3_METHODDEF
12356 OS_WAIT4_METHODDEF
12357 OS_WAITID_METHODDEF
12358 OS_WAITPID_METHODDEF
12359 OS_GETSID_METHODDEF
12360 OS_SETSID_METHODDEF
12361 OS_SETPGID_METHODDEF
12362 OS_TCGETPGRP_METHODDEF
12363 OS_TCSETPGRP_METHODDEF
12364 OS_OPEN_METHODDEF
12365 OS_CLOSE_METHODDEF
12366 OS_CLOSERANGE_METHODDEF
12367 OS_DEVICE_ENCODING_METHODDEF
12368 OS_DUP_METHODDEF
12369 OS_DUP2_METHODDEF
12370 OS_LOCKF_METHODDEF
12371 OS_LSEEK_METHODDEF
12372 OS_READ_METHODDEF
12373 OS_READV_METHODDEF
12374 OS_PREAD_METHODDEF
12375 OS_WRITE_METHODDEF
12376 OS_WRITEV_METHODDEF
12377 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012378#ifdef HAVE_SENDFILE
12379 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12380 posix_sendfile__doc__},
12381#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012382 OS_FSTAT_METHODDEF
12383 OS_ISATTY_METHODDEF
12384 OS_PIPE_METHODDEF
12385 OS_PIPE2_METHODDEF
12386 OS_MKFIFO_METHODDEF
12387 OS_MKNOD_METHODDEF
12388 OS_MAJOR_METHODDEF
12389 OS_MINOR_METHODDEF
12390 OS_MAKEDEV_METHODDEF
12391 OS_FTRUNCATE_METHODDEF
12392 OS_TRUNCATE_METHODDEF
12393 OS_POSIX_FALLOCATE_METHODDEF
12394 OS_POSIX_FADVISE_METHODDEF
12395 OS_PUTENV_METHODDEF
12396 OS_UNSETENV_METHODDEF
12397 OS_STRERROR_METHODDEF
12398 OS_FCHDIR_METHODDEF
12399 OS_FSYNC_METHODDEF
12400 OS_SYNC_METHODDEF
12401 OS_FDATASYNC_METHODDEF
12402 OS_WCOREDUMP_METHODDEF
12403 OS_WIFCONTINUED_METHODDEF
12404 OS_WIFSTOPPED_METHODDEF
12405 OS_WIFSIGNALED_METHODDEF
12406 OS_WIFEXITED_METHODDEF
12407 OS_WEXITSTATUS_METHODDEF
12408 OS_WTERMSIG_METHODDEF
12409 OS_WSTOPSIG_METHODDEF
12410 OS_FSTATVFS_METHODDEF
12411 OS_STATVFS_METHODDEF
12412 OS_CONFSTR_METHODDEF
12413 OS_SYSCONF_METHODDEF
12414 OS_FPATHCONF_METHODDEF
12415 OS_PATHCONF_METHODDEF
12416 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012417 OS__GETFULLPATHNAME_METHODDEF
12418 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012419 OS__GETDISKUSAGE_METHODDEF
12420 OS__GETFINALPATHNAME_METHODDEF
12421 OS__GETVOLUMEPATHNAME_METHODDEF
12422 OS_GETLOADAVG_METHODDEF
12423 OS_URANDOM_METHODDEF
12424 OS_SETRESUID_METHODDEF
12425 OS_SETRESGID_METHODDEF
12426 OS_GETRESUID_METHODDEF
12427 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012428
Larry Hastings2f936352014-08-05 14:04:04 +100012429 OS_GETXATTR_METHODDEF
12430 OS_SETXATTR_METHODDEF
12431 OS_REMOVEXATTR_METHODDEF
12432 OS_LISTXATTR_METHODDEF
12433
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012434#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12435 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12436#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012437 OS_CPU_COUNT_METHODDEF
12438 OS_GET_INHERITABLE_METHODDEF
12439 OS_SET_INHERITABLE_METHODDEF
12440 OS_GET_HANDLE_INHERITABLE_METHODDEF
12441 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012442#ifndef MS_WINDOWS
12443 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12444 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12445#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012446 {"scandir", (PyCFunction)posix_scandir,
12447 METH_VARARGS | METH_KEYWORDS,
12448 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012449 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012450};
12451
12452
Brian Curtin52173d42010-12-02 18:29:18 +000012453#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012454static int
Brian Curtin52173d42010-12-02 18:29:18 +000012455enable_symlink()
12456{
12457 HANDLE tok;
12458 TOKEN_PRIVILEGES tok_priv;
12459 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012460
12461 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012462 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012463
12464 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012465 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012466
12467 tok_priv.PrivilegeCount = 1;
12468 tok_priv.Privileges[0].Luid = luid;
12469 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12470
12471 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12472 sizeof(TOKEN_PRIVILEGES),
12473 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012474 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012475
Brian Curtin3b4499c2010-12-28 14:31:47 +000012476 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12477 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012478}
12479#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12480
Barry Warsaw4a342091996-12-19 23:50:02 +000012481static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012483{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012484#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012486#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012487#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012489#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012490#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012492#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012493#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012494 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012495#endif
Fred Drakec9680921999-12-13 16:37:25 +000012496#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012498#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012499#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012501#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012502#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012503 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012504#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012505#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012507#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012508#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012509 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012510#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012511#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012512 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012513#endif
12514#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012516#endif
12517#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012518 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012519#endif
12520#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012522#endif
12523#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012525#endif
12526#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012527 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012528#endif
12529#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012531#endif
12532#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012533 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012534#endif
12535#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012537#endif
12538#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012539 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012540#endif
12541#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012542 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012543#endif
12544#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012545 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012546#endif
12547#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012548 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012549#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012550#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012551 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012552#endif
12553#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012555#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012556#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012557 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012558#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012559#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012560 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012561#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012562#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012563 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012564#endif
12565#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012567#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012568#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012569 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012570#endif
12571#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012573#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012574#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012576#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012577#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012579#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012580#ifdef O_TMPFILE
12581 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12582#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012583#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012584 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012585#endif
12586#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012588#endif
12589#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012591#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012592#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012594#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012595#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012597#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012598
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012599
Jesus Cea94363612012-06-22 18:32:07 +020012600#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012602#endif
12603#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012605#endif
12606
Tim Peters5aa91602002-01-30 05:46:57 +000012607/* MS Windows */
12608#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012609 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012611#endif
12612#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012613 /* Optimize for short life (keep in memory). */
12614 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012616#endif
12617#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012618 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012620#endif
12621#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012622 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012624#endif
12625#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012626 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012628#endif
12629
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012630/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012631#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012632 /* Send a SIGIO signal whenever input or output
12633 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012634 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012635#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012636#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012637 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012638 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012639#endif
12640#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012641 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012642 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012643#endif
12644#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012645 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012646 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012647#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012648#ifdef O_NOLINKS
12649 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012650 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012651#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012652#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012653 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012654 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012655#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012656
Victor Stinner8c62be82010-05-06 00:08:46 +000012657 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012658#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012659 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012660#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012661#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012662 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012663#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012664#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012665 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012666#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012667#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012668 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012669#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012670#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012671 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012672#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012673#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012674 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012675#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012676#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012678#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012679#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012681#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012682#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012684#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012685#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012687#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012688#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012690#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012691#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012693#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012694#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012696#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012697#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012698 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012699#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012700#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012702#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012703#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012704 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012705#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012706#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012707 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012708#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012709
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012710 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012711#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012713#endif /* ST_RDONLY */
12714#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012715 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012716#endif /* ST_NOSUID */
12717
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012718 /* GNU extensions */
12719#ifdef ST_NODEV
12720 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12721#endif /* ST_NODEV */
12722#ifdef ST_NOEXEC
12723 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12724#endif /* ST_NOEXEC */
12725#ifdef ST_SYNCHRONOUS
12726 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12727#endif /* ST_SYNCHRONOUS */
12728#ifdef ST_MANDLOCK
12729 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12730#endif /* ST_MANDLOCK */
12731#ifdef ST_WRITE
12732 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12733#endif /* ST_WRITE */
12734#ifdef ST_APPEND
12735 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12736#endif /* ST_APPEND */
12737#ifdef ST_NOATIME
12738 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12739#endif /* ST_NOATIME */
12740#ifdef ST_NODIRATIME
12741 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12742#endif /* ST_NODIRATIME */
12743#ifdef ST_RELATIME
12744 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12745#endif /* ST_RELATIME */
12746
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012747 /* FreeBSD sendfile() constants */
12748#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012750#endif
12751#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012752 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012753#endif
12754#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012755 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012756#endif
12757
Ross Lagerwall7807c352011-03-17 20:20:30 +020012758 /* constants for posix_fadvise */
12759#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012761#endif
12762#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012764#endif
12765#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012767#endif
12768#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012770#endif
12771#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012773#endif
12774#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012776#endif
12777
12778 /* constants for waitid */
12779#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12781 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12782 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012783#endif
12784#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012786#endif
12787#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012789#endif
12790#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012792#endif
12793#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012795#endif
12796#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012798#endif
12799#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012801#endif
12802#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012804#endif
12805
12806 /* constants for lockf */
12807#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012809#endif
12810#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012812#endif
12813#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012814 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012815#endif
12816#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012817 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012818#endif
12819
Guido van Rossum246bc171999-02-01 23:54:31 +000012820#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012821 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12822 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12823 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12824 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12825 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012826#endif
12827
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012828#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012829 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12830 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12831 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012832#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012833 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012834#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012835#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012836 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012837#endif
12838#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012839 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012840#endif
12841#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012842 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012843#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012844#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012845 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012846#endif
12847#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012848 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012849#endif
12850#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012851 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012852#endif
12853#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012854 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012855#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012856#endif
12857
Benjamin Peterson9428d532011-09-14 11:45:52 -040012858#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012859 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12860 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12861 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012862#endif
12863
Victor Stinner8b905bd2011-10-25 13:34:04 +020012864#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012865 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012866#endif
12867#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012868 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012869#endif
12870#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012871 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012872#endif
12873#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012874 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012875#endif
12876#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012877 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012878#endif
12879#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012880 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012881#endif
12882#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012883 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012884#endif
12885
Victor Stinner8c62be82010-05-06 00:08:46 +000012886 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012887}
12888
12889
Martin v. Löwis1a214512008-06-11 05:26:20 +000012890static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012891 PyModuleDef_HEAD_INIT,
12892 MODNAME,
12893 posix__doc__,
12894 -1,
12895 posix_methods,
12896 NULL,
12897 NULL,
12898 NULL,
12899 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012900};
12901
12902
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012903static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012904
12905#ifdef HAVE_FACCESSAT
12906 "HAVE_FACCESSAT",
12907#endif
12908
12909#ifdef HAVE_FCHDIR
12910 "HAVE_FCHDIR",
12911#endif
12912
12913#ifdef HAVE_FCHMOD
12914 "HAVE_FCHMOD",
12915#endif
12916
12917#ifdef HAVE_FCHMODAT
12918 "HAVE_FCHMODAT",
12919#endif
12920
12921#ifdef HAVE_FCHOWN
12922 "HAVE_FCHOWN",
12923#endif
12924
Larry Hastings00964ed2013-08-12 13:49:30 -040012925#ifdef HAVE_FCHOWNAT
12926 "HAVE_FCHOWNAT",
12927#endif
12928
Larry Hastings9cf065c2012-06-22 16:30:09 -070012929#ifdef HAVE_FEXECVE
12930 "HAVE_FEXECVE",
12931#endif
12932
12933#ifdef HAVE_FDOPENDIR
12934 "HAVE_FDOPENDIR",
12935#endif
12936
Georg Brandl306336b2012-06-24 12:55:33 +020012937#ifdef HAVE_FPATHCONF
12938 "HAVE_FPATHCONF",
12939#endif
12940
Larry Hastings9cf065c2012-06-22 16:30:09 -070012941#ifdef HAVE_FSTATAT
12942 "HAVE_FSTATAT",
12943#endif
12944
12945#ifdef HAVE_FSTATVFS
12946 "HAVE_FSTATVFS",
12947#endif
12948
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012949#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012950 "HAVE_FTRUNCATE",
12951#endif
12952
Larry Hastings9cf065c2012-06-22 16:30:09 -070012953#ifdef HAVE_FUTIMENS
12954 "HAVE_FUTIMENS",
12955#endif
12956
12957#ifdef HAVE_FUTIMES
12958 "HAVE_FUTIMES",
12959#endif
12960
12961#ifdef HAVE_FUTIMESAT
12962 "HAVE_FUTIMESAT",
12963#endif
12964
12965#ifdef HAVE_LINKAT
12966 "HAVE_LINKAT",
12967#endif
12968
12969#ifdef HAVE_LCHFLAGS
12970 "HAVE_LCHFLAGS",
12971#endif
12972
12973#ifdef HAVE_LCHMOD
12974 "HAVE_LCHMOD",
12975#endif
12976
12977#ifdef HAVE_LCHOWN
12978 "HAVE_LCHOWN",
12979#endif
12980
12981#ifdef HAVE_LSTAT
12982 "HAVE_LSTAT",
12983#endif
12984
12985#ifdef HAVE_LUTIMES
12986 "HAVE_LUTIMES",
12987#endif
12988
12989#ifdef HAVE_MKDIRAT
12990 "HAVE_MKDIRAT",
12991#endif
12992
12993#ifdef HAVE_MKFIFOAT
12994 "HAVE_MKFIFOAT",
12995#endif
12996
12997#ifdef HAVE_MKNODAT
12998 "HAVE_MKNODAT",
12999#endif
13000
13001#ifdef HAVE_OPENAT
13002 "HAVE_OPENAT",
13003#endif
13004
13005#ifdef HAVE_READLINKAT
13006 "HAVE_READLINKAT",
13007#endif
13008
13009#ifdef HAVE_RENAMEAT
13010 "HAVE_RENAMEAT",
13011#endif
13012
13013#ifdef HAVE_SYMLINKAT
13014 "HAVE_SYMLINKAT",
13015#endif
13016
13017#ifdef HAVE_UNLINKAT
13018 "HAVE_UNLINKAT",
13019#endif
13020
13021#ifdef HAVE_UTIMENSAT
13022 "HAVE_UTIMENSAT",
13023#endif
13024
13025#ifdef MS_WINDOWS
13026 "MS_WINDOWS",
13027#endif
13028
13029 NULL
13030};
13031
13032
Mark Hammondfe51c6d2002-08-02 02:27:13 +000013033PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000013034INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000013035{
Victor Stinner8c62be82010-05-06 00:08:46 +000013036 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070013037 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020013038 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000013039
Brian Curtin52173d42010-12-02 18:29:18 +000013040#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000013041 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000013042#endif
13043
Victor Stinner8c62be82010-05-06 00:08:46 +000013044 m = PyModule_Create(&posixmodule);
13045 if (m == NULL)
13046 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000013047
Victor Stinner8c62be82010-05-06 00:08:46 +000013048 /* Initialize environ dictionary */
13049 v = convertenviron();
13050 Py_XINCREF(v);
13051 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
13052 return NULL;
13053 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000013054
Victor Stinner8c62be82010-05-06 00:08:46 +000013055 if (all_ins(m))
13056 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000013057
Victor Stinner8c62be82010-05-06 00:08:46 +000013058 if (setup_confname_tables(m))
13059 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000013060
Victor Stinner8c62be82010-05-06 00:08:46 +000013061 Py_INCREF(PyExc_OSError);
13062 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000013063
Guido van Rossumb3d39562000-01-31 18:41:26 +000013064#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000013065 if (posix_putenv_garbage == NULL)
13066 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000013067#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000013068
Victor Stinner8c62be82010-05-06 00:08:46 +000013069 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020013070#if defined(HAVE_WAITID) && !defined(__APPLE__)
13071 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013072 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13073 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013074#endif
13075
Christian Heimes25827622013-10-12 01:27:08 +020013076 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013077 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13078 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13079 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013080 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13081 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013082 structseq_new = StatResultType.tp_new;
13083 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013084
Christian Heimes25827622013-10-12 01:27:08 +020013085 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013086 if (PyStructSequence_InitType2(&StatVFSResultType,
13087 &statvfs_result_desc) < 0)
13088 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013089#ifdef NEED_TICKS_PER_SECOND
13090# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013091 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013092# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013093 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013094# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013095 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013096# endif
13097#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013098
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013099#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013100 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013101 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13102 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013103 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013104#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013105
13106 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013107 if (PyStructSequence_InitType2(&TerminalSizeType,
13108 &TerminalSize_desc) < 0)
13109 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013110
13111 /* initialize scandir types */
13112 if (PyType_Ready(&ScandirIteratorType) < 0)
13113 return NULL;
13114 if (PyType_Ready(&DirEntryType) < 0)
13115 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013116 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013117#if defined(HAVE_WAITID) && !defined(__APPLE__)
13118 Py_INCREF((PyObject*) &WaitidResultType);
13119 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13120#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013121 Py_INCREF((PyObject*) &StatResultType);
13122 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13123 Py_INCREF((PyObject*) &StatVFSResultType);
13124 PyModule_AddObject(m, "statvfs_result",
13125 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013126
13127#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013128 Py_INCREF(&SchedParamType);
13129 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013130#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013131
Larry Hastings605a62d2012-06-24 04:33:36 -070013132 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013133 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13134 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013135 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13136
13137 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013138 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13139 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013140 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13141
Thomas Wouters477c8d52006-05-27 19:21:47 +000013142#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013143 /*
13144 * Step 2 of weak-linking support on Mac OS X.
13145 *
13146 * The code below removes functions that are not available on the
13147 * currently active platform.
13148 *
13149 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013150 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013151 * OSX 10.4.
13152 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013153#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013154 if (fstatvfs == NULL) {
13155 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13156 return NULL;
13157 }
13158 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013159#endif /* HAVE_FSTATVFS */
13160
13161#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013162 if (statvfs == NULL) {
13163 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13164 return NULL;
13165 }
13166 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013167#endif /* HAVE_STATVFS */
13168
13169# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013170 if (lchown == NULL) {
13171 if (PyObject_DelAttrString(m, "lchown") == -1) {
13172 return NULL;
13173 }
13174 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013175#endif /* HAVE_LCHOWN */
13176
13177
13178#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013179
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013180 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013181 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13182
Larry Hastings6fe20b32012-04-19 15:07:49 -070013183 billion = PyLong_FromLong(1000000000);
13184 if (!billion)
13185 return NULL;
13186
Larry Hastings9cf065c2012-06-22 16:30:09 -070013187 /* suppress "function not used" warnings */
13188 {
13189 int ignored;
13190 fd_specified("", -1);
13191 follow_symlinks_specified("", 1);
13192 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13193 dir_fd_converter(Py_None, &ignored);
13194 dir_fd_unavailable(Py_None, &ignored);
13195 }
13196
13197 /*
13198 * provide list of locally available functions
13199 * so os.py can populate support_* lists
13200 */
13201 list = PyList_New(0);
13202 if (!list)
13203 return NULL;
13204 for (trace = have_functions; *trace; trace++) {
13205 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13206 if (!unicode)
13207 return NULL;
13208 if (PyList_Append(list, unicode))
13209 return NULL;
13210 Py_DECREF(unicode);
13211 }
13212 PyModule_AddObject(m, "_have_functions", list);
13213
13214 initialized = 1;
13215
Victor Stinner8c62be82010-05-06 00:08:46 +000013216 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013217}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013218
13219#ifdef __cplusplus
13220}
13221#endif