blob: 367e4f272fe2bd0db2f0ddc21e92505e5cc310e5 [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
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001466 buf = PyMem_New(wchar_t, buf_size+1);
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 Stinnerb6404912013-07-07 16:21:41 +02001476 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001477 return FALSE;
1478 }
1479
1480 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001481 PyMem_Free(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 Stinnerb6404912013-07-07 16:21:41 +02001566 PyMem_Free(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 Stinnerb6404912013-07-07 16:21:41 +02001656 PyMem_Free(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;
3323 tmpbuf = PyMem_RawRealloc(buf, buflen);
3324 if (tmpbuf == NULL)
3325 break;
3326
3327 buf = tmpbuf;
3328 cwd = getcwd(buf, buflen);
3329 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003330 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003331
3332 if (cwd == NULL) {
3333 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003334 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003335 }
3336
Victor Stinner8c62be82010-05-06 00:08:46 +00003337 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003338 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3339 else
3340 obj = PyUnicode_DecodeFSDefault(buf);
3341 PyMem_RawFree(buf);
3342
3343 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003344}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003345
Larry Hastings2f936352014-08-05 14:04:04 +10003346
3347/*[clinic input]
3348os.getcwd
3349
3350Return a unicode string representing the current working directory.
3351[clinic start generated code]*/
3352
Larry Hastings2f936352014-08-05 14:04:04 +10003353static PyObject *
3354os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003355/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003356{
3357 return posix_getcwd(0);
3358}
3359
Larry Hastings2f936352014-08-05 14:04:04 +10003360
3361/*[clinic input]
3362os.getcwdb
3363
3364Return a bytes string representing the current working directory.
3365[clinic start generated code]*/
3366
Larry Hastings2f936352014-08-05 14:04:04 +10003367static PyObject *
3368os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003369/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003370{
3371 return posix_getcwd(1);
3372}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003373
Larry Hastings2f936352014-08-05 14:04:04 +10003374
Larry Hastings9cf065c2012-06-22 16:30:09 -07003375#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3376#define HAVE_LINK 1
3377#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003378
Guido van Rossumb6775db1994-08-01 11:34:53 +00003379#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003380/*[clinic input]
3381
3382os.link
3383
3384 src : path_t
3385 dst : path_t
3386 *
3387 src_dir_fd : dir_fd = None
3388 dst_dir_fd : dir_fd = None
3389 follow_symlinks: bool = True
3390
3391Create a hard link to a file.
3392
3393If either src_dir_fd or dst_dir_fd is not None, it should be a file
3394 descriptor open to a directory, and the respective path string (src or dst)
3395 should be relative; the path will then be relative to that directory.
3396If follow_symlinks is False, and the last element of src is a symbolic
3397 link, link will create a link to the symbolic link itself instead of the
3398 file the link points to.
3399src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3400 platform. If they are unavailable, using them will raise a
3401 NotImplementedError.
3402[clinic start generated code]*/
3403
Larry Hastings2f936352014-08-05 14:04:04 +10003404static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003405os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
3406 int dst_dir_fd, int follow_symlinks)
3407/*[clinic end generated code: output=f47a7e88f7b391b6 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003408{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003409#ifdef MS_WINDOWS
3410 BOOL result;
3411#else
3412 int result;
3413#endif
3414
Larry Hastings9cf065c2012-06-22 16:30:09 -07003415#ifndef HAVE_LINKAT
3416 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3417 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003418 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419 }
3420#endif
3421
Larry Hastings2f936352014-08-05 14:04:04 +10003422 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003423 PyErr_SetString(PyExc_NotImplementedError,
3424 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003425 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003426 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003427
Brian Curtin1b9df392010-11-24 20:24:31 +00003428#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003429 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003430 if (src->wide)
3431 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 else
Larry Hastings2f936352014-08-05 14:04:04 +10003433 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003435
Larry Hastings2f936352014-08-05 14:04:04 +10003436 if (!result)
3437 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003438#else
3439 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003440#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003441 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3442 (dst_dir_fd != DEFAULT_DIR_FD) ||
3443 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003444 result = linkat(src_dir_fd, src->narrow,
3445 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003446 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3447 else
3448#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003449 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003450 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003451
Larry Hastings2f936352014-08-05 14:04:04 +10003452 if (result)
3453 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003454#endif
3455
Larry Hastings2f936352014-08-05 14:04:04 +10003456 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003457}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458#endif
3459
Brian Curtin1b9df392010-11-24 20:24:31 +00003460
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003461#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003462static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003463_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003464{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 PyObject *v;
3466 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3467 BOOL result;
3468 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003469 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003471 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003472 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003473
Gregory P. Smith40a21602013-03-20 20:52:50 -07003474 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003476 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003477
Gregory P. Smith40a21602013-03-20 20:52:50 -07003478 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003479 po_wchars = L".";
3480 len = 1;
3481 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003482 po_wchars = path->wide;
3483 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003484 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003485 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003486 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 if (!wnamebuf) {
3488 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003490 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003491 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003492 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003493 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003494 if (wch != SEP && wch != ALTSEP && wch != L':')
3495 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003496 wcscpy(wnamebuf + len, L"*.*");
3497 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003498 if ((list = PyList_New(0)) == NULL) {
3499 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003500 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003501 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003502 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003503 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 if (hFindFile == INVALID_HANDLE_VALUE) {
3505 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003506 if (error == ERROR_FILE_NOT_FOUND)
3507 goto exit;
3508 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003510 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 }
3512 do {
3513 /* Skip over . and .. */
3514 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3515 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 v = PyUnicode_FromWideChar(wFileData.cFileName,
3517 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003518 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003519 Py_DECREF(list);
3520 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003521 break;
3522 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003523 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003525 Py_DECREF(list);
3526 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003527 break;
3528 }
3529 Py_DECREF(v);
3530 }
3531 Py_BEGIN_ALLOW_THREADS
3532 result = FindNextFileW(hFindFile, &wFileData);
3533 Py_END_ALLOW_THREADS
3534 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3535 it got to the end of the directory. */
3536 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003537 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003538 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003539 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 }
3541 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003542
Larry Hastings9cf065c2012-06-22 16:30:09 -07003543 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003545 strcpy(namebuf, path->narrow);
3546 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003547 if (len > 0) {
3548 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003549 if (ch != '\\' && ch != '/' && ch != ':')
3550 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 strcpy(namebuf + len, "*.*");
3552 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003553
Larry Hastings9cf065c2012-06-22 16:30:09 -07003554 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003556
Antoine Pitroub73caab2010-08-09 23:39:31 +00003557 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003558 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003559 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 if (hFindFile == INVALID_HANDLE_VALUE) {
3561 int error = GetLastError();
3562 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003563 goto exit;
3564 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003565 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003566 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003567 }
3568 do {
3569 /* Skip over . and .. */
3570 if (strcmp(FileData.cFileName, ".") != 0 &&
3571 strcmp(FileData.cFileName, "..") != 0) {
3572 v = PyBytes_FromString(FileData.cFileName);
3573 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003574 Py_DECREF(list);
3575 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003576 break;
3577 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003578 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003579 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003580 Py_DECREF(list);
3581 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003582 break;
3583 }
3584 Py_DECREF(v);
3585 }
3586 Py_BEGIN_ALLOW_THREADS
3587 result = FindNextFile(hFindFile, &FileData);
3588 Py_END_ALLOW_THREADS
3589 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3590 it got to the end of the directory. */
3591 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003593 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003594 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003595 }
3596 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003597
Larry Hastings9cf065c2012-06-22 16:30:09 -07003598exit:
3599 if (hFindFile != INVALID_HANDLE_VALUE) {
3600 if (FindClose(hFindFile) == FALSE) {
3601 if (list != NULL) {
3602 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003603 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 }
3605 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003606 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003607 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003608
Larry Hastings9cf065c2012-06-22 16:30:09 -07003609 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003610} /* end of _listdir_windows_no_opendir */
3611
3612#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3613
3614static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003615_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003616{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003617 PyObject *v;
3618 DIR *dirp = NULL;
3619 struct dirent *ep;
3620 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003621#ifdef HAVE_FDOPENDIR
3622 int fd = -1;
3623#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003624
Victor Stinner8c62be82010-05-06 00:08:46 +00003625 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003626#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003627 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003629 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003630 if (fd == -1)
3631 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003632
Larry Hastingsfdaea062012-06-25 04:42:23 -07003633 return_str = 1;
3634
Larry Hastings9cf065c2012-06-22 16:30:09 -07003635 Py_BEGIN_ALLOW_THREADS
3636 dirp = fdopendir(fd);
3637 Py_END_ALLOW_THREADS
3638 }
3639 else
3640#endif
3641 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003642 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003643 if (path->narrow) {
3644 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003645 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003646 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003647 }
3648 else {
3649 name = ".";
3650 return_str = 1;
3651 }
3652
Larry Hastings9cf065c2012-06-22 16:30:09 -07003653 Py_BEGIN_ALLOW_THREADS
3654 dirp = opendir(name);
3655 Py_END_ALLOW_THREADS
3656 }
3657
3658 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003659 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003660#ifdef HAVE_FDOPENDIR
3661 if (fd != -1) {
3662 Py_BEGIN_ALLOW_THREADS
3663 close(fd);
3664 Py_END_ALLOW_THREADS
3665 }
3666#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003667 goto exit;
3668 }
3669 if ((list = PyList_New(0)) == NULL) {
3670 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003671 }
3672 for (;;) {
3673 errno = 0;
3674 Py_BEGIN_ALLOW_THREADS
3675 ep = readdir(dirp);
3676 Py_END_ALLOW_THREADS
3677 if (ep == NULL) {
3678 if (errno == 0) {
3679 break;
3680 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003682 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003683 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003684 }
3685 }
3686 if (ep->d_name[0] == '.' &&
3687 (NAMLEN(ep) == 1 ||
3688 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3689 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003690 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003691 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3692 else
3693 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003698 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003699 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003700 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003701 break;
3702 }
3703 Py_DECREF(v);
3704 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003705
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706exit:
3707 if (dirp != NULL) {
3708 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003709#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 if (fd > -1)
3711 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003712#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003713 closedir(dirp);
3714 Py_END_ALLOW_THREADS
3715 }
3716
Larry Hastings9cf065c2012-06-22 16:30:09 -07003717 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003718} /* end of _posix_listdir */
3719#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003720
Larry Hastings2f936352014-08-05 14:04:04 +10003721
3722/*[clinic input]
3723os.listdir
3724
3725 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3726
3727Return a list containing the names of the files in the directory.
3728
3729path can be specified as either str or bytes. If path is bytes,
3730 the filenames returned will also be bytes; in all other circumstances
3731 the filenames returned will be str.
3732If path is None, uses the path='.'.
3733On some platforms, path may also be specified as an open file descriptor;\
3734 the file descriptor must refer to a directory.
3735 If this functionality is unavailable, using it raises NotImplementedError.
3736
3737The list is in arbitrary order. It does not include the special
3738entries '.' and '..' even if they are present in the directory.
3739
3740
3741[clinic start generated code]*/
3742
Larry Hastings2f936352014-08-05 14:04:04 +10003743static PyObject *
3744os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003745/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003746{
3747#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3748 return _listdir_windows_no_opendir(path, NULL);
3749#else
3750 return _posix_listdir(path, NULL);
3751#endif
3752}
3753
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003754#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003755/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003756/*[clinic input]
3757os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003758
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003759 path: path_t
3760 /
3761
3762[clinic start generated code]*/
3763
3764static PyObject *
3765os__getfullpathname_impl(PyModuleDef *module, path_t *path)
3766/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/
3767{
3768 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769 {
Victor Stinner75875072013-11-24 19:23:25 +01003770 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003771 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 DWORD result;
3773 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003774
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003775 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003776 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003777 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003778 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003779 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003780 if (!woutbufp)
3781 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003782 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 }
3784 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003785 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003786 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003788 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003789 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003790 return v;
3791 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003792 else {
3793 char outbuf[MAX_PATH];
3794 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003795
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003796 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3797 outbuf, &temp)) {
3798 win32_error_object("GetFullPathName", path->object);
3799 return NULL;
3800 }
3801 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003802 }
Larry Hastings2f936352014-08-05 14:04:04 +10003803}
Brian Curtind40e6f72010-07-08 21:39:08 +00003804
Brian Curtind25aef52011-06-13 15:16:04 -05003805
Larry Hastings2f936352014-08-05 14:04:04 +10003806/*[clinic input]
3807os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003808
Larry Hastings2f936352014-08-05 14:04:04 +10003809 path: unicode
3810 /
3811
3812A helper function for samepath on windows.
3813[clinic start generated code]*/
3814
Larry Hastings2f936352014-08-05 14:04:04 +10003815static PyObject *
3816os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003817/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003818{
3819 HANDLE hFile;
3820 int buf_size;
3821 wchar_t *target_path;
3822 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003823 PyObject *result;
3824 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003825
Larry Hastings2f936352014-08-05 14:04:04 +10003826 path_wchar = PyUnicode_AsUnicode(path);
3827 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003828 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003829
Brian Curtind40e6f72010-07-08 21:39:08 +00003830 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003831 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003832 0, /* desired access */
3833 0, /* share mode */
3834 NULL, /* security attributes */
3835 OPEN_EXISTING,
3836 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3837 FILE_FLAG_BACKUP_SEMANTICS,
3838 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003839
Victor Stinnereb5657a2011-09-30 01:44:27 +02003840 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003841 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003842
3843 /* We have a good handle to the target, use it to determine the
3844 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003845 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003846
3847 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003848 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003849
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003850 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003851 if(!target_path)
3852 return PyErr_NoMemory();
3853
Steve Dower2ea51c92015-03-20 21:49:12 -07003854 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3855 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003857 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003858
3859 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003860 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003861
3862 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003863 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003864 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003865 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003866}
Brian Curtin62857742010-09-06 17:07:27 +00003867
Brian Curtin95d028f2011-06-09 09:10:38 -05003868PyDoc_STRVAR(posix__isdir__doc__,
3869"Return true if the pathname refers to an existing directory.");
3870
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003871/*[clinic input]
3872os._isdir
3873
3874 path: path_t
3875 /
3876
3877[clinic start generated code]*/
3878
Brian Curtin9c669cc2011-06-08 18:17:18 -05003879static PyObject *
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003880os__isdir_impl(PyModuleDef *module, path_t *path)
3881/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003882{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003883 DWORD attributes;
3884
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003885 if (!path->narrow)
3886 attributes = GetFileAttributesW(path->wide);
3887 else
3888 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003889
Brian Curtin9c669cc2011-06-08 18:17:18 -05003890 if (attributes == INVALID_FILE_ATTRIBUTES)
3891 Py_RETURN_FALSE;
3892
Brian Curtin9c669cc2011-06-08 18:17:18 -05003893 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3894 Py_RETURN_TRUE;
3895 else
3896 Py_RETURN_FALSE;
3897}
Tim Golden6b528062013-08-01 12:44:00 +01003898
Tim Golden6b528062013-08-01 12:44:00 +01003899
Larry Hastings2f936352014-08-05 14:04:04 +10003900/*[clinic input]
3901os._getvolumepathname
3902
3903 path: unicode
3904
3905A helper function for ismount on Win32.
3906[clinic start generated code]*/
3907
Larry Hastings2f936352014-08-05 14:04:04 +10003908static PyObject *
3909os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003910/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003911{
3912 PyObject *result;
3913 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003914 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003915 BOOL ret;
3916
Larry Hastings2f936352014-08-05 14:04:04 +10003917 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3918 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003919 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003920 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003921
3922 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003923 buflen = Py_MAX(buflen, MAX_PATH);
3924
3925 if (buflen > DWORD_MAX) {
3926 PyErr_SetString(PyExc_OverflowError, "path too long");
3927 return NULL;
3928 }
3929
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003930 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003931 if (mountpath == NULL)
3932 return PyErr_NoMemory();
3933
3934 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003935 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003936 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003937 Py_END_ALLOW_THREADS
3938
3939 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003940 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003941 goto exit;
3942 }
3943 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3944
3945exit:
3946 PyMem_Free(mountpath);
3947 return result;
3948}
Tim Golden6b528062013-08-01 12:44:00 +01003949
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003950#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003951
Larry Hastings2f936352014-08-05 14:04:04 +10003952
3953/*[clinic input]
3954os.mkdir
3955
3956 path : path_t
3957
3958 mode: int = 0o777
3959
3960 *
3961
3962 dir_fd : dir_fd(requires='mkdirat') = None
3963
3964# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3965
3966Create a directory.
3967
3968If dir_fd is not None, it should be a file descriptor open to a directory,
3969 and path should be relative; path will then be relative to that directory.
3970dir_fd may not be implemented on your platform.
3971 If it is unavailable, using it will raise a NotImplementedError.
3972
3973The mode argument is ignored on Windows.
3974[clinic start generated code]*/
3975
Larry Hastings2f936352014-08-05 14:04:04 +10003976static PyObject *
3977os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003978/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003979{
3980 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003981
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003982#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003984 if (path->wide)
3985 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003986 else
Larry Hastings2f936352014-08-05 14:04:04 +10003987 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003988 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003989
Larry Hastings2f936352014-08-05 14:04:04 +10003990 if (!result)
3991 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003993 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003994#if HAVE_MKDIRAT
3995 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003996 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003997 else
3998#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003999#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10004000 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004001#else
Larry Hastings2f936352014-08-05 14:04:04 +10004002 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004003#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004004 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004005 if (result < 0)
4006 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004007#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004008 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004009}
4010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004011
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004012/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4013#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004014#include <sys/resource.h>
4015#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004016
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004017
4018#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004019/*[clinic input]
4020os.nice
4021
4022 increment: int
4023 /
4024
4025Add increment to the priority of process and return the new priority.
4026[clinic start generated code]*/
4027
Larry Hastings2f936352014-08-05 14:04:04 +10004028static PyObject *
4029os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004030/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004031{
4032 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004033
Victor Stinner8c62be82010-05-06 00:08:46 +00004034 /* There are two flavours of 'nice': one that returns the new
4035 priority (as required by almost all standards out there) and the
4036 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4037 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004038
Victor Stinner8c62be82010-05-06 00:08:46 +00004039 If we are of the nice family that returns the new priority, we
4040 need to clear errno before the call, and check if errno is filled
4041 before calling posix_error() on a returnvalue of -1, because the
4042 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004043
Victor Stinner8c62be82010-05-06 00:08:46 +00004044 errno = 0;
4045 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004046#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004047 if (value == 0)
4048 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004049#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004050 if (value == -1 && errno != 0)
4051 /* either nice() or getpriority() returned an error */
4052 return posix_error();
4053 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004054}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004055#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004056
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004057
4058#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004059/*[clinic input]
4060os.getpriority
4061
4062 which: int
4063 who: int
4064
4065Return program scheduling priority.
4066[clinic start generated code]*/
4067
Larry Hastings2f936352014-08-05 14:04:04 +10004068static PyObject *
4069os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004070/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004071{
4072 int retval;
4073
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004074 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004075 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004076 if (errno != 0)
4077 return posix_error();
4078 return PyLong_FromLong((long)retval);
4079}
4080#endif /* HAVE_GETPRIORITY */
4081
4082
4083#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004084/*[clinic input]
4085os.setpriority
4086
4087 which: int
4088 who: int
4089 priority: int
4090
4091Set program scheduling priority.
4092[clinic start generated code]*/
4093
Larry Hastings2f936352014-08-05 14:04:04 +10004094static PyObject *
4095os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004096/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004097{
4098 int retval;
4099
4100 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004101 if (retval == -1)
4102 return posix_error();
4103 Py_RETURN_NONE;
4104}
4105#endif /* HAVE_SETPRIORITY */
4106
4107
Barry Warsaw53699e91996-12-10 23:23:01 +00004108static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004109internal_rename(path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int is_replace)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004110{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004112 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004114#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004115 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004116 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004117#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004118 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004119#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120
Larry Hastings9cf065c2012-06-22 16:30:09 -07004121 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4122 (dst_dir_fd != DEFAULT_DIR_FD);
4123#ifndef HAVE_RENAMEAT
4124 if (dir_fd_specified) {
4125 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004126 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 }
4128#endif
4129
Larry Hastings2f936352014-08-05 14:04:04 +10004130 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004131 PyErr_Format(PyExc_ValueError,
4132 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004133 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 }
4135
4136#ifdef MS_WINDOWS
4137 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004138 if (src->wide)
4139 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004140 else
Larry Hastings2f936352014-08-05 14:04:04 +10004141 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004142 Py_END_ALLOW_THREADS
4143
Larry Hastings2f936352014-08-05 14:04:04 +10004144 if (!result)
4145 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004146
4147#else
4148 Py_BEGIN_ALLOW_THREADS
4149#ifdef HAVE_RENAMEAT
4150 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004151 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152 else
4153#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004154 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155 Py_END_ALLOW_THREADS
4156
Larry Hastings2f936352014-08-05 14:04:04 +10004157 if (result)
4158 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004159#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004160 Py_RETURN_NONE;
4161}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004162
Larry Hastings2f936352014-08-05 14:04:04 +10004163
4164/*[clinic input]
4165os.rename
4166
4167 src : path_t
4168 dst : path_t
4169 *
4170 src_dir_fd : dir_fd = None
4171 dst_dir_fd : dir_fd = None
4172
4173Rename a file or directory.
4174
4175If either src_dir_fd or dst_dir_fd is not None, it should be a file
4176 descriptor open to a directory, and the respective path string (src or dst)
4177 should be relative; the path will then be relative to that directory.
4178src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4179 If they are unavailable, using them will raise a NotImplementedError.
4180[clinic start generated code]*/
4181
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004182static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004183os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
4184 int dst_dir_fd)
4185/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004186{
Larry Hastings2f936352014-08-05 14:04:04 +10004187 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004188}
4189
Larry Hastings2f936352014-08-05 14:04:04 +10004190
4191/*[clinic input]
4192os.replace = os.rename
4193
4194Rename a file or directory, overwriting the destination.
4195
4196If either src_dir_fd or dst_dir_fd is not None, it should be a file
4197 descriptor open to a directory, and the respective path string (src or dst)
4198 should be relative; the path will then be relative to that directory.
4199src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4200 If they are unavailable, using them will raise a NotImplementedError."
4201[clinic start generated code]*/
4202
Larry Hastings2f936352014-08-05 14:04:04 +10004203static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004204os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst,
4205 int src_dir_fd, int dst_dir_fd)
4206/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004207{
4208 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4209}
4210
4211
4212/*[clinic input]
4213os.rmdir
4214
4215 path: path_t
4216 *
4217 dir_fd: dir_fd(requires='unlinkat') = None
4218
4219Remove a directory.
4220
4221If dir_fd is not None, it should be a file descriptor open to a directory,
4222 and path should be relative; path will then be relative to that directory.
4223dir_fd may not be implemented on your platform.
4224 If it is unavailable, using it will raise a NotImplementedError.
4225[clinic start generated code]*/
4226
Larry Hastings2f936352014-08-05 14:04:04 +10004227static PyObject *
4228os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004229/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004230{
4231 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004232
4233 Py_BEGIN_ALLOW_THREADS
4234#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004235 if (path->wide)
4236 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004237 else
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004239 result = !result; /* Windows, success=1, UNIX, success=0 */
4240#else
4241#ifdef HAVE_UNLINKAT
4242 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004243 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004244 else
4245#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004246 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247#endif
4248 Py_END_ALLOW_THREADS
4249
Larry Hastings2f936352014-08-05 14:04:04 +10004250 if (result)
4251 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004252
Larry Hastings2f936352014-08-05 14:04:04 +10004253 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004254}
4255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004256
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004257#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004258#ifdef MS_WINDOWS
4259/*[clinic input]
4260os.system -> long
4261
4262 command: Py_UNICODE
4263
4264Execute the command in a subshell.
4265[clinic start generated code]*/
4266
Larry Hastings2f936352014-08-05 14:04:04 +10004267static long
4268os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004269/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004270{
4271 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004272 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004273 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004274 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004275 return result;
4276}
4277#else /* MS_WINDOWS */
4278/*[clinic input]
4279os.system -> long
4280
4281 command: FSConverter
4282
4283Execute the command in a subshell.
4284[clinic start generated code]*/
4285
Larry Hastings2f936352014-08-05 14:04:04 +10004286static long
4287os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004288/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004289{
4290 long result;
4291 char *bytes = PyBytes_AsString(command);
4292 Py_BEGIN_ALLOW_THREADS
4293 result = system(bytes);
4294 Py_END_ALLOW_THREADS
4295 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004296}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004297#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004298#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004299
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004300
Larry Hastings2f936352014-08-05 14:04:04 +10004301/*[clinic input]
4302os.umask
4303
4304 mask: int
4305 /
4306
4307Set the current numeric umask and return the previous umask.
4308[clinic start generated code]*/
4309
Larry Hastings2f936352014-08-05 14:04:04 +10004310static PyObject *
4311os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004312/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004313{
4314 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004315 if (i < 0)
4316 return posix_error();
4317 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004318}
4319
Brian Curtind40e6f72010-07-08 21:39:08 +00004320#ifdef MS_WINDOWS
4321
4322/* override the default DeleteFileW behavior so that directory
4323symlinks can be removed with this function, the same as with
4324Unix symlinks */
4325BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4326{
4327 WIN32_FILE_ATTRIBUTE_DATA info;
4328 WIN32_FIND_DATAW find_data;
4329 HANDLE find_data_handle;
4330 int is_directory = 0;
4331 int is_link = 0;
4332
4333 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4334 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004335
Brian Curtind40e6f72010-07-08 21:39:08 +00004336 /* Get WIN32_FIND_DATA structure for the path to determine if
4337 it is a symlink */
4338 if(is_directory &&
4339 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4340 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4341
4342 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004343 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4344 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4345 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4346 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004347 FindClose(find_data_handle);
4348 }
4349 }
4350 }
4351
4352 if (is_directory && is_link)
4353 return RemoveDirectoryW(lpFileName);
4354
4355 return DeleteFileW(lpFileName);
4356}
4357#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004358
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004359
Larry Hastings2f936352014-08-05 14:04:04 +10004360/*[clinic input]
4361os.unlink
4362
4363 path: path_t
4364 *
4365 dir_fd: dir_fd(requires='unlinkat')=None
4366
4367Remove a file (same as remove()).
4368
4369If dir_fd is not None, it should be a file descriptor open to a directory,
4370 and path should be relative; path will then be relative to that directory.
4371dir_fd may not be implemented on your platform.
4372 If it is unavailable, using it will raise a NotImplementedError.
4373
4374[clinic start generated code]*/
4375
Larry Hastings2f936352014-08-05 14:04:04 +10004376static PyObject *
4377os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004378/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004379{
4380 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004381
4382 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004383 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004385 if (path->wide)
4386 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004387 else
Larry Hastings2f936352014-08-05 14:04:04 +10004388 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 result = !result; /* Windows, success=1, UNIX, success=0 */
4390#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004391#ifdef HAVE_UNLINKAT
4392 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004393 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 else
4395#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004396 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004397#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004398 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004399 Py_END_ALLOW_THREADS
4400
Larry Hastings2f936352014-08-05 14:04:04 +10004401 if (result)
4402 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004403
Larry Hastings2f936352014-08-05 14:04:04 +10004404 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004405}
4406
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004407
Larry Hastings2f936352014-08-05 14:04:04 +10004408/*[clinic input]
4409os.remove = os.unlink
4410
4411Remove a file (same as unlink()).
4412
4413If dir_fd is not None, it should be a file descriptor open to a directory,
4414 and path should be relative; path will then be relative to that directory.
4415dir_fd may not be implemented on your platform.
4416 If it is unavailable, using it will raise a NotImplementedError.
4417[clinic start generated code]*/
4418
Larry Hastings2f936352014-08-05 14:04:04 +10004419static PyObject *
4420os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004421/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004422{
4423 return os_unlink_impl(module, path, dir_fd);
4424}
4425
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004426
Larry Hastings605a62d2012-06-24 04:33:36 -07004427static PyStructSequence_Field uname_result_fields[] = {
4428 {"sysname", "operating system name"},
4429 {"nodename", "name of machine on network (implementation-defined)"},
4430 {"release", "operating system release"},
4431 {"version", "operating system version"},
4432 {"machine", "hardware identifier"},
4433 {NULL}
4434};
4435
4436PyDoc_STRVAR(uname_result__doc__,
4437"uname_result: Result from os.uname().\n\n\
4438This object may be accessed either as a tuple of\n\
4439 (sysname, nodename, release, version, machine),\n\
4440or via the attributes sysname, nodename, release, version, and machine.\n\
4441\n\
4442See os.uname for more information.");
4443
4444static PyStructSequence_Desc uname_result_desc = {
4445 "uname_result", /* name */
4446 uname_result__doc__, /* doc */
4447 uname_result_fields,
4448 5
4449};
4450
4451static PyTypeObject UnameResultType;
4452
4453
4454#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004455/*[clinic input]
4456os.uname
4457
4458Return an object identifying the current operating system.
4459
4460The object behaves like a named tuple with the following fields:
4461 (sysname, nodename, release, version, machine)
4462
4463[clinic start generated code]*/
4464
Larry Hastings2f936352014-08-05 14:04:04 +10004465static PyObject *
4466os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004467/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004468{
Victor Stinner8c62be82010-05-06 00:08:46 +00004469 struct utsname u;
4470 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004471 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004472
Victor Stinner8c62be82010-05-06 00:08:46 +00004473 Py_BEGIN_ALLOW_THREADS
4474 res = uname(&u);
4475 Py_END_ALLOW_THREADS
4476 if (res < 0)
4477 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004478
4479 value = PyStructSequence_New(&UnameResultType);
4480 if (value == NULL)
4481 return NULL;
4482
4483#define SET(i, field) \
4484 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004485 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004486 if (!o) { \
4487 Py_DECREF(value); \
4488 return NULL; \
4489 } \
4490 PyStructSequence_SET_ITEM(value, i, o); \
4491 } \
4492
4493 SET(0, u.sysname);
4494 SET(1, u.nodename);
4495 SET(2, u.release);
4496 SET(3, u.version);
4497 SET(4, u.machine);
4498
4499#undef SET
4500
4501 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004502}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004503#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004504
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004505
Larry Hastings9cf065c2012-06-22 16:30:09 -07004506
4507typedef struct {
4508 int now;
4509 time_t atime_s;
4510 long atime_ns;
4511 time_t mtime_s;
4512 long mtime_ns;
4513} utime_t;
4514
4515/*
Victor Stinner484df002014-10-09 13:52:31 +02004516 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004517 * they also intentionally leak the declaration of a pointer named "time"
4518 */
4519#define UTIME_TO_TIMESPEC \
4520 struct timespec ts[2]; \
4521 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004522 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004523 time = NULL; \
4524 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004525 ts[0].tv_sec = ut->atime_s; \
4526 ts[0].tv_nsec = ut->atime_ns; \
4527 ts[1].tv_sec = ut->mtime_s; \
4528 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 time = ts; \
4530 } \
4531
4532#define UTIME_TO_TIMEVAL \
4533 struct timeval tv[2]; \
4534 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004535 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004536 time = NULL; \
4537 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004538 tv[0].tv_sec = ut->atime_s; \
4539 tv[0].tv_usec = ut->atime_ns / 1000; \
4540 tv[1].tv_sec = ut->mtime_s; \
4541 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 time = tv; \
4543 } \
4544
4545#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004546 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004548 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 time = NULL; \
4550 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004551 u.actime = ut->atime_s; \
4552 u.modtime = ut->mtime_s; \
4553 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554 }
4555
4556#define UTIME_TO_TIME_T \
4557 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004558 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004559 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 time = NULL; \
4561 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004562 timet[0] = ut->atime_s; \
4563 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004564 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565 } \
4566
4567
Victor Stinner528a9ab2015-09-03 21:30:26 +02004568#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004569
4570static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004571utime_dir_fd(utime_t *ut, int dir_fd, const char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004572{
4573#ifdef HAVE_UTIMENSAT
4574 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4575 UTIME_TO_TIMESPEC;
4576 return utimensat(dir_fd, path, time, flags);
4577#elif defined(HAVE_FUTIMESAT)
4578 UTIME_TO_TIMEVAL;
4579 /*
4580 * follow_symlinks will never be false here;
4581 * we only allow !follow_symlinks and dir_fd together
4582 * if we have utimensat()
4583 */
4584 assert(follow_symlinks);
4585 return futimesat(dir_fd, path, time);
4586#endif
4587}
4588
Larry Hastings2f936352014-08-05 14:04:04 +10004589 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4590#else
4591 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004592#endif
4593
Victor Stinner528a9ab2015-09-03 21:30:26 +02004594#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595
4596static int
Victor Stinner484df002014-10-09 13:52:31 +02004597utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004598{
4599#ifdef HAVE_FUTIMENS
4600 UTIME_TO_TIMESPEC;
4601 return futimens(fd, time);
4602#else
4603 UTIME_TO_TIMEVAL;
4604 return futimes(fd, time);
4605#endif
4606}
4607
Larry Hastings2f936352014-08-05 14:04:04 +10004608 #define PATH_UTIME_HAVE_FD 1
4609#else
4610 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611#endif
4612
Victor Stinner5ebae872015-09-22 01:29:33 +02004613#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4614# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4615#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004616
Victor Stinner4552ced2015-09-21 22:37:15 +02004617#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004618
4619static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004620utime_nofollow_symlinks(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621{
4622#ifdef HAVE_UTIMENSAT
4623 UTIME_TO_TIMESPEC;
4624 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4625#else
4626 UTIME_TO_TIMEVAL;
4627 return lutimes(path, time);
4628#endif
4629}
4630
4631#endif
4632
4633#ifndef MS_WINDOWS
4634
4635static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02004636utime_default(utime_t *ut, const char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004637{
4638#ifdef HAVE_UTIMENSAT
4639 UTIME_TO_TIMESPEC;
4640 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4641#elif defined(HAVE_UTIMES)
4642 UTIME_TO_TIMEVAL;
4643 return utimes(path, time);
4644#elif defined(HAVE_UTIME_H)
4645 UTIME_TO_UTIMBUF;
4646 return utime(path, time);
4647#else
4648 UTIME_TO_TIME_T;
4649 return utime(path, time);
4650#endif
4651}
4652
4653#endif
4654
Larry Hastings76ad59b2012-05-03 00:30:07 -07004655static int
4656split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4657{
4658 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004659 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004660 divmod = PyNumber_Divmod(py_long, billion);
4661 if (!divmod)
4662 goto exit;
4663 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4664 if ((*s == -1) && PyErr_Occurred())
4665 goto exit;
4666 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004667 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004668 goto exit;
4669
4670 result = 1;
4671exit:
4672 Py_XDECREF(divmod);
4673 return result;
4674}
4675
Larry Hastings2f936352014-08-05 14:04:04 +10004676
4677/*[clinic input]
4678os.utime
4679
4680 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4681 times: object = NULL
4682 *
4683 ns: object = NULL
4684 dir_fd: dir_fd(requires='futimensat') = None
4685 follow_symlinks: bool=True
4686
Martin Panter0ff89092015-09-09 01:56:53 +00004687# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004688
4689Set the access and modified time of path.
4690
4691path may always be specified as a string.
4692On some platforms, path may also be specified as an open file descriptor.
4693 If this functionality is unavailable, using it raises an exception.
4694
4695If times is not None, it must be a tuple (atime, mtime);
4696 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004697If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004698 atime_ns and mtime_ns should be expressed as integer nanoseconds
4699 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004700If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004701Specifying tuples for both times and ns is an error.
4702
4703If dir_fd is not None, it should be a file descriptor open to a directory,
4704 and path should be relative; path will then be relative to that directory.
4705If follow_symlinks is False, and the last element of the path is a symbolic
4706 link, utime will modify the symbolic link itself instead of the file the
4707 link points to.
4708It is an error to use dir_fd or follow_symlinks when specifying path
4709 as an open file descriptor.
4710dir_fd and follow_symlinks may not be available on your platform.
4711 If they are unavailable, using them will raise a NotImplementedError.
4712
4713[clinic start generated code]*/
4714
Larry Hastings2f936352014-08-05 14:04:04 +10004715static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004716os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times,
4717 PyObject *ns, int dir_fd, int follow_symlinks)
Martin Panter0ff89092015-09-09 01:56:53 +00004718/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004719{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720#ifdef MS_WINDOWS
4721 HANDLE hFile;
4722 FILETIME atime, mtime;
4723#else
4724 int result;
4725#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004726
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004728 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004729
Christian Heimesb3c87242013-08-01 00:08:16 +02004730 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004731
Larry Hastings9cf065c2012-06-22 16:30:09 -07004732 if (times && (times != Py_None) && ns) {
4733 PyErr_SetString(PyExc_ValueError,
4734 "utime: you may specify either 'times'"
4735 " or 'ns' but not both");
4736 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004737 }
4738
4739 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004740 time_t a_sec, m_sec;
4741 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 PyErr_SetString(PyExc_TypeError,
4744 "utime: 'times' must be either"
4745 " a tuple of two ints or None");
4746 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004747 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004749 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004750 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004751 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004752 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004754 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004755 utime.atime_s = a_sec;
4756 utime.atime_ns = a_nsec;
4757 utime.mtime_s = m_sec;
4758 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004759 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004760 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004761 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762 PyErr_SetString(PyExc_TypeError,
4763 "utime: 'ns' must be a tuple of two ints");
4764 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004765 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004767 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004769 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 &utime.mtime_s, &utime.mtime_ns)) {
4771 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004772 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 }
4774 else {
4775 /* times and ns are both None/unspecified. use "now". */
4776 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004777 }
4778
Victor Stinner4552ced2015-09-21 22:37:15 +02004779#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 if (follow_symlinks_specified("utime", follow_symlinks))
4781 goto exit;
4782#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004783
Larry Hastings2f936352014-08-05 14:04:04 +10004784 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4785 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4786 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004788
Larry Hastings9cf065c2012-06-22 16:30:09 -07004789#if !defined(HAVE_UTIMENSAT)
4790 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004791 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 "utime: cannot use dir_fd and follow_symlinks "
4793 "together on this platform");
4794 goto exit;
4795 }
4796#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004797
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004798#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004800 if (path->wide)
4801 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004802 NULL, OPEN_EXISTING,
4803 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 else
Larry Hastings2f936352014-08-05 14:04:04 +10004805 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004806 NULL, OPEN_EXISTING,
4807 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004808 Py_END_ALLOW_THREADS
4809 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004810 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004812 }
4813
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004815 GetSystemTimeAsFileTime(&mtime);
4816 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004817 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004818 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004819 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4820 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004821 }
4822 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4823 /* Avoid putting the file name into the error here,
4824 as that may confuse the user into believing that
4825 something is wrong with the file, when it also
4826 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004827 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004829 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004830#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004832
Victor Stinner4552ced2015-09-21 22:37:15 +02004833#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004834 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004835 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004836 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004837#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004838
Victor Stinner528a9ab2015-09-03 21:30:26 +02004839#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004840 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004841 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004842 else
4843#endif
4844
Victor Stinner528a9ab2015-09-03 21:30:26 +02004845#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004846 if (path->fd != -1)
4847 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004848 else
4849#endif
4850
Larry Hastings2f936352014-08-05 14:04:04 +10004851 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004852
4853 Py_END_ALLOW_THREADS
4854
4855 if (result < 0) {
4856 /* see previous comment about not putting filename in error here */
4857 return_value = posix_error();
4858 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004859 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004860
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004861#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862
4863 Py_INCREF(Py_None);
4864 return_value = Py_None;
4865
4866exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004867#ifdef MS_WINDOWS
4868 if (hFile != INVALID_HANDLE_VALUE)
4869 CloseHandle(hFile);
4870#endif
4871 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004872}
4873
Guido van Rossum3b066191991-06-04 19:40:25 +00004874/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004875
Larry Hastings2f936352014-08-05 14:04:04 +10004876
4877/*[clinic input]
4878os._exit
4879
4880 status: int
4881
4882Exit to the system with specified status, without normal exit processing.
4883[clinic start generated code]*/
4884
Larry Hastings2f936352014-08-05 14:04:04 +10004885static PyObject *
4886os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004887/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004888{
4889 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004891}
4892
Martin v. Löwis114619e2002-10-07 06:44:21 +00004893#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4894static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004895free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004896{
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 Py_ssize_t i;
4898 for (i = 0; i < count; i++)
4899 PyMem_Free(array[i]);
4900 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004901}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004902
Antoine Pitrou69f71142009-05-24 21:25:49 +00004903static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004904int fsconvert_strdup(PyObject *o, char**out)
4905{
Victor Stinner8c62be82010-05-06 00:08:46 +00004906 PyObject *bytes;
4907 Py_ssize_t size;
4908 if (!PyUnicode_FSConverter(o, &bytes))
4909 return 0;
4910 size = PyBytes_GET_SIZE(bytes);
4911 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004912 if (!*out) {
4913 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004914 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004915 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 memcpy(*out, PyBytes_AsString(bytes), size+1);
4917 Py_DECREF(bytes);
4918 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004919}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004920#endif
4921
Ross Lagerwall7807c352011-03-17 20:20:30 +02004922#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004923static char**
4924parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4925{
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 char **envlist;
4927 Py_ssize_t i, pos, envc;
4928 PyObject *keys=NULL, *vals=NULL;
4929 PyObject *key, *val, *key2, *val2;
4930 char *p, *k, *v;
4931 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004932
Victor Stinner8c62be82010-05-06 00:08:46 +00004933 i = PyMapping_Size(env);
4934 if (i < 0)
4935 return NULL;
4936 envlist = PyMem_NEW(char *, i + 1);
4937 if (envlist == NULL) {
4938 PyErr_NoMemory();
4939 return NULL;
4940 }
4941 envc = 0;
4942 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004943 if (!keys)
4944 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004945 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004946 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 goto error;
4948 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4949 PyErr_Format(PyExc_TypeError,
4950 "env.keys() or env.values() is not a list");
4951 goto error;
4952 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 for (pos = 0; pos < i; pos++) {
4955 key = PyList_GetItem(keys, pos);
4956 val = PyList_GetItem(vals, pos);
4957 if (!key || !val)
4958 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004959
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 if (PyUnicode_FSConverter(key, &key2) == 0)
4961 goto error;
4962 if (PyUnicode_FSConverter(val, &val2) == 0) {
4963 Py_DECREF(key2);
4964 goto error;
4965 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004966
Victor Stinner8c62be82010-05-06 00:08:46 +00004967 k = PyBytes_AsString(key2);
4968 v = PyBytes_AsString(val2);
4969 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004970
Victor Stinner8c62be82010-05-06 00:08:46 +00004971 p = PyMem_NEW(char, len);
4972 if (p == NULL) {
4973 PyErr_NoMemory();
4974 Py_DECREF(key2);
4975 Py_DECREF(val2);
4976 goto error;
4977 }
4978 PyOS_snprintf(p, len, "%s=%s", k, v);
4979 envlist[envc++] = p;
4980 Py_DECREF(key2);
4981 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004982 }
4983 Py_DECREF(vals);
4984 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004985
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 envlist[envc] = 0;
4987 *envc_ptr = envc;
4988 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004989
4990error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004991 Py_XDECREF(keys);
4992 Py_XDECREF(vals);
4993 while (--envc >= 0)
4994 PyMem_DEL(envlist[envc]);
4995 PyMem_DEL(envlist);
4996 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004997}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004998
Ross Lagerwall7807c352011-03-17 20:20:30 +02004999static char**
5000parse_arglist(PyObject* argv, Py_ssize_t *argc)
5001{
5002 int i;
5003 char **argvlist = PyMem_NEW(char *, *argc+1);
5004 if (argvlist == NULL) {
5005 PyErr_NoMemory();
5006 return NULL;
5007 }
5008 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005009 PyObject* item = PySequence_ITEM(argv, i);
5010 if (item == NULL)
5011 goto fail;
5012 if (!fsconvert_strdup(item, &argvlist[i])) {
5013 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005014 goto fail;
5015 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005016 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017 }
5018 argvlist[*argc] = NULL;
5019 return argvlist;
5020fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005021 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005022 free_string_array(argvlist, *argc);
5023 return NULL;
5024}
5025#endif
5026
Larry Hastings2f936352014-08-05 14:04:04 +10005027
Ross Lagerwall7807c352011-03-17 20:20:30 +02005028#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005029/*[clinic input]
5030os.execv
5031
5032 path: FSConverter
5033 Path of executable file.
5034 argv: object
5035 Tuple or list of strings.
5036 /
5037
5038Execute an executable path with arguments, replacing current process.
5039[clinic start generated code]*/
5040
Larry Hastings2f936352014-08-05 14:04:04 +10005041static PyObject *
5042os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005043/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005044{
5045 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046 char **argvlist;
5047 Py_ssize_t argc;
5048
5049 /* execv has two arguments: (path, argv), where
5050 argv is a list or tuple of strings. */
5051
Larry Hastings2f936352014-08-05 14:04:04 +10005052 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5054 PyErr_SetString(PyExc_TypeError,
5055 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 return NULL;
5057 }
5058 argc = PySequence_Size(argv);
5059 if (argc < 1) {
5060 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 return NULL;
5062 }
5063
5064 argvlist = parse_arglist(argv, &argc);
5065 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005066 return NULL;
5067 }
5068
Larry Hastings2f936352014-08-05 14:04:04 +10005069 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005070
5071 /* If we get here it's definitely an error */
5072
5073 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005074 return posix_error();
5075}
5076
Larry Hastings2f936352014-08-05 14:04:04 +10005077
5078/*[clinic input]
5079os.execve
5080
5081 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5082 Path of executable file.
5083 argv: object
5084 Tuple or list of strings.
5085 env: object
5086 Dictionary of strings mapping to strings.
5087
5088Execute an executable path with arguments, replacing current process.
5089[clinic start generated code]*/
5090
Larry Hastings2f936352014-08-05 14:04:04 +10005091static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005092os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv,
5093 PyObject *env)
5094/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005095{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005096 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005097 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005099
Victor Stinner8c62be82010-05-06 00:08:46 +00005100 /* execve has three arguments: (path, argv, env), where
5101 argv is a list or tuple of strings and env is a dictionary
5102 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005103
Ross Lagerwall7807c352011-03-17 20:20:30 +02005104 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005106 "execve: argv must be a tuple or list");
5107 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005108 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005109 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 if (!PyMapping_Check(env)) {
5111 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005112 "execve: environment must be a mapping object");
5113 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005115
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005117 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005118 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005119 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005120
Victor Stinner8c62be82010-05-06 00:08:46 +00005121 envlist = parse_envlist(env, &envc);
5122 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005123 goto fail;
5124
Larry Hastings9cf065c2012-06-22 16:30:09 -07005125#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005126 if (path->fd > -1)
5127 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005128 else
5129#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005130 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005131
5132 /* If we get here it's definitely an error */
5133
Larry Hastings2f936352014-08-05 14:04:04 +10005134 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005135
5136 while (--envc >= 0)
5137 PyMem_DEL(envlist[envc]);
5138 PyMem_DEL(envlist);
5139 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005140 if (argvlist)
5141 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005142 return NULL;
5143}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005144#endif /* HAVE_EXECV */
5145
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005146
Guido van Rossuma1065681999-01-25 23:20:23 +00005147#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005148/*[clinic input]
5149os.spawnv
5150
5151 mode: int
5152 Mode of process creation.
5153 path: FSConverter
5154 Path of executable file.
5155 argv: object
5156 Tuple or list of strings.
5157 /
5158
5159Execute the program specified by path in a new process.
5160[clinic start generated code]*/
5161
Larry Hastings2f936352014-08-05 14:04:04 +10005162static PyObject *
5163os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005164/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005165{
5166 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005167 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005168 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005169 Py_ssize_t argc;
5170 Py_intptr_t spawnval;
5171 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005172
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 /* spawnv has three arguments: (mode, path, argv), where
5174 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005175
Larry Hastings2f936352014-08-05 14:04:04 +10005176 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005177 if (PyList_Check(argv)) {
5178 argc = PyList_Size(argv);
5179 getitem = PyList_GetItem;
5180 }
5181 else if (PyTuple_Check(argv)) {
5182 argc = PyTuple_Size(argv);
5183 getitem = PyTuple_GetItem;
5184 }
5185 else {
5186 PyErr_SetString(PyExc_TypeError,
5187 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 return NULL;
5189 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005190
Victor Stinner8c62be82010-05-06 00:08:46 +00005191 argvlist = PyMem_NEW(char *, argc+1);
5192 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005193 return PyErr_NoMemory();
5194 }
5195 for (i = 0; i < argc; i++) {
5196 if (!fsconvert_strdup((*getitem)(argv, i),
5197 &argvlist[i])) {
5198 free_string_array(argvlist, i);
5199 PyErr_SetString(
5200 PyExc_TypeError,
5201 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 return NULL;
5203 }
5204 }
5205 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 if (mode == _OLD_P_OVERLAY)
5208 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005209
Victor Stinner8c62be82010-05-06 00:08:46 +00005210 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005211 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005212 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005213
Victor Stinner8c62be82010-05-06 00:08:46 +00005214 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005215
Victor Stinner8c62be82010-05-06 00:08:46 +00005216 if (spawnval == -1)
5217 return posix_error();
5218 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005219 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005220}
5221
5222
Larry Hastings2f936352014-08-05 14:04:04 +10005223/*[clinic input]
5224os.spawnve
5225
5226 mode: int
5227 Mode of process creation.
5228 path: FSConverter
5229 Path of executable file.
5230 argv: object
5231 Tuple or list of strings.
5232 env: object
5233 Dictionary of strings mapping to strings.
5234 /
5235
5236Execute the program specified by path in a new process.
5237[clinic start generated code]*/
5238
Larry Hastings2f936352014-08-05 14:04:04 +10005239static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005240os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path,
5241 PyObject *argv, PyObject *env)
5242/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005243{
5244 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005245 char **argvlist;
5246 char **envlist;
5247 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005248 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005249 Py_intptr_t spawnval;
5250 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5251 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005252
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 /* spawnve has four arguments: (mode, path, argv, env), where
5254 argv is a list or tuple of strings and env is a dictionary
5255 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005256
Larry Hastings2f936352014-08-05 14:04:04 +10005257 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 if (PyList_Check(argv)) {
5259 argc = PyList_Size(argv);
5260 getitem = PyList_GetItem;
5261 }
5262 else if (PyTuple_Check(argv)) {
5263 argc = PyTuple_Size(argv);
5264 getitem = PyTuple_GetItem;
5265 }
5266 else {
5267 PyErr_SetString(PyExc_TypeError,
5268 "spawnve() arg 2 must be a tuple or list");
5269 goto fail_0;
5270 }
5271 if (!PyMapping_Check(env)) {
5272 PyErr_SetString(PyExc_TypeError,
5273 "spawnve() arg 3 must be a mapping object");
5274 goto fail_0;
5275 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005276
Victor Stinner8c62be82010-05-06 00:08:46 +00005277 argvlist = PyMem_NEW(char *, argc+1);
5278 if (argvlist == NULL) {
5279 PyErr_NoMemory();
5280 goto fail_0;
5281 }
5282 for (i = 0; i < argc; i++) {
5283 if (!fsconvert_strdup((*getitem)(argv, i),
5284 &argvlist[i]))
5285 {
5286 lastarg = i;
5287 goto fail_1;
5288 }
5289 }
5290 lastarg = argc;
5291 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005292
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 envlist = parse_envlist(env, &envc);
5294 if (envlist == NULL)
5295 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 if (mode == _OLD_P_OVERLAY)
5298 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005299
Victor Stinner8c62be82010-05-06 00:08:46 +00005300 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005301 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 if (spawnval == -1)
5305 (void) posix_error();
5306 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005307 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005308
Victor Stinner8c62be82010-05-06 00:08:46 +00005309 while (--envc >= 0)
5310 PyMem_DEL(envlist[envc]);
5311 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005312 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005313 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005314 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005316}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005317
Guido van Rossuma1065681999-01-25 23:20:23 +00005318#endif /* HAVE_SPAWNV */
5319
5320
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005321#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005322/*[clinic input]
5323os.fork1
5324
5325Fork a child process with a single multiplexed (i.e., not bound) thread.
5326
5327Return 0 to child process and PID of child to parent process.
5328[clinic start generated code]*/
5329
Larry Hastings2f936352014-08-05 14:04:04 +10005330static PyObject *
5331os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005332/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005333{
Victor Stinner8c62be82010-05-06 00:08:46 +00005334 pid_t pid;
5335 int result = 0;
5336 _PyImport_AcquireLock();
5337 pid = fork1();
5338 if (pid == 0) {
5339 /* child: this clobbers and resets the import lock. */
5340 PyOS_AfterFork();
5341 } else {
5342 /* parent: release the import lock. */
5343 result = _PyImport_ReleaseLock();
5344 }
5345 if (pid == -1)
5346 return posix_error();
5347 if (result < 0) {
5348 /* Don't clobber the OSError if the fork failed. */
5349 PyErr_SetString(PyExc_RuntimeError,
5350 "not holding the import lock");
5351 return NULL;
5352 }
5353 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005354}
Larry Hastings2f936352014-08-05 14:04:04 +10005355#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005356
5357
Guido van Rossumad0ee831995-03-01 10:34:45 +00005358#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005359/*[clinic input]
5360os.fork
5361
5362Fork a child process.
5363
5364Return 0 to child process and PID of child to parent process.
5365[clinic start generated code]*/
5366
Larry Hastings2f936352014-08-05 14:04:04 +10005367static PyObject *
5368os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005369/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005370{
Victor Stinner8c62be82010-05-06 00:08:46 +00005371 pid_t pid;
5372 int result = 0;
5373 _PyImport_AcquireLock();
5374 pid = fork();
5375 if (pid == 0) {
5376 /* child: this clobbers and resets the import lock. */
5377 PyOS_AfterFork();
5378 } else {
5379 /* parent: release the import lock. */
5380 result = _PyImport_ReleaseLock();
5381 }
5382 if (pid == -1)
5383 return posix_error();
5384 if (result < 0) {
5385 /* Don't clobber the OSError if the fork failed. */
5386 PyErr_SetString(PyExc_RuntimeError,
5387 "not holding the import lock");
5388 return NULL;
5389 }
5390 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005391}
Larry Hastings2f936352014-08-05 14:04:04 +10005392#endif /* HAVE_FORK */
5393
Guido van Rossum85e3b011991-06-03 12:42:10 +00005394
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005395#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005396#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005397/*[clinic input]
5398os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005399
Larry Hastings2f936352014-08-05 14:04:04 +10005400 policy: int
5401
5402Get the maximum scheduling priority for policy.
5403[clinic start generated code]*/
5404
Larry Hastings2f936352014-08-05 14:04:04 +10005405static PyObject *
5406os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005407/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005408{
5409 int max;
5410
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005411 max = sched_get_priority_max(policy);
5412 if (max < 0)
5413 return posix_error();
5414 return PyLong_FromLong(max);
5415}
5416
Larry Hastings2f936352014-08-05 14:04:04 +10005417
5418/*[clinic input]
5419os.sched_get_priority_min
5420
5421 policy: int
5422
5423Get the minimum scheduling priority for policy.
5424[clinic start generated code]*/
5425
Larry Hastings2f936352014-08-05 14:04:04 +10005426static PyObject *
5427os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005428/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005429{
5430 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005431 if (min < 0)
5432 return posix_error();
5433 return PyLong_FromLong(min);
5434}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005435#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5436
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005437
Larry Hastings2f936352014-08-05 14:04:04 +10005438#ifdef HAVE_SCHED_SETSCHEDULER
5439/*[clinic input]
5440os.sched_getscheduler
5441 pid: pid_t
5442 /
5443
5444Get the scheduling policy for the process identifiedy by pid.
5445
5446Passing 0 for pid returns the scheduling policy for the calling process.
5447[clinic start generated code]*/
5448
Larry Hastings2f936352014-08-05 14:04:04 +10005449static PyObject *
5450os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005451/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005452{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005453 int policy;
5454
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005455 policy = sched_getscheduler(pid);
5456 if (policy < 0)
5457 return posix_error();
5458 return PyLong_FromLong(policy);
5459}
Larry Hastings2f936352014-08-05 14:04:04 +10005460#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005461
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005462
5463#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005464/*[clinic input]
5465class os.sched_param "PyObject *" "&SchedParamType"
5466
5467@classmethod
5468os.sched_param.__new__
5469
5470 sched_priority: object
5471 A scheduling parameter.
5472
5473Current has only one field: sched_priority");
5474[clinic start generated code]*/
5475
Larry Hastings2f936352014-08-05 14:04:04 +10005476static PyObject *
5477os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005478/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005479{
5480 PyObject *res;
5481
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005482 res = PyStructSequence_New(type);
5483 if (!res)
5484 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005485 Py_INCREF(sched_priority);
5486 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005487 return res;
5488}
5489
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005490
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005491PyDoc_VAR(os_sched_param__doc__);
5492
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005493static PyStructSequence_Field sched_param_fields[] = {
5494 {"sched_priority", "the scheduling priority"},
5495 {0}
5496};
5497
5498static PyStructSequence_Desc sched_param_desc = {
5499 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005500 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005501 sched_param_fields,
5502 1
5503};
5504
5505static int
5506convert_sched_param(PyObject *param, struct sched_param *res)
5507{
5508 long priority;
5509
5510 if (Py_TYPE(param) != &SchedParamType) {
5511 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5512 return 0;
5513 }
5514 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5515 if (priority == -1 && PyErr_Occurred())
5516 return 0;
5517 if (priority > INT_MAX || priority < INT_MIN) {
5518 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5519 return 0;
5520 }
5521 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5522 return 1;
5523}
Larry Hastings2f936352014-08-05 14:04:04 +10005524#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005525
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005526
5527#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005528/*[clinic input]
5529os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005530
Larry Hastings2f936352014-08-05 14:04:04 +10005531 pid: pid_t
5532 policy: int
5533 param: sched_param
5534 /
5535
5536Set the scheduling policy for the process identified by pid.
5537
5538If pid is 0, the calling process is changed.
5539param is an instance of sched_param.
5540[clinic start generated code]*/
5541
Larry Hastings2f936352014-08-05 14:04:04 +10005542static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005543os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy,
5544 struct sched_param *param)
5545/*[clinic end generated code: output=37053e5c528c35c9 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005546{
Jesus Cea9c822272011-09-10 01:40:52 +02005547 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005548 ** sched_setscheduler() returns 0 in Linux, but the previous
5549 ** scheduling policy under Solaris/Illumos, and others.
5550 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005551 */
Larry Hastings2f936352014-08-05 14:04:04 +10005552 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005553 return posix_error();
5554 Py_RETURN_NONE;
5555}
Larry Hastings2f936352014-08-05 14:04:04 +10005556#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005557
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005558
5559#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005560/*[clinic input]
5561os.sched_getparam
5562 pid: pid_t
5563 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005564
Larry Hastings2f936352014-08-05 14:04:04 +10005565Returns scheduling parameters for the process identified by pid.
5566
5567If pid is 0, returns parameters for the calling process.
5568Return value is an instance of sched_param.
5569[clinic start generated code]*/
5570
Larry Hastings2f936352014-08-05 14:04:04 +10005571static PyObject *
5572os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005573/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005574{
5575 struct sched_param param;
5576 PyObject *result;
5577 PyObject *priority;
5578
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005579 if (sched_getparam(pid, &param))
5580 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005581 result = PyStructSequence_New(&SchedParamType);
5582 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005583 return NULL;
5584 priority = PyLong_FromLong(param.sched_priority);
5585 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005586 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005587 return NULL;
5588 }
Larry Hastings2f936352014-08-05 14:04:04 +10005589 PyStructSequence_SET_ITEM(result, 0, priority);
5590 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005591}
5592
Larry Hastings2f936352014-08-05 14:04:04 +10005593
5594/*[clinic input]
5595os.sched_setparam
5596 pid: pid_t
5597 param: sched_param
5598 /
5599
5600Set scheduling parameters for the process identified by pid.
5601
5602If pid is 0, sets parameters for the calling process.
5603param should be an instance of sched_param.
5604[clinic start generated code]*/
5605
Larry Hastings2f936352014-08-05 14:04:04 +10005606static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005607os_sched_setparam_impl(PyModuleDef *module, pid_t pid,
5608 struct sched_param *param)
5609/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005610{
5611 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005612 return posix_error();
5613 Py_RETURN_NONE;
5614}
Larry Hastings2f936352014-08-05 14:04:04 +10005615#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005616
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005617
5618#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005619/*[clinic input]
5620os.sched_rr_get_interval -> double
5621 pid: pid_t
5622 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005623
Larry Hastings2f936352014-08-05 14:04:04 +10005624Return the round-robin quantum for the process identified by pid, in seconds.
5625
5626Value returned is a float.
5627[clinic start generated code]*/
5628
Larry Hastings2f936352014-08-05 14:04:04 +10005629static double
5630os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005631/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005632{
5633 struct timespec interval;
5634 if (sched_rr_get_interval(pid, &interval)) {
5635 posix_error();
5636 return -1.0;
5637 }
5638 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5639}
5640#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005641
Larry Hastings2f936352014-08-05 14:04:04 +10005642
5643/*[clinic input]
5644os.sched_yield
5645
5646Voluntarily relinquish the CPU.
5647[clinic start generated code]*/
5648
Larry Hastings2f936352014-08-05 14:04:04 +10005649static PyObject *
5650os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005651/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005652{
5653 if (sched_yield())
5654 return posix_error();
5655 Py_RETURN_NONE;
5656}
5657
Benjamin Peterson2740af82011-08-02 17:41:34 -05005658#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005659/* The minimum number of CPUs allocated in a cpu_set_t */
5660static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005661
Larry Hastings2f936352014-08-05 14:04:04 +10005662/*[clinic input]
5663os.sched_setaffinity
5664 pid: pid_t
5665 mask : object
5666 /
5667
5668Set the CPU affinity of the process identified by pid to mask.
5669
5670mask should be an iterable of integers identifying CPUs.
5671[clinic start generated code]*/
5672
Larry Hastings2f936352014-08-05 14:04:04 +10005673static PyObject *
5674os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005675/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005676{
Antoine Pitrou84869872012-08-04 16:16:35 +02005677 int ncpus;
5678 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005679 cpu_set_t *cpu_set = NULL;
5680 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005681
Larry Hastings2f936352014-08-05 14:04:04 +10005682 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005683 if (iterator == NULL)
5684 return NULL;
5685
5686 ncpus = NCPUS_START;
5687 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005688 cpu_set = CPU_ALLOC(ncpus);
5689 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005690 PyErr_NoMemory();
5691 goto error;
5692 }
Larry Hastings2f936352014-08-05 14:04:04 +10005693 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005694
5695 while ((item = PyIter_Next(iterator))) {
5696 long cpu;
5697 if (!PyLong_Check(item)) {
5698 PyErr_Format(PyExc_TypeError,
5699 "expected an iterator of ints, "
5700 "but iterator yielded %R",
5701 Py_TYPE(item));
5702 Py_DECREF(item);
5703 goto error;
5704 }
5705 cpu = PyLong_AsLong(item);
5706 Py_DECREF(item);
5707 if (cpu < 0) {
5708 if (!PyErr_Occurred())
5709 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5710 goto error;
5711 }
5712 if (cpu > INT_MAX - 1) {
5713 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5714 goto error;
5715 }
5716 if (cpu >= ncpus) {
5717 /* Grow CPU mask to fit the CPU number */
5718 int newncpus = ncpus;
5719 cpu_set_t *newmask;
5720 size_t newsetsize;
5721 while (newncpus <= cpu) {
5722 if (newncpus > INT_MAX / 2)
5723 newncpus = cpu + 1;
5724 else
5725 newncpus = newncpus * 2;
5726 }
5727 newmask = CPU_ALLOC(newncpus);
5728 if (newmask == NULL) {
5729 PyErr_NoMemory();
5730 goto error;
5731 }
5732 newsetsize = CPU_ALLOC_SIZE(newncpus);
5733 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005734 memcpy(newmask, cpu_set, setsize);
5735 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005736 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005737 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005738 ncpus = newncpus;
5739 }
Larry Hastings2f936352014-08-05 14:04:04 +10005740 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005741 }
5742 Py_CLEAR(iterator);
5743
Larry Hastings2f936352014-08-05 14:04:04 +10005744 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005745 posix_error();
5746 goto error;
5747 }
Larry Hastings2f936352014-08-05 14:04:04 +10005748 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005749 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005750
5751error:
Larry Hastings2f936352014-08-05 14:04:04 +10005752 if (cpu_set)
5753 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005754 Py_XDECREF(iterator);
5755 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005756}
5757
Larry Hastings2f936352014-08-05 14:04:04 +10005758
5759/*[clinic input]
5760os.sched_getaffinity
5761 pid: pid_t
5762 /
5763
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005764Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005765
5766The affinity is returned as a set of CPU identifiers.
5767[clinic start generated code]*/
5768
Larry Hastings2f936352014-08-05 14:04:04 +10005769static PyObject *
5770os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Charles-François Natali80d62e62015-08-13 20:37:08 +01005771/*[clinic end generated code: output=b431a8f310e369e7 input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005772{
Antoine Pitrou84869872012-08-04 16:16:35 +02005773 int cpu, ncpus, count;
5774 size_t setsize;
5775 cpu_set_t *mask = NULL;
5776 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005777
Antoine Pitrou84869872012-08-04 16:16:35 +02005778 ncpus = NCPUS_START;
5779 while (1) {
5780 setsize = CPU_ALLOC_SIZE(ncpus);
5781 mask = CPU_ALLOC(ncpus);
5782 if (mask == NULL)
5783 return PyErr_NoMemory();
5784 if (sched_getaffinity(pid, setsize, mask) == 0)
5785 break;
5786 CPU_FREE(mask);
5787 if (errno != EINVAL)
5788 return posix_error();
5789 if (ncpus > INT_MAX / 2) {
5790 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5791 "a large enough CPU set");
5792 return NULL;
5793 }
5794 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005795 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005796
5797 res = PySet_New(NULL);
5798 if (res == NULL)
5799 goto error;
5800 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5801 if (CPU_ISSET_S(cpu, setsize, mask)) {
5802 PyObject *cpu_num = PyLong_FromLong(cpu);
5803 --count;
5804 if (cpu_num == NULL)
5805 goto error;
5806 if (PySet_Add(res, cpu_num)) {
5807 Py_DECREF(cpu_num);
5808 goto error;
5809 }
5810 Py_DECREF(cpu_num);
5811 }
5812 }
5813 CPU_FREE(mask);
5814 return res;
5815
5816error:
5817 if (mask)
5818 CPU_FREE(mask);
5819 Py_XDECREF(res);
5820 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005821}
5822
Benjamin Peterson2740af82011-08-02 17:41:34 -05005823#endif /* HAVE_SCHED_SETAFFINITY */
5824
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005825#endif /* HAVE_SCHED_H */
5826
Larry Hastings2f936352014-08-05 14:04:04 +10005827
Neal Norwitzb59798b2003-03-21 01:43:31 +00005828/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005829/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5830#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005831#define DEV_PTY_FILE "/dev/ptc"
5832#define HAVE_DEV_PTMX
5833#else
5834#define DEV_PTY_FILE "/dev/ptmx"
5835#endif
5836
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005837#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005838#ifdef HAVE_PTY_H
5839#include <pty.h>
5840#else
5841#ifdef HAVE_LIBUTIL_H
5842#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005843#else
5844#ifdef HAVE_UTIL_H
5845#include <util.h>
5846#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005847#endif /* HAVE_LIBUTIL_H */
5848#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005849#ifdef HAVE_STROPTS_H
5850#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005851#endif
5852#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005853
Larry Hastings2f936352014-08-05 14:04:04 +10005854
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005855#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005856/*[clinic input]
5857os.openpty
5858
5859Open a pseudo-terminal.
5860
5861Return a tuple of (master_fd, slave_fd) containing open file descriptors
5862for both the master and slave ends.
5863[clinic start generated code]*/
5864
Larry Hastings2f936352014-08-05 14:04:04 +10005865static PyObject *
5866os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005867/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005868{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005869 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005870#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005871 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005872#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005873#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005875#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005877#endif
5878#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005879
Thomas Wouters70c21a12000-07-14 14:28:33 +00005880#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005882 goto posix_error;
5883
5884 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5885 goto error;
5886 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5887 goto error;
5888
Neal Norwitzb59798b2003-03-21 01:43:31 +00005889#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5891 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005892 goto posix_error;
5893 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5894 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005895
Victor Stinnerdaf45552013-08-28 00:53:59 +02005896 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005898 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005899
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005900#else
Victor Stinner000de532013-11-25 23:19:58 +01005901 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005903 goto posix_error;
5904
Victor Stinner8c62be82010-05-06 00:08:46 +00005905 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005906
Victor Stinner8c62be82010-05-06 00:08:46 +00005907 /* change permission of slave */
5908 if (grantpt(master_fd) < 0) {
5909 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005910 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005911 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005912
Victor Stinner8c62be82010-05-06 00:08:46 +00005913 /* unlock slave */
5914 if (unlockpt(master_fd) < 0) {
5915 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005916 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005917 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005918
Victor Stinner8c62be82010-05-06 00:08:46 +00005919 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005920
Victor Stinner8c62be82010-05-06 00:08:46 +00005921 slave_name = ptsname(master_fd); /* get name of slave */
5922 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005923 goto posix_error;
5924
5925 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005926 if (slave_fd == -1)
5927 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005928
5929 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5930 goto posix_error;
5931
Neal Norwitzb59798b2003-03-21 01:43:31 +00005932#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005933 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5934 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005935#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005937#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005938#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005939#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005940
Victor Stinner8c62be82010-05-06 00:08:46 +00005941 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005942
Victor Stinnerdaf45552013-08-28 00:53:59 +02005943posix_error:
5944 posix_error();
5945error:
5946 if (master_fd != -1)
5947 close(master_fd);
5948 if (slave_fd != -1)
5949 close(slave_fd);
5950 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005951}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005952#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005953
Larry Hastings2f936352014-08-05 14:04:04 +10005954
Fred Drake8cef4cf2000-06-28 16:40:38 +00005955#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005956/*[clinic input]
5957os.forkpty
5958
5959Fork a new process with a new pseudo-terminal as controlling tty.
5960
5961Returns a tuple of (pid, master_fd).
5962Like fork(), return pid of 0 to the child process,
5963and pid of child to the parent process.
5964To both, return fd of newly opened pseudo-terminal.
5965[clinic start generated code]*/
5966
Larry Hastings2f936352014-08-05 14:04:04 +10005967static PyObject *
5968os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005969/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005970{
Victor Stinner8c62be82010-05-06 00:08:46 +00005971 int master_fd = -1, result = 0;
5972 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005973
Victor Stinner8c62be82010-05-06 00:08:46 +00005974 _PyImport_AcquireLock();
5975 pid = forkpty(&master_fd, NULL, NULL, NULL);
5976 if (pid == 0) {
5977 /* child: this clobbers and resets the import lock. */
5978 PyOS_AfterFork();
5979 } else {
5980 /* parent: release the import lock. */
5981 result = _PyImport_ReleaseLock();
5982 }
5983 if (pid == -1)
5984 return posix_error();
5985 if (result < 0) {
5986 /* Don't clobber the OSError if the fork failed. */
5987 PyErr_SetString(PyExc_RuntimeError,
5988 "not holding the import lock");
5989 return NULL;
5990 }
5991 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005992}
Larry Hastings2f936352014-08-05 14:04:04 +10005993#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005994
Ross Lagerwall7807c352011-03-17 20:20:30 +02005995
Guido van Rossumad0ee831995-03-01 10:34:45 +00005996#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005997/*[clinic input]
5998os.getegid
5999
6000Return the current process's effective group id.
6001[clinic start generated code]*/
6002
Larry Hastings2f936352014-08-05 14:04:04 +10006003static PyObject *
6004os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006005/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006006{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006007 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006008}
Larry Hastings2f936352014-08-05 14:04:04 +10006009#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006010
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006011
Guido van Rossumad0ee831995-03-01 10:34:45 +00006012#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006013/*[clinic input]
6014os.geteuid
6015
6016Return the current process's effective user id.
6017[clinic start generated code]*/
6018
Larry Hastings2f936352014-08-05 14:04:04 +10006019static PyObject *
6020os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006021/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006022{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006023 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006024}
Larry Hastings2f936352014-08-05 14:04:04 +10006025#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006026
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006027
Guido van Rossumad0ee831995-03-01 10:34:45 +00006028#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006029/*[clinic input]
6030os.getgid
6031
6032Return the current process's group id.
6033[clinic start generated code]*/
6034
Larry Hastings2f936352014-08-05 14:04:04 +10006035static PyObject *
6036os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006037/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006038{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006039 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006040}
Larry Hastings2f936352014-08-05 14:04:04 +10006041#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006042
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006043
Larry Hastings2f936352014-08-05 14:04:04 +10006044/*[clinic input]
6045os.getpid
6046
6047Return the current process id.
6048[clinic start generated code]*/
6049
Larry Hastings2f936352014-08-05 14:04:04 +10006050static PyObject *
6051os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006052/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006053{
Victor Stinner8c62be82010-05-06 00:08:46 +00006054 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006055}
6056
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006057#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006058
6059/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006060PyDoc_STRVAR(posix_getgrouplist__doc__,
6061"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6062Returns a list of groups to which a user belongs.\n\n\
6063 user: username to lookup\n\
6064 group: base group id of the user");
6065
6066static PyObject *
6067posix_getgrouplist(PyObject *self, PyObject *args)
6068{
6069#ifdef NGROUPS_MAX
6070#define MAX_GROUPS NGROUPS_MAX
6071#else
6072 /* defined to be 16 on Solaris7, so this should be a small number */
6073#define MAX_GROUPS 64
6074#endif
6075
6076 const char *user;
6077 int i, ngroups;
6078 PyObject *list;
6079#ifdef __APPLE__
6080 int *groups, basegid;
6081#else
6082 gid_t *groups, basegid;
6083#endif
6084 ngroups = MAX_GROUPS;
6085
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006086#ifdef __APPLE__
6087 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006088 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006089#else
6090 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6091 _Py_Gid_Converter, &basegid))
6092 return NULL;
6093#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006094
6095#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006096 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006097#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006098 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006099#endif
6100 if (groups == NULL)
6101 return PyErr_NoMemory();
6102
6103 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6104 PyMem_Del(groups);
6105 return posix_error();
6106 }
6107
6108 list = PyList_New(ngroups);
6109 if (list == NULL) {
6110 PyMem_Del(groups);
6111 return NULL;
6112 }
6113
6114 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006115#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006116 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006117#else
6118 PyObject *o = _PyLong_FromGid(groups[i]);
6119#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006120 if (o == NULL) {
6121 Py_DECREF(list);
6122 PyMem_Del(groups);
6123 return NULL;
6124 }
6125 PyList_SET_ITEM(list, i, o);
6126 }
6127
6128 PyMem_Del(groups);
6129
6130 return list;
6131}
Larry Hastings2f936352014-08-05 14:04:04 +10006132#endif /* HAVE_GETGROUPLIST */
6133
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006134
Fred Drakec9680921999-12-13 16:37:25 +00006135#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006136/*[clinic input]
6137os.getgroups
6138
6139Return list of supplemental group IDs for the process.
6140[clinic start generated code]*/
6141
Larry Hastings2f936352014-08-05 14:04:04 +10006142static PyObject *
6143os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006144/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006145{
6146 PyObject *result = NULL;
6147
Fred Drakec9680921999-12-13 16:37:25 +00006148#ifdef NGROUPS_MAX
6149#define MAX_GROUPS NGROUPS_MAX
6150#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006151 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006152#define MAX_GROUPS 64
6153#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006154 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006155
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006156 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006157 * This is a helper variable to store the intermediate result when
6158 * that happens.
6159 *
6160 * To keep the code readable the OSX behaviour is unconditional,
6161 * according to the POSIX spec this should be safe on all unix-y
6162 * systems.
6163 */
6164 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006165 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006166
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006167#ifdef __APPLE__
6168 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6169 * there are more groups than can fit in grouplist. Therefore, on OS X
6170 * always first call getgroups with length 0 to get the actual number
6171 * of groups.
6172 */
6173 n = getgroups(0, NULL);
6174 if (n < 0) {
6175 return posix_error();
6176 } else if (n <= MAX_GROUPS) {
6177 /* groups will fit in existing array */
6178 alt_grouplist = grouplist;
6179 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006180 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006181 if (alt_grouplist == NULL) {
6182 errno = EINVAL;
6183 return posix_error();
6184 }
6185 }
6186
6187 n = getgroups(n, alt_grouplist);
6188 if (n == -1) {
6189 if (alt_grouplist != grouplist) {
6190 PyMem_Free(alt_grouplist);
6191 }
6192 return posix_error();
6193 }
6194#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006195 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006196 if (n < 0) {
6197 if (errno == EINVAL) {
6198 n = getgroups(0, NULL);
6199 if (n == -1) {
6200 return posix_error();
6201 }
6202 if (n == 0) {
6203 /* Avoid malloc(0) */
6204 alt_grouplist = grouplist;
6205 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006206 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006207 if (alt_grouplist == NULL) {
6208 errno = EINVAL;
6209 return posix_error();
6210 }
6211 n = getgroups(n, alt_grouplist);
6212 if (n == -1) {
6213 PyMem_Free(alt_grouplist);
6214 return posix_error();
6215 }
6216 }
6217 } else {
6218 return posix_error();
6219 }
6220 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006221#endif
6222
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006223 result = PyList_New(n);
6224 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006225 int i;
6226 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006227 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006229 Py_DECREF(result);
6230 result = NULL;
6231 break;
Fred Drakec9680921999-12-13 16:37:25 +00006232 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006233 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006234 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006235 }
6236
6237 if (alt_grouplist != grouplist) {
6238 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006239 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006240
Fred Drakec9680921999-12-13 16:37:25 +00006241 return result;
6242}
Larry Hastings2f936352014-08-05 14:04:04 +10006243#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006244
Antoine Pitroub7572f02009-12-02 20:46:48 +00006245#ifdef HAVE_INITGROUPS
6246PyDoc_STRVAR(posix_initgroups__doc__,
6247"initgroups(username, gid) -> None\n\n\
6248Call the system initgroups() to initialize the group access list with all of\n\
6249the groups of which the specified username is a member, plus the specified\n\
6250group id.");
6251
Larry Hastings2f936352014-08-05 14:04:04 +10006252/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006253static PyObject *
6254posix_initgroups(PyObject *self, PyObject *args)
6255{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006256 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006257 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006258 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006259#ifdef __APPLE__
6260 int gid;
6261#else
6262 gid_t gid;
6263#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006264
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006265#ifdef __APPLE__
6266 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6267 PyUnicode_FSConverter, &oname,
6268 &gid))
6269#else
6270 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6271 PyUnicode_FSConverter, &oname,
6272 _Py_Gid_Converter, &gid))
6273#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006274 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006275 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006276
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006277 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006278 Py_DECREF(oname);
6279 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006280 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006281
Victor Stinner8c62be82010-05-06 00:08:46 +00006282 Py_INCREF(Py_None);
6283 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006284}
Larry Hastings2f936352014-08-05 14:04:04 +10006285#endif /* HAVE_INITGROUPS */
6286
Antoine Pitroub7572f02009-12-02 20:46:48 +00006287
Martin v. Löwis606edc12002-06-13 21:09:11 +00006288#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006289/*[clinic input]
6290os.getpgid
6291
6292 pid: pid_t
6293
6294Call the system call getpgid(), and return the result.
6295[clinic start generated code]*/
6296
Larry Hastings2f936352014-08-05 14:04:04 +10006297static PyObject *
6298os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006299/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006300{
6301 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 if (pgid < 0)
6303 return posix_error();
6304 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006305}
6306#endif /* HAVE_GETPGID */
6307
6308
Guido van Rossumb6775db1994-08-01 11:34:53 +00006309#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006310/*[clinic input]
6311os.getpgrp
6312
6313Return the current process group id.
6314[clinic start generated code]*/
6315
Larry Hastings2f936352014-08-05 14:04:04 +10006316static PyObject *
6317os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006318/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006319{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006320#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006321 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006322#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006323 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006324#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006325}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006326#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006327
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006328
Guido van Rossumb6775db1994-08-01 11:34:53 +00006329#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006330/*[clinic input]
6331os.setpgrp
6332
6333Make the current process the leader of its process group.
6334[clinic start generated code]*/
6335
Larry Hastings2f936352014-08-05 14:04:04 +10006336static PyObject *
6337os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006338/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006339{
Guido van Rossum64933891994-10-20 21:56:42 +00006340#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006341 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006342#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006343 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006344#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006345 return posix_error();
6346 Py_INCREF(Py_None);
6347 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006348}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006349#endif /* HAVE_SETPGRP */
6350
Guido van Rossumad0ee831995-03-01 10:34:45 +00006351#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006352
6353#ifdef MS_WINDOWS
6354#include <tlhelp32.h>
6355
6356static PyObject*
6357win32_getppid()
6358{
6359 HANDLE snapshot;
6360 pid_t mypid;
6361 PyObject* result = NULL;
6362 BOOL have_record;
6363 PROCESSENTRY32 pe;
6364
6365 mypid = getpid(); /* This function never fails */
6366
6367 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6368 if (snapshot == INVALID_HANDLE_VALUE)
6369 return PyErr_SetFromWindowsErr(GetLastError());
6370
6371 pe.dwSize = sizeof(pe);
6372 have_record = Process32First(snapshot, &pe);
6373 while (have_record) {
6374 if (mypid == (pid_t)pe.th32ProcessID) {
6375 /* We could cache the ulong value in a static variable. */
6376 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6377 break;
6378 }
6379
6380 have_record = Process32Next(snapshot, &pe);
6381 }
6382
6383 /* If our loop exits and our pid was not found (result will be NULL)
6384 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6385 * error anyway, so let's raise it. */
6386 if (!result)
6387 result = PyErr_SetFromWindowsErr(GetLastError());
6388
6389 CloseHandle(snapshot);
6390
6391 return result;
6392}
6393#endif /*MS_WINDOWS*/
6394
Larry Hastings2f936352014-08-05 14:04:04 +10006395
6396/*[clinic input]
6397os.getppid
6398
6399Return the parent's process id.
6400
6401If the parent process has already exited, Windows machines will still
6402return its id; others systems will return the id of the 'init' process (1).
6403[clinic start generated code]*/
6404
Larry Hastings2f936352014-08-05 14:04:04 +10006405static PyObject *
6406os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006407/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006408{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006409#ifdef MS_WINDOWS
6410 return win32_getppid();
6411#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006412 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006413#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006414}
6415#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006416
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006417
Fred Drake12c6e2d1999-12-14 21:25:03 +00006418#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006419/*[clinic input]
6420os.getlogin
6421
6422Return the actual login name.
6423[clinic start generated code]*/
6424
Larry Hastings2f936352014-08-05 14:04:04 +10006425static PyObject *
6426os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006427/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006428{
Victor Stinner8c62be82010-05-06 00:08:46 +00006429 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006430#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006431 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006432 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006433
6434 if (GetUserNameW(user_name, &num_chars)) {
6435 /* num_chars is the number of unicode chars plus null terminator */
6436 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006437 }
6438 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006439 result = PyErr_SetFromWindowsErr(GetLastError());
6440#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006441 char *name;
6442 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006443
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 errno = 0;
6445 name = getlogin();
6446 if (name == NULL) {
6447 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006448 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006449 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006450 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006451 }
6452 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006453 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006454 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006455#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006456 return result;
6457}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006458#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006459
Larry Hastings2f936352014-08-05 14:04:04 +10006460
Guido van Rossumad0ee831995-03-01 10:34:45 +00006461#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006462/*[clinic input]
6463os.getuid
6464
6465Return the current process's user id.
6466[clinic start generated code]*/
6467
Larry Hastings2f936352014-08-05 14:04:04 +10006468static PyObject *
6469os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006470/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006471{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006472 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006473}
Larry Hastings2f936352014-08-05 14:04:04 +10006474#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006475
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006476
Brian Curtineb24d742010-04-12 17:16:38 +00006477#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006478#define HAVE_KILL
6479#endif /* MS_WINDOWS */
6480
6481#ifdef HAVE_KILL
6482/*[clinic input]
6483os.kill
6484
6485 pid: pid_t
6486 signal: Py_ssize_t
6487 /
6488
6489Kill a process with a signal.
6490[clinic start generated code]*/
6491
Larry Hastings2f936352014-08-05 14:04:04 +10006492static PyObject *
6493os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006494/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006495#ifndef MS_WINDOWS
6496{
6497 if (kill(pid, (int)signal) == -1)
6498 return posix_error();
6499 Py_RETURN_NONE;
6500}
6501#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006502{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006503 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006504 DWORD sig = (DWORD)signal;
6505 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006507
Victor Stinner8c62be82010-05-06 00:08:46 +00006508 /* Console processes which share a common console can be sent CTRL+C or
6509 CTRL+BREAK events, provided they handle said events. */
6510 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006511 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 err = GetLastError();
6513 PyErr_SetFromWindowsErr(err);
6514 }
6515 else
6516 Py_RETURN_NONE;
6517 }
Brian Curtineb24d742010-04-12 17:16:38 +00006518
Victor Stinner8c62be82010-05-06 00:08:46 +00006519 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6520 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006521 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 if (handle == NULL) {
6523 err = GetLastError();
6524 return PyErr_SetFromWindowsErr(err);
6525 }
Brian Curtineb24d742010-04-12 17:16:38 +00006526
Victor Stinner8c62be82010-05-06 00:08:46 +00006527 if (TerminateProcess(handle, sig) == 0) {
6528 err = GetLastError();
6529 result = PyErr_SetFromWindowsErr(err);
6530 } else {
6531 Py_INCREF(Py_None);
6532 result = Py_None;
6533 }
Brian Curtineb24d742010-04-12 17:16:38 +00006534
Victor Stinner8c62be82010-05-06 00:08:46 +00006535 CloseHandle(handle);
6536 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006537}
Larry Hastings2f936352014-08-05 14:04:04 +10006538#endif /* !MS_WINDOWS */
6539#endif /* HAVE_KILL */
6540
6541
6542#ifdef HAVE_KILLPG
6543/*[clinic input]
6544os.killpg
6545
6546 pgid: pid_t
6547 signal: int
6548 /
6549
6550Kill a process group with a signal.
6551[clinic start generated code]*/
6552
Larry Hastings2f936352014-08-05 14:04:04 +10006553static PyObject *
6554os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006555/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006556{
6557 /* XXX some man pages make the `pgid` parameter an int, others
6558 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6559 take the same type. Moreover, pid_t is always at least as wide as
6560 int (else compilation of this module fails), which is safe. */
6561 if (killpg(pgid, signal) == -1)
6562 return posix_error();
6563 Py_RETURN_NONE;
6564}
6565#endif /* HAVE_KILLPG */
6566
Brian Curtineb24d742010-04-12 17:16:38 +00006567
Guido van Rossumc0125471996-06-28 18:55:32 +00006568#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006569#ifdef HAVE_SYS_LOCK_H
6570#include <sys/lock.h>
6571#endif
6572
Larry Hastings2f936352014-08-05 14:04:04 +10006573/*[clinic input]
6574os.plock
6575 op: int
6576 /
6577
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006578Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006579[clinic start generated code]*/
6580
Larry Hastings2f936352014-08-05 14:04:04 +10006581static PyObject *
6582os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006583/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006584{
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 if (plock(op) == -1)
6586 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006587 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006588}
Larry Hastings2f936352014-08-05 14:04:04 +10006589#endif /* HAVE_PLOCK */
6590
Guido van Rossumc0125471996-06-28 18:55:32 +00006591
Guido van Rossumb6775db1994-08-01 11:34:53 +00006592#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006593/*[clinic input]
6594os.setuid
6595
6596 uid: uid_t
6597 /
6598
6599Set the current process's user id.
6600[clinic start generated code]*/
6601
Larry Hastings2f936352014-08-05 14:04:04 +10006602static PyObject *
6603os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006604/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006605{
Victor Stinner8c62be82010-05-06 00:08:46 +00006606 if (setuid(uid) < 0)
6607 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006608 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006609}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006610#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006611
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006612
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006613#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006614/*[clinic input]
6615os.seteuid
6616
6617 euid: uid_t
6618 /
6619
6620Set the current process's effective user id.
6621[clinic start generated code]*/
6622
Larry Hastings2f936352014-08-05 14:04:04 +10006623static PyObject *
6624os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006625/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006626{
6627 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006629 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006630}
6631#endif /* HAVE_SETEUID */
6632
Larry Hastings2f936352014-08-05 14:04:04 +10006633
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006634#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006635/*[clinic input]
6636os.setegid
6637
6638 egid: gid_t
6639 /
6640
6641Set the current process's effective group id.
6642[clinic start generated code]*/
6643
Larry Hastings2f936352014-08-05 14:04:04 +10006644static PyObject *
6645os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006646/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006647{
6648 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006650 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006651}
6652#endif /* HAVE_SETEGID */
6653
Larry Hastings2f936352014-08-05 14:04:04 +10006654
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006655#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006656/*[clinic input]
6657os.setreuid
6658
6659 ruid: uid_t
6660 euid: uid_t
6661 /
6662
6663Set the current process's real and effective user ids.
6664[clinic start generated code]*/
6665
Larry Hastings2f936352014-08-05 14:04:04 +10006666static PyObject *
6667os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006668/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006669{
Victor Stinner8c62be82010-05-06 00:08:46 +00006670 if (setreuid(ruid, euid) < 0) {
6671 return posix_error();
6672 } else {
6673 Py_INCREF(Py_None);
6674 return Py_None;
6675 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006676}
6677#endif /* HAVE_SETREUID */
6678
Larry Hastings2f936352014-08-05 14:04:04 +10006679
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006680#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006681/*[clinic input]
6682os.setregid
6683
6684 rgid: gid_t
6685 egid: gid_t
6686 /
6687
6688Set the current process's real and effective group ids.
6689[clinic start generated code]*/
6690
Larry Hastings2f936352014-08-05 14:04:04 +10006691static PyObject *
6692os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006693/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006694{
6695 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006696 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006697 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006698}
6699#endif /* HAVE_SETREGID */
6700
Larry Hastings2f936352014-08-05 14:04:04 +10006701
Guido van Rossumb6775db1994-08-01 11:34:53 +00006702#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006703/*[clinic input]
6704os.setgid
6705 gid: gid_t
6706 /
6707
6708Set the current process's group id.
6709[clinic start generated code]*/
6710
Larry Hastings2f936352014-08-05 14:04:04 +10006711static PyObject *
6712os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006713/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006714{
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 if (setgid(gid) < 0)
6716 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006717 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006718}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006719#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006720
Larry Hastings2f936352014-08-05 14:04:04 +10006721
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006722#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006723/*[clinic input]
6724os.setgroups
6725
6726 groups: object
6727 /
6728
6729Set the groups of the current process to list.
6730[clinic start generated code]*/
6731
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006732static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006733os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006734/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006735{
Victor Stinner8c62be82010-05-06 00:08:46 +00006736 int i, len;
6737 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006738
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 if (!PySequence_Check(groups)) {
6740 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6741 return NULL;
6742 }
6743 len = PySequence_Size(groups);
6744 if (len > MAX_GROUPS) {
6745 PyErr_SetString(PyExc_ValueError, "too many groups");
6746 return NULL;
6747 }
6748 for(i = 0; i < len; i++) {
6749 PyObject *elem;
6750 elem = PySequence_GetItem(groups, i);
6751 if (!elem)
6752 return NULL;
6753 if (!PyLong_Check(elem)) {
6754 PyErr_SetString(PyExc_TypeError,
6755 "groups must be integers");
6756 Py_DECREF(elem);
6757 return NULL;
6758 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006759 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 Py_DECREF(elem);
6761 return NULL;
6762 }
6763 }
6764 Py_DECREF(elem);
6765 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006766
Victor Stinner8c62be82010-05-06 00:08:46 +00006767 if (setgroups(len, grouplist) < 0)
6768 return posix_error();
6769 Py_INCREF(Py_None);
6770 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006771}
6772#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006773
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006774#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6775static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006776wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006777{
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 PyObject *result;
6779 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006780 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006781
Victor Stinner8c62be82010-05-06 00:08:46 +00006782 if (pid == -1)
6783 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006784
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 if (struct_rusage == NULL) {
6786 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6787 if (m == NULL)
6788 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006789 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 Py_DECREF(m);
6791 if (struct_rusage == NULL)
6792 return NULL;
6793 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006794
Victor Stinner8c62be82010-05-06 00:08:46 +00006795 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6796 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6797 if (!result)
6798 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006799
6800#ifndef doubletime
6801#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6802#endif
6803
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006805 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006806 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006807 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006808#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006809 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6810 SET_INT(result, 2, ru->ru_maxrss);
6811 SET_INT(result, 3, ru->ru_ixrss);
6812 SET_INT(result, 4, ru->ru_idrss);
6813 SET_INT(result, 5, ru->ru_isrss);
6814 SET_INT(result, 6, ru->ru_minflt);
6815 SET_INT(result, 7, ru->ru_majflt);
6816 SET_INT(result, 8, ru->ru_nswap);
6817 SET_INT(result, 9, ru->ru_inblock);
6818 SET_INT(result, 10, ru->ru_oublock);
6819 SET_INT(result, 11, ru->ru_msgsnd);
6820 SET_INT(result, 12, ru->ru_msgrcv);
6821 SET_INT(result, 13, ru->ru_nsignals);
6822 SET_INT(result, 14, ru->ru_nvcsw);
6823 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006824#undef SET_INT
6825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 if (PyErr_Occurred()) {
6827 Py_DECREF(result);
6828 return NULL;
6829 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006830
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006832}
6833#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6834
Larry Hastings2f936352014-08-05 14:04:04 +10006835
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006836#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006837/*[clinic input]
6838os.wait3
6839
6840 options: int
6841Wait for completion of a child process.
6842
6843Returns a tuple of information about the child process:
6844 (pid, status, rusage)
6845[clinic start generated code]*/
6846
Larry Hastings2f936352014-08-05 14:04:04 +10006847static PyObject *
6848os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006849/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006850{
Victor Stinner8c62be82010-05-06 00:08:46 +00006851 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006852 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006853 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006854 WAIT_TYPE status;
6855 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006856
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006857 do {
6858 Py_BEGIN_ALLOW_THREADS
6859 pid = wait3(&status, options, &ru);
6860 Py_END_ALLOW_THREADS
6861 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6862 if (pid < 0)
6863 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006864
Victor Stinner4195b5c2012-02-08 23:03:19 +01006865 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006866}
6867#endif /* HAVE_WAIT3 */
6868
Larry Hastings2f936352014-08-05 14:04:04 +10006869
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006870#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006871/*[clinic input]
6872
6873os.wait4
6874
6875 pid: pid_t
6876 options: int
6877
6878Wait for completion of a specific child process.
6879
6880Returns a tuple of information about the child process:
6881 (pid, status, rusage)
6882[clinic start generated code]*/
6883
Larry Hastings2f936352014-08-05 14:04:04 +10006884static PyObject *
6885os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006886/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006887{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006888 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006889 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006890 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006891 WAIT_TYPE status;
6892 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006893
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006894 do {
6895 Py_BEGIN_ALLOW_THREADS
6896 res = wait4(pid, &status, options, &ru);
6897 Py_END_ALLOW_THREADS
6898 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6899 if (res < 0)
6900 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006901
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006902 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006903}
6904#endif /* HAVE_WAIT4 */
6905
Larry Hastings2f936352014-08-05 14:04:04 +10006906
Ross Lagerwall7807c352011-03-17 20:20:30 +02006907#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006908/*[clinic input]
6909os.waitid
6910
6911 idtype: idtype_t
6912 Must be one of be P_PID, P_PGID or P_ALL.
6913 id: id_t
6914 The id to wait on.
6915 options: int
6916 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6917 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6918 /
6919
6920Returns the result of waiting for a process or processes.
6921
6922Returns either waitid_result or None if WNOHANG is specified and there are
6923no children in a waitable state.
6924[clinic start generated code]*/
6925
Larry Hastings2f936352014-08-05 14:04:04 +10006926static PyObject *
6927os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006928/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006929{
6930 PyObject *result;
6931 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006932 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006933 siginfo_t si;
6934 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006935
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006936 do {
6937 Py_BEGIN_ALLOW_THREADS
6938 res = waitid(idtype, id, &si, options);
6939 Py_END_ALLOW_THREADS
6940 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6941 if (res < 0)
6942 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006943
6944 if (si.si_pid == 0)
6945 Py_RETURN_NONE;
6946
6947 result = PyStructSequence_New(&WaitidResultType);
6948 if (!result)
6949 return NULL;
6950
6951 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006952 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006953 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6954 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6955 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6956 if (PyErr_Occurred()) {
6957 Py_DECREF(result);
6958 return NULL;
6959 }
6960
6961 return result;
6962}
Larry Hastings2f936352014-08-05 14:04:04 +10006963#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006964
Larry Hastings2f936352014-08-05 14:04:04 +10006965
6966#if defined(HAVE_WAITPID)
6967/*[clinic input]
6968os.waitpid
6969 pid: pid_t
6970 options: int
6971 /
6972
6973Wait for completion of a given child process.
6974
6975Returns a tuple of information regarding the child process:
6976 (pid, status)
6977
6978The options argument is ignored on Windows.
6979[clinic start generated code]*/
6980
Larry Hastings2f936352014-08-05 14:04:04 +10006981static PyObject *
6982os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006983/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006984{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006985 pid_t res;
6986 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006987 WAIT_TYPE status;
6988 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006989
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006990 do {
6991 Py_BEGIN_ALLOW_THREADS
6992 res = waitpid(pid, &status, options);
6993 Py_END_ALLOW_THREADS
6994 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6995 if (res < 0)
6996 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006997
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006998 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006999}
Tim Petersab034fa2002-02-01 11:27:43 +00007000#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00007001/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10007002/*[clinic input]
7003os.waitpid
7004 pid: Py_intptr_t
7005 options: int
7006 /
7007
7008Wait for completion of a given process.
7009
7010Returns a tuple of information regarding the process:
7011 (pid, status << 8)
7012
7013The options argument is ignored on Windows.
7014[clinic start generated code]*/
7015
Larry Hastings2f936352014-08-05 14:04:04 +10007016static PyObject *
7017os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007018/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007019{
7020 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007021 Py_intptr_t res;
7022 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007023
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007024 do {
7025 Py_BEGIN_ALLOW_THREADS
7026 res = _cwait(&status, pid, options);
7027 Py_END_ALLOW_THREADS
7028 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007029 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007030 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007031
Victor Stinner8c62be82010-05-06 00:08:46 +00007032 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007033 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007034}
Larry Hastings2f936352014-08-05 14:04:04 +10007035#endif
7036
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007037
Guido van Rossumad0ee831995-03-01 10:34:45 +00007038#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007039/*[clinic input]
7040os.wait
7041
7042Wait for completion of a child process.
7043
7044Returns a tuple of information about the child process:
7045 (pid, status)
7046[clinic start generated code]*/
7047
Larry Hastings2f936352014-08-05 14:04:04 +10007048static PyObject *
7049os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007050/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007051{
Victor Stinner8c62be82010-05-06 00:08:46 +00007052 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007053 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007054 WAIT_TYPE status;
7055 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007056
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007057 do {
7058 Py_BEGIN_ALLOW_THREADS
7059 pid = wait(&status);
7060 Py_END_ALLOW_THREADS
7061 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7062 if (pid < 0)
7063 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007064
Victor Stinner8c62be82010-05-06 00:08:46 +00007065 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007066}
Larry Hastings2f936352014-08-05 14:04:04 +10007067#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007068
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007069
Larry Hastings9cf065c2012-06-22 16:30:09 -07007070#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7071PyDoc_STRVAR(readlink__doc__,
7072"readlink(path, *, dir_fd=None) -> path\n\n\
7073Return a string representing the path to which the symbolic link points.\n\
7074\n\
7075If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7076 and path should be relative; path will then be relative to that directory.\n\
7077dir_fd may not be implemented on your platform.\n\
7078 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007079#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007080
Guido van Rossumb6775db1994-08-01 11:34:53 +00007081#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007082
Larry Hastings2f936352014-08-05 14:04:04 +10007083/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007084static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007085posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007086{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007087 path_t path;
7088 int dir_fd = DEFAULT_DIR_FD;
7089 char buffer[MAXPATHLEN];
7090 ssize_t length;
7091 PyObject *return_value = NULL;
7092 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007093
Larry Hastings9cf065c2012-06-22 16:30:09 -07007094 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007095 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007096 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7097 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007098 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007099 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007100
Victor Stinner8c62be82010-05-06 00:08:46 +00007101 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007102#ifdef HAVE_READLINKAT
7103 if (dir_fd != DEFAULT_DIR_FD)
7104 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007105 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007106#endif
7107 length = readlink(path.narrow, buffer, sizeof(buffer));
7108 Py_END_ALLOW_THREADS
7109
7110 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007111 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007112 goto exit;
7113 }
7114
7115 if (PyUnicode_Check(path.object))
7116 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7117 else
7118 return_value = PyBytes_FromStringAndSize(buffer, length);
7119exit:
7120 path_cleanup(&path);
7121 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007122}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007123
Guido van Rossumb6775db1994-08-01 11:34:53 +00007124#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007125
Larry Hastings2f936352014-08-05 14:04:04 +10007126#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7127
7128static PyObject *
7129win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7130{
7131 wchar_t *path;
7132 DWORD n_bytes_returned;
7133 DWORD io_result;
7134 PyObject *po, *result;
7135 int dir_fd;
7136 HANDLE reparse_point_handle;
7137
7138 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7139 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7140 wchar_t *print_name;
7141
7142 static char *keywords[] = {"path", "dir_fd", NULL};
7143
7144 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7145 &po,
7146 dir_fd_unavailable, &dir_fd
7147 ))
7148 return NULL;
7149
7150 path = PyUnicode_AsUnicode(po);
7151 if (path == NULL)
7152 return NULL;
7153
7154 /* First get a handle to the reparse point */
7155 Py_BEGIN_ALLOW_THREADS
7156 reparse_point_handle = CreateFileW(
7157 path,
7158 0,
7159 0,
7160 0,
7161 OPEN_EXISTING,
7162 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7163 0);
7164 Py_END_ALLOW_THREADS
7165
7166 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7167 return win32_error_object("readlink", po);
7168
7169 Py_BEGIN_ALLOW_THREADS
7170 /* New call DeviceIoControl to read the reparse point */
7171 io_result = DeviceIoControl(
7172 reparse_point_handle,
7173 FSCTL_GET_REPARSE_POINT,
7174 0, 0, /* in buffer */
7175 target_buffer, sizeof(target_buffer),
7176 &n_bytes_returned,
7177 0 /* we're not using OVERLAPPED_IO */
7178 );
7179 CloseHandle(reparse_point_handle);
7180 Py_END_ALLOW_THREADS
7181
7182 if (io_result==0)
7183 return win32_error_object("readlink", po);
7184
7185 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7186 {
7187 PyErr_SetString(PyExc_ValueError,
7188 "not a symbolic link");
7189 return NULL;
7190 }
7191 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7192 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7193
7194 result = PyUnicode_FromWideChar(print_name,
7195 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7196 return result;
7197}
7198
7199#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7200
7201
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007202
Larry Hastings9cf065c2012-06-22 16:30:09 -07007203#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007204
7205#if defined(MS_WINDOWS)
7206
7207/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7208static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7209static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007210
Larry Hastings9cf065c2012-06-22 16:30:09 -07007211static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007212check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007213{
7214 HINSTANCE hKernel32;
7215 /* only recheck */
7216 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7217 return 1;
7218 hKernel32 = GetModuleHandleW(L"KERNEL32");
7219 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7220 "CreateSymbolicLinkW");
7221 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7222 "CreateSymbolicLinkA");
7223 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7224}
7225
Victor Stinner31b3b922013-06-05 01:49:17 +02007226/* Remove the last portion of the path */
7227static void
7228_dirnameW(WCHAR *path)
7229{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007230 WCHAR *ptr;
7231
7232 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007233 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007234 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007235 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007236 }
7237 *ptr = 0;
7238}
7239
Victor Stinner31b3b922013-06-05 01:49:17 +02007240/* Remove the last portion of the path */
7241static void
7242_dirnameA(char *path)
7243{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007244 char *ptr;
7245
7246 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007247 for(ptr = path + strlen(path); ptr != path; ptr--) {
7248 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007249 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007250 }
7251 *ptr = 0;
7252}
7253
Victor Stinner31b3b922013-06-05 01:49:17 +02007254/* Is this path absolute? */
7255static int
7256_is_absW(const WCHAR *path)
7257{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007258 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7259
7260}
7261
Victor Stinner31b3b922013-06-05 01:49:17 +02007262/* Is this path absolute? */
7263static int
7264_is_absA(const char *path)
7265{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007266 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7267
7268}
7269
Victor Stinner31b3b922013-06-05 01:49:17 +02007270/* join root and rest with a backslash */
7271static void
7272_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7273{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007274 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007275
Victor Stinner31b3b922013-06-05 01:49:17 +02007276 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 wcscpy(dest_path, rest);
7278 return;
7279 }
7280
7281 root_len = wcslen(root);
7282
7283 wcscpy(dest_path, root);
7284 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007285 dest_path[root_len] = L'\\';
7286 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007287 }
7288 wcscpy(dest_path+root_len, rest);
7289}
7290
Victor Stinner31b3b922013-06-05 01:49:17 +02007291/* join root and rest with a backslash */
7292static void
7293_joinA(char *dest_path, const char *root, const char *rest)
7294{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007295 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007296
Victor Stinner31b3b922013-06-05 01:49:17 +02007297 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007298 strcpy(dest_path, rest);
7299 return;
7300 }
7301
7302 root_len = strlen(root);
7303
7304 strcpy(dest_path, root);
7305 if(root_len) {
7306 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007307 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308 }
7309 strcpy(dest_path+root_len, rest);
7310}
7311
Victor Stinner31b3b922013-06-05 01:49:17 +02007312/* Return True if the path at src relative to dest is a directory */
7313static int
7314_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007315{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007316 WIN32_FILE_ATTRIBUTE_DATA src_info;
7317 WCHAR dest_parent[MAX_PATH];
7318 WCHAR src_resolved[MAX_PATH] = L"";
7319
7320 /* dest_parent = os.path.dirname(dest) */
7321 wcscpy(dest_parent, dest);
7322 _dirnameW(dest_parent);
7323 /* src_resolved = os.path.join(dest_parent, src) */
7324 _joinW(src_resolved, dest_parent, src);
7325 return (
7326 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7327 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7328 );
7329}
7330
Victor Stinner31b3b922013-06-05 01:49:17 +02007331/* Return True if the path at src relative to dest is a directory */
7332static int
Serhiy Storchakaef1585e2015-12-25 20:01:53 +02007333_check_dirA(const char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007334{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007335 WIN32_FILE_ATTRIBUTE_DATA src_info;
7336 char dest_parent[MAX_PATH];
7337 char src_resolved[MAX_PATH] = "";
7338
7339 /* dest_parent = os.path.dirname(dest) */
7340 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007341 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007342 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007343 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007344 return (
7345 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7346 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7347 );
7348}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007349#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007350
Larry Hastings2f936352014-08-05 14:04:04 +10007351
7352/*[clinic input]
7353os.symlink
7354 src: path_t
7355 dst: path_t
7356 target_is_directory: bool = False
7357 *
7358 dir_fd: dir_fd(requires='symlinkat')=None
7359
7360# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7361
7362Create a symbolic link pointing to src named dst.
7363
7364target_is_directory is required on Windows if the target is to be
7365 interpreted as a directory. (On Windows, symlink requires
7366 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7367 target_is_directory is ignored on non-Windows platforms.
7368
7369If dir_fd is not None, it should be a file descriptor open to a directory,
7370 and path should be relative; path will then be relative to that directory.
7371dir_fd may not be implemented on your platform.
7372 If it is unavailable, using it will raise a NotImplementedError.
7373
7374[clinic start generated code]*/
7375
Larry Hastings2f936352014-08-05 14:04:04 +10007376static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04007377os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst,
7378 int target_is_directory, int dir_fd)
7379/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007380{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007381#ifdef MS_WINDOWS
7382 DWORD result;
7383#else
7384 int result;
7385#endif
7386
Larry Hastings9cf065c2012-06-22 16:30:09 -07007387#ifdef MS_WINDOWS
7388 if (!check_CreateSymbolicLink()) {
7389 PyErr_SetString(PyExc_NotImplementedError,
7390 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007391 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007392 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007393 if (!win32_can_symlink) {
7394 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007395 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007396 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007397#endif
7398
Larry Hastings2f936352014-08-05 14:04:04 +10007399 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007400 PyErr_SetString(PyExc_ValueError,
7401 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007402 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007403 }
7404
7405#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007406
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007408 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007409 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007410 target_is_directory |= _check_dirW(src->wide, dst->wide);
7411 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007412 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007413 }
7414 else {
7415 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007416 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7417 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007418 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007419 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007420 Py_END_ALLOW_THREADS
7421
Larry Hastings2f936352014-08-05 14:04:04 +10007422 if (!result)
7423 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007424
7425#else
7426
7427 Py_BEGIN_ALLOW_THREADS
7428#if HAVE_SYMLINKAT
7429 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007430 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007431 else
7432#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007433 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007434 Py_END_ALLOW_THREADS
7435
Larry Hastings2f936352014-08-05 14:04:04 +10007436 if (result)
7437 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007438#endif
7439
Larry Hastings2f936352014-08-05 14:04:04 +10007440 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007441}
7442#endif /* HAVE_SYMLINK */
7443
Larry Hastings9cf065c2012-06-22 16:30:09 -07007444
Brian Curtind40e6f72010-07-08 21:39:08 +00007445
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007446
Larry Hastings605a62d2012-06-24 04:33:36 -07007447static PyStructSequence_Field times_result_fields[] = {
7448 {"user", "user time"},
7449 {"system", "system time"},
7450 {"children_user", "user time of children"},
7451 {"children_system", "system time of children"},
7452 {"elapsed", "elapsed time since an arbitrary point in the past"},
7453 {NULL}
7454};
7455
7456PyDoc_STRVAR(times_result__doc__,
7457"times_result: Result from os.times().\n\n\
7458This object may be accessed either as a tuple of\n\
7459 (user, system, children_user, children_system, elapsed),\n\
7460or via the attributes user, system, children_user, children_system,\n\
7461and elapsed.\n\
7462\n\
7463See os.times for more information.");
7464
7465static PyStructSequence_Desc times_result_desc = {
7466 "times_result", /* name */
7467 times_result__doc__, /* doc */
7468 times_result_fields,
7469 5
7470};
7471
7472static PyTypeObject TimesResultType;
7473
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007474#ifdef MS_WINDOWS
7475#define HAVE_TIMES /* mandatory, for the method table */
7476#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007477
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007478#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007479
7480static PyObject *
7481build_times_result(double user, double system,
7482 double children_user, double children_system,
7483 double elapsed)
7484{
7485 PyObject *value = PyStructSequence_New(&TimesResultType);
7486 if (value == NULL)
7487 return NULL;
7488
7489#define SET(i, field) \
7490 { \
7491 PyObject *o = PyFloat_FromDouble(field); \
7492 if (!o) { \
7493 Py_DECREF(value); \
7494 return NULL; \
7495 } \
7496 PyStructSequence_SET_ITEM(value, i, o); \
7497 } \
7498
7499 SET(0, user);
7500 SET(1, system);
7501 SET(2, children_user);
7502 SET(3, children_system);
7503 SET(4, elapsed);
7504
7505#undef SET
7506
7507 return value;
7508}
7509
Larry Hastings605a62d2012-06-24 04:33:36 -07007510
Larry Hastings2f936352014-08-05 14:04:04 +10007511#ifndef MS_WINDOWS
7512#define NEED_TICKS_PER_SECOND
7513static long ticks_per_second = -1;
7514#endif /* MS_WINDOWS */
7515
7516/*[clinic input]
7517os.times
7518
7519Return a collection containing process timing information.
7520
7521The object returned behaves like a named tuple with these fields:
7522 (utime, stime, cutime, cstime, elapsed_time)
7523All fields are floating point numbers.
7524[clinic start generated code]*/
7525
Larry Hastings2f936352014-08-05 14:04:04 +10007526static PyObject *
7527os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007528/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007529#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007530{
Victor Stinner8c62be82010-05-06 00:08:46 +00007531 FILETIME create, exit, kernel, user;
7532 HANDLE hProc;
7533 hProc = GetCurrentProcess();
7534 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7535 /* The fields of a FILETIME structure are the hi and lo part
7536 of a 64-bit value expressed in 100 nanosecond units.
7537 1e7 is one second in such units; 1e-7 the inverse.
7538 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7539 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007540 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007541 (double)(user.dwHighDateTime*429.4967296 +
7542 user.dwLowDateTime*1e-7),
7543 (double)(kernel.dwHighDateTime*429.4967296 +
7544 kernel.dwLowDateTime*1e-7),
7545 (double)0,
7546 (double)0,
7547 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007548}
Larry Hastings2f936352014-08-05 14:04:04 +10007549#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007550{
Larry Hastings2f936352014-08-05 14:04:04 +10007551
7552
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007553 struct tms t;
7554 clock_t c;
7555 errno = 0;
7556 c = times(&t);
7557 if (c == (clock_t) -1)
7558 return posix_error();
7559 return build_times_result(
7560 (double)t.tms_utime / ticks_per_second,
7561 (double)t.tms_stime / ticks_per_second,
7562 (double)t.tms_cutime / ticks_per_second,
7563 (double)t.tms_cstime / ticks_per_second,
7564 (double)c / ticks_per_second);
7565}
Larry Hastings2f936352014-08-05 14:04:04 +10007566#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007567#endif /* HAVE_TIMES */
7568
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007569
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007570#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007571/*[clinic input]
7572os.getsid
7573
7574 pid: pid_t
7575 /
7576
7577Call the system call getsid(pid) and return the result.
7578[clinic start generated code]*/
7579
Larry Hastings2f936352014-08-05 14:04:04 +10007580static PyObject *
7581os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007582/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007583{
Victor Stinner8c62be82010-05-06 00:08:46 +00007584 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007585 sid = getsid(pid);
7586 if (sid < 0)
7587 return posix_error();
7588 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007589}
7590#endif /* HAVE_GETSID */
7591
7592
Guido van Rossumb6775db1994-08-01 11:34:53 +00007593#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007594/*[clinic input]
7595os.setsid
7596
7597Call the system call setsid().
7598[clinic start generated code]*/
7599
Larry Hastings2f936352014-08-05 14:04:04 +10007600static PyObject *
7601os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007602/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 if (setsid() < 0)
7605 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007606 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007608#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609
Larry Hastings2f936352014-08-05 14:04:04 +10007610
Guido van Rossumb6775db1994-08-01 11:34:53 +00007611#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.setpgid
7614
7615 pid: pid_t
7616 pgrp: pid_t
7617 /
7618
7619Call the system call setpgid(pid, pgrp).
7620[clinic start generated code]*/
7621
Larry Hastings2f936352014-08-05 14:04:04 +10007622static PyObject *
7623os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007624/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007625{
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 if (setpgid(pid, pgrp) < 0)
7627 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007628 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007630#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007632
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007634/*[clinic input]
7635os.tcgetpgrp
7636
7637 fd: int
7638 /
7639
7640Return the process group associated with the terminal specified by fd.
7641[clinic start generated code]*/
7642
Larry Hastings2f936352014-08-05 14:04:04 +10007643static PyObject *
7644os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007645/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007646{
7647 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 if (pgid < 0)
7649 return posix_error();
7650 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007651}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007652#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007653
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007654
Guido van Rossumb6775db1994-08-01 11:34:53 +00007655#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007656/*[clinic input]
7657os.tcsetpgrp
7658
7659 fd: int
7660 pgid: pid_t
7661 /
7662
7663Set the process group associated with the terminal specified by fd.
7664[clinic start generated code]*/
7665
Larry Hastings2f936352014-08-05 14:04:04 +10007666static PyObject *
7667os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007668/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007669{
Victor Stinner8c62be82010-05-06 00:08:46 +00007670 if (tcsetpgrp(fd, pgid) < 0)
7671 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007672 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007673}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007674#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007675
Guido van Rossum687dd131993-05-17 08:34:16 +00007676/* Functions acting on file descriptors */
7677
Victor Stinnerdaf45552013-08-28 00:53:59 +02007678#ifdef O_CLOEXEC
7679extern int _Py_open_cloexec_works;
7680#endif
7681
Larry Hastings2f936352014-08-05 14:04:04 +10007682
7683/*[clinic input]
7684os.open -> int
7685 path: path_t
7686 flags: int
7687 mode: int = 0o777
7688 *
7689 dir_fd: dir_fd(requires='openat') = None
7690
7691# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7692
7693Open a file for low level IO. Returns a file descriptor (integer).
7694
7695If dir_fd is not None, it should be a file descriptor open to a directory,
7696 and path should be relative; path will then be relative to that directory.
7697dir_fd may not be implemented on your platform.
7698 If it is unavailable, using it will raise a NotImplementedError.
7699[clinic start generated code]*/
7700
Larry Hastings2f936352014-08-05 14:04:04 +10007701static int
Larry Hastings89964c42015-04-14 18:07:59 -04007702os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode,
7703 int dir_fd)
7704/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007705{
7706 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007707 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007708
Victor Stinnerdaf45552013-08-28 00:53:59 +02007709#ifdef O_CLOEXEC
7710 int *atomic_flag_works = &_Py_open_cloexec_works;
7711#elif !defined(MS_WINDOWS)
7712 int *atomic_flag_works = NULL;
7713#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007714
Victor Stinnerdaf45552013-08-28 00:53:59 +02007715#ifdef MS_WINDOWS
7716 flags |= O_NOINHERIT;
7717#elif defined(O_CLOEXEC)
7718 flags |= O_CLOEXEC;
7719#endif
7720
Steve Dower8fc89802015-04-12 00:26:27 -04007721 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007722 do {
7723 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007724#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007725 if (path->wide)
7726 fd = _wopen(path->wide, flags, mode);
7727 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007728#endif
7729#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007730 if (dir_fd != DEFAULT_DIR_FD)
7731 fd = openat(dir_fd, path->narrow, flags, mode);
7732 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007733#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007734 fd = open(path->narrow, flags, mode);
7735 Py_END_ALLOW_THREADS
7736 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007737 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007738
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007739 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007740 if (!async_err)
7741 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007742 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007743 }
7744
Victor Stinnerdaf45552013-08-28 00:53:59 +02007745#ifndef MS_WINDOWS
7746 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7747 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007748 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007749 }
7750#endif
7751
Larry Hastings2f936352014-08-05 14:04:04 +10007752 return fd;
7753}
7754
7755
7756/*[clinic input]
7757os.close
7758
7759 fd: int
7760
7761Close a file descriptor.
7762[clinic start generated code]*/
7763
Barry Warsaw53699e91996-12-10 23:23:01 +00007764static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007765os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007766/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007767{
Larry Hastings2f936352014-08-05 14:04:04 +10007768 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007769 if (!_PyVerify_fd(fd))
7770 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007771 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7772 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7773 * for more details.
7774 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007775 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007776 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007777 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007778 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007779 Py_END_ALLOW_THREADS
7780 if (res < 0)
7781 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007782 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007783}
7784
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007785
Larry Hastings2f936352014-08-05 14:04:04 +10007786/*[clinic input]
7787os.closerange
7788
7789 fd_low: int
7790 fd_high: int
7791 /
7792
7793Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7794[clinic start generated code]*/
7795
Larry Hastings2f936352014-08-05 14:04:04 +10007796static PyObject *
7797os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007798/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007799{
7800 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007801 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007802 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007803 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007804 if (_PyVerify_fd(i))
7805 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007806 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007807 Py_END_ALLOW_THREADS
7808 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007809}
7810
7811
Larry Hastings2f936352014-08-05 14:04:04 +10007812/*[clinic input]
7813os.dup -> int
7814
7815 fd: int
7816 /
7817
7818Return a duplicate of a file descriptor.
7819[clinic start generated code]*/
7820
Larry Hastings2f936352014-08-05 14:04:04 +10007821static int
7822os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007823/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007824{
7825 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007826}
7827
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007828
Larry Hastings2f936352014-08-05 14:04:04 +10007829/*[clinic input]
7830os.dup2
7831 fd: int
7832 fd2: int
7833 inheritable: bool=True
7834
7835Duplicate file descriptor.
7836[clinic start generated code]*/
7837
Larry Hastings2f936352014-08-05 14:04:04 +10007838static PyObject *
7839os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007840/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007841{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007842 int res;
7843#if defined(HAVE_DUP3) && \
7844 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7845 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7846 int dup3_works = -1;
7847#endif
7848
Victor Stinner8c62be82010-05-06 00:08:46 +00007849 if (!_PyVerify_fd_dup2(fd, fd2))
7850 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007851
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007852 /* dup2() can fail with EINTR if the target FD is already open, because it
7853 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7854 * upon close(), and therefore below.
7855 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856#ifdef MS_WINDOWS
7857 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007858 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007859 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007860 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007861 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007862 if (res < 0)
7863 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007864
7865 /* Character files like console cannot be make non-inheritable */
7866 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7867 close(fd2);
7868 return NULL;
7869 }
7870
7871#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7872 Py_BEGIN_ALLOW_THREADS
7873 if (!inheritable)
7874 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7875 else
7876 res = dup2(fd, fd2);
7877 Py_END_ALLOW_THREADS
7878 if (res < 0)
7879 return posix_error();
7880
7881#else
7882
7883#ifdef HAVE_DUP3
7884 if (!inheritable && dup3_works != 0) {
7885 Py_BEGIN_ALLOW_THREADS
7886 res = dup3(fd, fd2, O_CLOEXEC);
7887 Py_END_ALLOW_THREADS
7888 if (res < 0) {
7889 if (dup3_works == -1)
7890 dup3_works = (errno != ENOSYS);
7891 if (dup3_works)
7892 return posix_error();
7893 }
7894 }
7895
7896 if (inheritable || dup3_works == 0)
7897 {
7898#endif
7899 Py_BEGIN_ALLOW_THREADS
7900 res = dup2(fd, fd2);
7901 Py_END_ALLOW_THREADS
7902 if (res < 0)
7903 return posix_error();
7904
7905 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7906 close(fd2);
7907 return NULL;
7908 }
7909#ifdef HAVE_DUP3
7910 }
7911#endif
7912
7913#endif
7914
Larry Hastings2f936352014-08-05 14:04:04 +10007915 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007916}
7917
Larry Hastings2f936352014-08-05 14:04:04 +10007918
Ross Lagerwall7807c352011-03-17 20:20:30 +02007919#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007920/*[clinic input]
7921os.lockf
7922
7923 fd: int
7924 An open file descriptor.
7925 command: int
7926 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7927 length: Py_off_t
7928 The number of bytes to lock, starting at the current position.
7929 /
7930
7931Apply, test or remove a POSIX lock on an open file descriptor.
7932
7933[clinic start generated code]*/
7934
Larry Hastings2f936352014-08-05 14:04:04 +10007935static PyObject *
7936os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007937/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007938{
7939 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007940
7941 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007942 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007943 Py_END_ALLOW_THREADS
7944
7945 if (res < 0)
7946 return posix_error();
7947
7948 Py_RETURN_NONE;
7949}
Larry Hastings2f936352014-08-05 14:04:04 +10007950#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007951
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007952
Larry Hastings2f936352014-08-05 14:04:04 +10007953/*[clinic input]
7954os.lseek -> Py_off_t
7955
7956 fd: int
7957 position: Py_off_t
7958 how: int
7959 /
7960
7961Set the position of a file descriptor. Return the new position.
7962
7963Return the new cursor position in number of bytes
7964relative to the beginning of the file.
7965[clinic start generated code]*/
7966
Larry Hastings2f936352014-08-05 14:04:04 +10007967static Py_off_t
7968os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007969/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007970{
7971 Py_off_t result;
7972
7973 if (!_PyVerify_fd(fd)) {
7974 posix_error();
7975 return -1;
7976 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007977#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7979 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007980 case 0: how = SEEK_SET; break;
7981 case 1: how = SEEK_CUR; break;
7982 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007983 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007984#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007985
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007987 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007988
Larry Hastings2f936352014-08-05 14:04:04 +10007989 if (!_PyVerify_fd(fd)) {
7990 posix_error();
7991 return -1;
7992 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007993 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007994 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007995#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007996 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007997#else
Larry Hastings2f936352014-08-05 14:04:04 +10007998 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007999#endif
Steve Dower8fc89802015-04-12 00:26:27 -04008000 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00008001 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008002 if (result < 0)
8003 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00008004
Larry Hastings2f936352014-08-05 14:04:04 +10008005 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008006}
8007
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008008
Larry Hastings2f936352014-08-05 14:04:04 +10008009/*[clinic input]
8010os.read
8011 fd: int
8012 length: Py_ssize_t
8013 /
8014
8015Read from a file descriptor. Returns a bytes object.
8016[clinic start generated code]*/
8017
Larry Hastings2f936352014-08-05 14:04:04 +10008018static PyObject *
8019os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008020/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008021{
Victor Stinner8c62be82010-05-06 00:08:46 +00008022 Py_ssize_t n;
8023 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008024
8025 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 errno = EINVAL;
8027 return posix_error();
8028 }
Larry Hastings2f936352014-08-05 14:04:04 +10008029
8030#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008031 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008032 if (length > INT_MAX)
8033 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008034#endif
8035
8036 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 if (buffer == NULL)
8038 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008039
Victor Stinner66aab0c2015-03-19 22:53:20 +01008040 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8041 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008043 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 }
Larry Hastings2f936352014-08-05 14:04:04 +10008045
8046 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008047 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008048
Victor Stinner8c62be82010-05-06 00:08:46 +00008049 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008050}
8051
Ross Lagerwall7807c352011-03-17 20:20:30 +02008052#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8053 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008054static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8056{
8057 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008058 Py_ssize_t blen, total = 0;
8059
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008060 *iov = PyMem_New(struct iovec, cnt);
8061 if (*iov == NULL) {
8062 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008063 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008065
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 *buf = PyMem_New(Py_buffer, cnt);
8067 if (*buf == NULL) {
8068 PyMem_Del(*iov);
8069 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008070 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008071 }
8072
8073 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008074 PyObject *item = PySequence_GetItem(seq, i);
8075 if (item == NULL)
8076 goto fail;
8077 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8078 Py_DECREF(item);
8079 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008080 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008081 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008082 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008083 blen = (*buf)[i].len;
8084 (*iov)[i].iov_len = blen;
8085 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008086 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008087 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008088
8089fail:
8090 PyMem_Del(*iov);
8091 for (j = 0; j < i; j++) {
8092 PyBuffer_Release(&(*buf)[j]);
8093 }
8094 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008095 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008096}
8097
8098static void
8099iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8100{
8101 int i;
8102 PyMem_Del(iov);
8103 for (i = 0; i < cnt; i++) {
8104 PyBuffer_Release(&buf[i]);
8105 }
8106 PyMem_Del(buf);
8107}
8108#endif
8109
Larry Hastings2f936352014-08-05 14:04:04 +10008110
Ross Lagerwall7807c352011-03-17 20:20:30 +02008111#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008112/*[clinic input]
8113os.readv -> Py_ssize_t
8114
8115 fd: int
8116 buffers: object
8117 /
8118
8119Read from a file descriptor fd into an iterable of buffers.
8120
8121The buffers should be mutable buffers accepting bytes.
8122readv will transfer data into each buffer until it is full
8123and then move on to the next buffer in the sequence to hold
8124the rest of the data.
8125
8126readv returns the total number of bytes read,
8127which may be less than the total capacity of all the buffers.
8128[clinic start generated code]*/
8129
Larry Hastings2f936352014-08-05 14:04:04 +10008130static Py_ssize_t
8131os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008132/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008133{
8134 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008135 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008137 struct iovec *iov;
8138 Py_buffer *buf;
8139
Larry Hastings2f936352014-08-05 14:04:04 +10008140 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008141 PyErr_SetString(PyExc_TypeError,
8142 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008143 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008144 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145
Larry Hastings2f936352014-08-05 14:04:04 +10008146 cnt = PySequence_Size(buffers);
8147
8148 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8149 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008150
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008151 do {
8152 Py_BEGIN_ALLOW_THREADS
8153 n = readv(fd, iov, cnt);
8154 Py_END_ALLOW_THREADS
8155 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008156
8157 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008158 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008159 if (!async_err)
8160 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008161 return -1;
8162 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008163
Larry Hastings2f936352014-08-05 14:04:04 +10008164 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008165}
Larry Hastings2f936352014-08-05 14:04:04 +10008166#endif /* HAVE_READV */
8167
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168
8169#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008170/*[clinic input]
8171# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8172os.pread
8173
8174 fd: int
8175 length: int
8176 offset: Py_off_t
8177 /
8178
8179Read a number of bytes from a file descriptor starting at a particular offset.
8180
8181Read length bytes from file descriptor fd, starting at offset bytes from
8182the beginning of the file. The file offset remains unchanged.
8183[clinic start generated code]*/
8184
Larry Hastings2f936352014-08-05 14:04:04 +10008185static PyObject *
8186os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008187/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008188{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008190 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008192
Larry Hastings2f936352014-08-05 14:04:04 +10008193 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008194 errno = EINVAL;
8195 return posix_error();
8196 }
Larry Hastings2f936352014-08-05 14:04:04 +10008197 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008198 if (buffer == NULL)
8199 return NULL;
8200 if (!_PyVerify_fd(fd)) {
8201 Py_DECREF(buffer);
8202 return posix_error();
8203 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008204
8205 do {
8206 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008207 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008208 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008209 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008210 Py_END_ALLOW_THREADS
8211 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8212
Ross Lagerwall7807c352011-03-17 20:20:30 +02008213 if (n < 0) {
8214 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008215 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216 }
Larry Hastings2f936352014-08-05 14:04:04 +10008217 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008218 _PyBytes_Resize(&buffer, n);
8219 return buffer;
8220}
Larry Hastings2f936352014-08-05 14:04:04 +10008221#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008222
Larry Hastings2f936352014-08-05 14:04:04 +10008223
8224/*[clinic input]
8225os.write -> Py_ssize_t
8226
8227 fd: int
8228 data: Py_buffer
8229 /
8230
8231Write a bytes object to a file descriptor.
8232[clinic start generated code]*/
8233
Larry Hastings2f936352014-08-05 14:04:04 +10008234static Py_ssize_t
8235os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008236/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008237{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008238 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008239}
8240
8241#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008243"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008244sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008245 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008246Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008247
Larry Hastings2f936352014-08-05 14:04:04 +10008248/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008249static PyObject *
8250posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8251{
8252 int in, out;
8253 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008254 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008255 off_t offset;
8256
8257#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8258#ifndef __APPLE__
8259 Py_ssize_t len;
8260#endif
8261 PyObject *headers = NULL, *trailers = NULL;
8262 Py_buffer *hbuf, *tbuf;
8263 off_t sbytes;
8264 struct sf_hdtr sf;
8265 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008266 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008267 static char *keywords[] = {"out", "in",
8268 "offset", "count",
8269 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008270
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008271 sf.headers = NULL;
8272 sf.trailers = NULL;
8273
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008274#ifdef __APPLE__
8275 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008276 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008277#else
8278 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008279 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280#endif
8281 &headers, &trailers, &flags))
8282 return NULL;
8283 if (headers != NULL) {
8284 if (!PySequence_Check(headers)) {
8285 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008286 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008287 return NULL;
8288 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008289 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008290 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008291 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008292 (i = iov_setup(&(sf.headers), &hbuf,
8293 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008294 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008295#ifdef __APPLE__
8296 sbytes += i;
8297#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008298 }
8299 }
8300 if (trailers != NULL) {
8301 if (!PySequence_Check(trailers)) {
8302 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008303 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 return NULL;
8305 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008306 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008307 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008308 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008309 (i = iov_setup(&(sf.trailers), &tbuf,
8310 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008311 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008312#ifdef __APPLE__
8313 sbytes += i;
8314#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008315 }
8316 }
8317
Steve Dower8fc89802015-04-12 00:26:27 -04008318 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 do {
8320 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008321#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008322 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008323#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008324 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008325#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008326 Py_END_ALLOW_THREADS
8327 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008328 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008329
8330 if (sf.headers != NULL)
8331 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8332 if (sf.trailers != NULL)
8333 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8334
8335 if (ret < 0) {
8336 if ((errno == EAGAIN) || (errno == EBUSY)) {
8337 if (sbytes != 0) {
8338 // some data has been sent
8339 goto done;
8340 }
8341 else {
8342 // no data has been sent; upper application is supposed
8343 // to retry on EAGAIN or EBUSY
8344 return posix_error();
8345 }
8346 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008347 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008348 }
8349 goto done;
8350
8351done:
8352 #if !defined(HAVE_LARGEFILE_SUPPORT)
8353 return Py_BuildValue("l", sbytes);
8354 #else
8355 return Py_BuildValue("L", sbytes);
8356 #endif
8357
8358#else
8359 Py_ssize_t count;
8360 PyObject *offobj;
8361 static char *keywords[] = {"out", "in",
8362 "offset", "count", NULL};
8363 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8364 keywords, &out, &in, &offobj, &count))
8365 return NULL;
8366#ifdef linux
8367 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008368 do {
8369 Py_BEGIN_ALLOW_THREADS
8370 ret = sendfile(out, in, NULL, count);
8371 Py_END_ALLOW_THREADS
8372 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008373 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008374 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008375 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008376 }
8377#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008378 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008379 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008380
8381 do {
8382 Py_BEGIN_ALLOW_THREADS
8383 ret = sendfile(out, in, &offset, count);
8384 Py_END_ALLOW_THREADS
8385 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008386 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008387 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008388 return Py_BuildValue("n", ret);
8389#endif
8390}
Larry Hastings2f936352014-08-05 14:04:04 +10008391#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008392
Larry Hastings2f936352014-08-05 14:04:04 +10008393
8394/*[clinic input]
8395os.fstat
8396
8397 fd : int
8398
8399Perform a stat system call on the given file descriptor.
8400
8401Like stat(), but for an open file descriptor.
8402Equivalent to os.stat(fd).
8403[clinic start generated code]*/
8404
Larry Hastings2f936352014-08-05 14:04:04 +10008405static PyObject *
8406os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008407/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008408{
Victor Stinner8c62be82010-05-06 00:08:46 +00008409 STRUCT_STAT st;
8410 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008411 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008412
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008413 do {
8414 Py_BEGIN_ALLOW_THREADS
8415 res = FSTAT(fd, &st);
8416 Py_END_ALLOW_THREADS
8417 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008418 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008419#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008420 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008421#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008422 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008423#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008424 }
Tim Peters5aa91602002-01-30 05:46:57 +00008425
Victor Stinner4195b5c2012-02-08 23:03:19 +01008426 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008427}
8428
Larry Hastings2f936352014-08-05 14:04:04 +10008429
8430/*[clinic input]
8431os.isatty -> bool
8432 fd: int
8433 /
8434
8435Return True if the fd is connected to a terminal.
8436
8437Return True if the file descriptor is an open file descriptor
8438connected to the slave end of a terminal.
8439[clinic start generated code]*/
8440
Larry Hastings2f936352014-08-05 14:04:04 +10008441static int
8442os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008443/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008444{
Steve Dower8fc89802015-04-12 00:26:27 -04008445 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008446 if (!_PyVerify_fd(fd))
8447 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008448 _Py_BEGIN_SUPPRESS_IPH
8449 return_value = isatty(fd);
8450 _Py_END_SUPPRESS_IPH
8451 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008452}
8453
8454
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008455#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008456/*[clinic input]
8457os.pipe
8458
8459Create a pipe.
8460
8461Returns a tuple of two file descriptors:
8462 (read_fd, write_fd)
8463[clinic start generated code]*/
8464
Larry Hastings2f936352014-08-05 14:04:04 +10008465static PyObject *
8466os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008467/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008468{
Victor Stinner8c62be82010-05-06 00:08:46 +00008469 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008470#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008471 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008472 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008473 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008474#else
8475 int res;
8476#endif
8477
8478#ifdef MS_WINDOWS
8479 attr.nLength = sizeof(attr);
8480 attr.lpSecurityDescriptor = NULL;
8481 attr.bInheritHandle = FALSE;
8482
8483 Py_BEGIN_ALLOW_THREADS
8484 ok = CreatePipe(&read, &write, &attr, 0);
8485 if (ok) {
8486 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8487 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8488 if (fds[0] == -1 || fds[1] == -1) {
8489 CloseHandle(read);
8490 CloseHandle(write);
8491 ok = 0;
8492 }
8493 }
8494 Py_END_ALLOW_THREADS
8495
Victor Stinner8c62be82010-05-06 00:08:46 +00008496 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008497 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008498#else
8499
8500#ifdef HAVE_PIPE2
8501 Py_BEGIN_ALLOW_THREADS
8502 res = pipe2(fds, O_CLOEXEC);
8503 Py_END_ALLOW_THREADS
8504
8505 if (res != 0 && errno == ENOSYS)
8506 {
8507#endif
8508 Py_BEGIN_ALLOW_THREADS
8509 res = pipe(fds);
8510 Py_END_ALLOW_THREADS
8511
8512 if (res == 0) {
8513 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8514 close(fds[0]);
8515 close(fds[1]);
8516 return NULL;
8517 }
8518 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8519 close(fds[0]);
8520 close(fds[1]);
8521 return NULL;
8522 }
8523 }
8524#ifdef HAVE_PIPE2
8525 }
8526#endif
8527
8528 if (res != 0)
8529 return PyErr_SetFromErrno(PyExc_OSError);
8530#endif /* !MS_WINDOWS */
8531 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008532}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008533#endif /* HAVE_PIPE */
8534
Larry Hastings2f936352014-08-05 14:04:04 +10008535
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008536#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008537/*[clinic input]
8538os.pipe2
8539
8540 flags: int
8541 /
8542
8543Create a pipe with flags set atomically.
8544
8545Returns a tuple of two file descriptors:
8546 (read_fd, write_fd)
8547
8548flags can be constructed by ORing together one or more of these values:
8549O_NONBLOCK, O_CLOEXEC.
8550[clinic start generated code]*/
8551
Larry Hastings2f936352014-08-05 14:04:04 +10008552static PyObject *
8553os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008554/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008555{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008556 int fds[2];
8557 int res;
8558
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008559 res = pipe2(fds, flags);
8560 if (res != 0)
8561 return posix_error();
8562 return Py_BuildValue("(ii)", fds[0], fds[1]);
8563}
8564#endif /* HAVE_PIPE2 */
8565
Larry Hastings2f936352014-08-05 14:04:04 +10008566
Ross Lagerwall7807c352011-03-17 20:20:30 +02008567#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008568/*[clinic input]
8569os.writev -> Py_ssize_t
8570 fd: int
8571 buffers: object
8572 /
8573
8574Iterate over buffers, and write the contents of each to a file descriptor.
8575
8576Returns the total number of bytes written.
8577buffers must be a sequence of bytes-like objects.
8578[clinic start generated code]*/
8579
Larry Hastings2f936352014-08-05 14:04:04 +10008580static Py_ssize_t
8581os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008582/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008583{
8584 int cnt;
8585 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008586 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008587 struct iovec *iov;
8588 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008589
8590 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008591 PyErr_SetString(PyExc_TypeError,
8592 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008593 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594 }
Larry Hastings2f936352014-08-05 14:04:04 +10008595 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008596
Larry Hastings2f936352014-08-05 14:04:04 +10008597 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8598 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008599 }
8600
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008601 do {
8602 Py_BEGIN_ALLOW_THREADS
8603 result = writev(fd, iov, cnt);
8604 Py_END_ALLOW_THREADS
8605 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008606
8607 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008608 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008609 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008610
Georg Brandl306336b2012-06-24 12:55:33 +02008611 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008612}
Larry Hastings2f936352014-08-05 14:04:04 +10008613#endif /* HAVE_WRITEV */
8614
8615
8616#ifdef HAVE_PWRITE
8617/*[clinic input]
8618os.pwrite -> Py_ssize_t
8619
8620 fd: int
8621 buffer: Py_buffer
8622 offset: Py_off_t
8623 /
8624
8625Write bytes to a file descriptor starting at a particular offset.
8626
8627Write buffer to fd, starting at offset bytes from the beginning of
8628the file. Returns the number of bytes writte. Does not change the
8629current file offset.
8630[clinic start generated code]*/
8631
Larry Hastings2f936352014-08-05 14:04:04 +10008632static Py_ssize_t
Larry Hastings89964c42015-04-14 18:07:59 -04008633os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
8634 Py_off_t offset)
8635/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008636{
8637 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008638 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008639
8640 if (!_PyVerify_fd(fd)) {
8641 posix_error();
8642 return -1;
8643 }
8644
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 do {
8646 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008647 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008649 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008650 Py_END_ALLOW_THREADS
8651 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008652
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008653 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008654 posix_error();
8655 return size;
8656}
8657#endif /* HAVE_PWRITE */
8658
8659
8660#ifdef HAVE_MKFIFO
8661/*[clinic input]
8662os.mkfifo
8663
8664 path: path_t
8665 mode: int=0o666
8666 *
8667 dir_fd: dir_fd(requires='mkfifoat')=None
8668
8669Create a "fifo" (a POSIX named pipe).
8670
8671If dir_fd is not None, it should be a file descriptor open to a directory,
8672 and path should be relative; path will then be relative to that directory.
8673dir_fd may not be implemented on your platform.
8674 If it is unavailable, using it will raise a NotImplementedError.
8675[clinic start generated code]*/
8676
Larry Hastings2f936352014-08-05 14:04:04 +10008677static PyObject *
8678os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008679/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008680{
8681 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008683
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 do {
8685 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008686#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008687 if (dir_fd != DEFAULT_DIR_FD)
8688 result = mkfifoat(dir_fd, path->narrow, mode);
8689 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008690#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008691 result = mkfifo(path->narrow, mode);
8692 Py_END_ALLOW_THREADS
8693 } while (result != 0 && errno == EINTR &&
8694 !(async_err = PyErr_CheckSignals()));
8695 if (result != 0)
8696 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008697
8698 Py_RETURN_NONE;
8699}
8700#endif /* HAVE_MKFIFO */
8701
8702
8703#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8704/*[clinic input]
8705os.mknod
8706
8707 path: path_t
8708 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008709 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008710 *
8711 dir_fd: dir_fd(requires='mknodat')=None
8712
8713Create a node in the file system.
8714
8715Create a node in the file system (file, device special file or named pipe)
8716at path. mode specifies both the permissions to use and the
8717type of node to be created, being combined (bitwise OR) with one of
8718S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8719device defines the newly created device special file (probably using
8720os.makedev()). Otherwise device is ignored.
8721
8722If dir_fd is not None, it should be a file descriptor open to a directory,
8723 and path should be relative; path will then be relative to that directory.
8724dir_fd may not be implemented on your platform.
8725 If it is unavailable, using it will raise a NotImplementedError.
8726[clinic start generated code]*/
8727
Larry Hastings2f936352014-08-05 14:04:04 +10008728static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008729os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
8730 int dir_fd)
8731/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008732{
8733 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008734 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008735
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008736 do {
8737 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008738#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008739 if (dir_fd != DEFAULT_DIR_FD)
8740 result = mknodat(dir_fd, path->narrow, mode, device);
8741 else
Larry Hastings2f936352014-08-05 14:04:04 +10008742#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008743 result = mknod(path->narrow, mode, device);
8744 Py_END_ALLOW_THREADS
8745 } while (result != 0 && errno == EINTR &&
8746 !(async_err = PyErr_CheckSignals()));
8747 if (result != 0)
8748 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008749
8750 Py_RETURN_NONE;
8751}
8752#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8753
8754
8755#ifdef HAVE_DEVICE_MACROS
8756/*[clinic input]
8757os.major -> unsigned_int
8758
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008759 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008760 /
8761
8762Extracts a device major number from a raw device number.
8763[clinic start generated code]*/
8764
Larry Hastings2f936352014-08-05 14:04:04 +10008765static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008766os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008767/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008768{
8769 return major(device);
8770}
8771
8772
8773/*[clinic input]
8774os.minor -> unsigned_int
8775
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008776 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008777 /
8778
8779Extracts a device minor number from a raw device number.
8780[clinic start generated code]*/
8781
Larry Hastings2f936352014-08-05 14:04:04 +10008782static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008783os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008784/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008785{
8786 return minor(device);
8787}
8788
8789
8790/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008791os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008792
8793 major: int
8794 minor: int
8795 /
8796
8797Composes a raw device number from the major and minor device numbers.
8798[clinic start generated code]*/
8799
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008800static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008801os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008802/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008803{
8804 return makedev(major, minor);
8805}
8806#endif /* HAVE_DEVICE_MACROS */
8807
8808
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008809#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008810/*[clinic input]
8811os.ftruncate
8812
8813 fd: int
8814 length: Py_off_t
8815 /
8816
8817Truncate a file, specified by file descriptor, to a specific length.
8818[clinic start generated code]*/
8819
Larry Hastings2f936352014-08-05 14:04:04 +10008820static PyObject *
8821os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008822/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008823{
8824 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008825 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008826
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008827 if (!_PyVerify_fd(fd))
8828 return posix_error();
8829
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008830 do {
8831 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008832 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008833#ifdef MS_WINDOWS
8834 result = _chsize_s(fd, length);
8835#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008836 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008837#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008838 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008839 Py_END_ALLOW_THREADS
8840 } while (result != 0 && errno == EINTR &&
8841 !(async_err = PyErr_CheckSignals()));
8842 if (result != 0)
8843 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008844 Py_RETURN_NONE;
8845}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008846#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008847
8848
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008849#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008850/*[clinic input]
8851os.truncate
8852 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8853 length: Py_off_t
8854
8855Truncate a file, specified by path, to a specific length.
8856
8857On some platforms, path may also be specified as an open file descriptor.
8858 If this functionality is unavailable, using it raises an exception.
8859[clinic start generated code]*/
8860
Larry Hastings2f936352014-08-05 14:04:04 +10008861static PyObject *
8862os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008863/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008864{
8865 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008866#ifdef MS_WINDOWS
8867 int fd;
8868#endif
8869
8870 if (path->fd != -1)
8871 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008872
8873 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008874 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008875#ifdef MS_WINDOWS
8876 if (path->wide)
8877 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008878 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008879 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008880 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008881 result = -1;
8882 else {
8883 result = _chsize_s(fd, length);
8884 close(fd);
8885 if (result < 0)
8886 errno = result;
8887 }
8888#else
8889 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008890#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008891 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008892 Py_END_ALLOW_THREADS
8893 if (result < 0)
8894 return path_error(path);
8895
8896 Py_RETURN_NONE;
8897}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008898#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008899
Ross Lagerwall7807c352011-03-17 20:20:30 +02008900
Victor Stinnerd6b17692014-09-30 12:20:05 +02008901/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8902 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8903 defined, which is the case in Python on AIX. AIX bug report:
8904 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8905#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8906# define POSIX_FADVISE_AIX_BUG
8907#endif
8908
Victor Stinnerec39e262014-09-30 12:35:58 +02008909
Victor Stinnerd6b17692014-09-30 12:20:05 +02008910#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008911/*[clinic input]
8912os.posix_fallocate
8913
8914 fd: int
8915 offset: Py_off_t
8916 length: Py_off_t
8917 /
8918
8919Ensure a file has allocated at least a particular number of bytes on disk.
8920
8921Ensure that the file specified by fd encompasses a range of bytes
8922starting at offset bytes from the beginning and continuing for length bytes.
8923[clinic start generated code]*/
8924
Larry Hastings2f936352014-08-05 14:04:04 +10008925static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008926os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset,
8927 Py_off_t length)
8928/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008929{
8930 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008931 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008932
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008933 do {
8934 Py_BEGIN_ALLOW_THREADS
8935 result = posix_fallocate(fd, offset, length);
8936 Py_END_ALLOW_THREADS
8937 } while (result != 0 && errno == EINTR &&
8938 !(async_err = PyErr_CheckSignals()));
8939 if (result != 0)
8940 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008941 Py_RETURN_NONE;
8942}
Victor Stinnerec39e262014-09-30 12:35:58 +02008943#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008944
Ross Lagerwall7807c352011-03-17 20:20:30 +02008945
Victor Stinnerd6b17692014-09-30 12:20:05 +02008946#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008947/*[clinic input]
8948os.posix_fadvise
8949
8950 fd: int
8951 offset: Py_off_t
8952 length: Py_off_t
8953 advice: int
8954 /
8955
8956Announce an intention to access data in a specific pattern.
8957
8958Announce an intention to access data in a specific pattern, thus allowing
8959the kernel to make optimizations.
8960The advice applies to the region of the file specified by fd starting at
8961offset and continuing for length bytes.
8962advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8963POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8964POSIX_FADV_DONTNEED.
8965[clinic start generated code]*/
8966
Larry Hastings2f936352014-08-05 14:04:04 +10008967static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008968os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset,
8969 Py_off_t length, int advice)
8970/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008971{
8972 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008973 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008974
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008975 do {
8976 Py_BEGIN_ALLOW_THREADS
8977 result = posix_fadvise(fd, offset, length, advice);
8978 Py_END_ALLOW_THREADS
8979 } while (result != 0 && errno == EINTR &&
8980 !(async_err = PyErr_CheckSignals()));
8981 if (result != 0)
8982 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008983 Py_RETURN_NONE;
8984}
Victor Stinnerec39e262014-09-30 12:35:58 +02008985#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008986
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008987#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008988
Fred Drake762e2061999-08-26 17:23:54 +00008989/* Save putenv() parameters as values here, so we can collect them when they
8990 * get re-set with another call for the same key. */
8991static PyObject *posix_putenv_garbage;
8992
Larry Hastings2f936352014-08-05 14:04:04 +10008993static void
8994posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008995{
Larry Hastings2f936352014-08-05 14:04:04 +10008996 /* Install the first arg and newstr in posix_putenv_garbage;
8997 * this will cause previous value to be collected. This has to
8998 * happen after the real putenv() call because the old value
8999 * was still accessible until then. */
9000 if (PyDict_SetItem(posix_putenv_garbage, name, value))
9001 /* really not much we can do; just leak */
9002 PyErr_Clear();
9003 else
9004 Py_DECREF(value);
9005}
9006
9007
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009008#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009009/*[clinic input]
9010os.putenv
9011
9012 name: unicode
9013 value: unicode
9014 /
9015
9016Change or add an environment variable.
9017[clinic start generated code]*/
9018
Larry Hastings2f936352014-08-05 14:04:04 +10009019static PyObject *
9020os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009021/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009022{
9023 wchar_t *env;
9024
9025 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9026 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009027 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009028 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009029 }
Larry Hastings2f936352014-08-05 14:04:04 +10009030 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009031 PyErr_Format(PyExc_ValueError,
9032 "the environment variable is longer than %u characters",
9033 _MAX_ENV);
9034 goto error;
9035 }
9036
Larry Hastings2f936352014-08-05 14:04:04 +10009037 env = PyUnicode_AsUnicode(unicode);
9038 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009039 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009040 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009041 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009042 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009043 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009044
Larry Hastings2f936352014-08-05 14:04:04 +10009045 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009046 Py_RETURN_NONE;
9047
9048error:
Larry Hastings2f936352014-08-05 14:04:04 +10009049 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009050 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009051}
Larry Hastings2f936352014-08-05 14:04:04 +10009052#else /* MS_WINDOWS */
9053/*[clinic input]
9054os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009055
Larry Hastings2f936352014-08-05 14:04:04 +10009056 name: FSConverter
9057 value: FSConverter
9058 /
9059
9060Change or add an environment variable.
9061[clinic start generated code]*/
9062
Larry Hastings2f936352014-08-05 14:04:04 +10009063static PyObject *
9064os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009065/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009066{
9067 PyObject *bytes = NULL;
9068 char *env;
9069 char *name_string = PyBytes_AsString(name);
9070 char *value_string = PyBytes_AsString(value);
9071
9072 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9073 if (bytes == NULL) {
9074 PyErr_NoMemory();
9075 return NULL;
9076 }
9077
9078 env = PyBytes_AS_STRING(bytes);
9079 if (putenv(env)) {
9080 Py_DECREF(bytes);
9081 return posix_error();
9082 }
9083
9084 posix_putenv_garbage_setitem(name, bytes);
9085 Py_RETURN_NONE;
9086}
9087#endif /* MS_WINDOWS */
9088#endif /* HAVE_PUTENV */
9089
9090
9091#ifdef HAVE_UNSETENV
9092/*[clinic input]
9093os.unsetenv
9094 name: FSConverter
9095 /
9096
9097Delete an environment variable.
9098[clinic start generated code]*/
9099
Larry Hastings2f936352014-08-05 14:04:04 +10009100static PyObject *
9101os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009102/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009103{
Victor Stinner984890f2011-11-24 13:53:38 +01009104#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009105 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009106#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009107
Victor Stinner984890f2011-11-24 13:53:38 +01009108#ifdef HAVE_BROKEN_UNSETENV
9109 unsetenv(PyBytes_AS_STRING(name));
9110#else
Victor Stinner65170952011-11-22 22:16:17 +01009111 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009112 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009113 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009114#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009115
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 /* Remove the key from posix_putenv_garbage;
9117 * this will cause it to be collected. This has to
9118 * happen after the real unsetenv() call because the
9119 * old value was still accessible until then.
9120 */
Victor Stinner65170952011-11-22 22:16:17 +01009121 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009122 /* really not much we can do; just leak */
9123 PyErr_Clear();
9124 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009125 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009126}
Larry Hastings2f936352014-08-05 14:04:04 +10009127#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009128
Larry Hastings2f936352014-08-05 14:04:04 +10009129
9130/*[clinic input]
9131os.strerror
9132
9133 code: int
9134 /
9135
9136Translate an error code to a message string.
9137[clinic start generated code]*/
9138
Larry Hastings2f936352014-08-05 14:04:04 +10009139static PyObject *
9140os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009141/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009142{
9143 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009144 if (message == NULL) {
9145 PyErr_SetString(PyExc_ValueError,
9146 "strerror() argument out of range");
9147 return NULL;
9148 }
Victor Stinner1b579672011-12-17 05:47:23 +01009149 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009150}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009151
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009152
Guido van Rossumc9641791998-08-04 15:26:23 +00009153#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009154#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009155/*[clinic input]
9156os.WCOREDUMP -> bool
9157
9158 status: int
9159 /
9160
9161Return True if the process returning status was dumped to a core file.
9162[clinic start generated code]*/
9163
Larry Hastings2f936352014-08-05 14:04:04 +10009164static int
9165os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009166/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009167{
9168 WAIT_TYPE wait_status;
9169 WAIT_STATUS_INT(wait_status) = status;
9170 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009171}
9172#endif /* WCOREDUMP */
9173
Larry Hastings2f936352014-08-05 14:04:04 +10009174
Fred Drake106c1a02002-04-23 15:58:02 +00009175#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009176/*[clinic input]
9177os.WIFCONTINUED -> bool
9178
9179 status: int
9180
9181Return True if a particular process was continued from a job control stop.
9182
9183Return True if the process returning status was continued from a
9184job control stop.
9185[clinic start generated code]*/
9186
Larry Hastings2f936352014-08-05 14:04:04 +10009187static int
9188os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009189/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009190{
9191 WAIT_TYPE wait_status;
9192 WAIT_STATUS_INT(wait_status) = status;
9193 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009194}
9195#endif /* WIFCONTINUED */
9196
Larry Hastings2f936352014-08-05 14:04:04 +10009197
Guido van Rossumc9641791998-08-04 15:26:23 +00009198#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009199/*[clinic input]
9200os.WIFSTOPPED -> bool
9201
9202 status: int
9203
9204Return True if the process returning status was stopped.
9205[clinic start generated code]*/
9206
Larry Hastings2f936352014-08-05 14:04:04 +10009207static int
9208os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009209/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009210{
9211 WAIT_TYPE wait_status;
9212 WAIT_STATUS_INT(wait_status) = status;
9213 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009214}
9215#endif /* WIFSTOPPED */
9216
Larry Hastings2f936352014-08-05 14:04:04 +10009217
Guido van Rossumc9641791998-08-04 15:26:23 +00009218#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009219/*[clinic input]
9220os.WIFSIGNALED -> bool
9221
9222 status: int
9223
9224Return True if the process returning status was terminated by a signal.
9225[clinic start generated code]*/
9226
Larry Hastings2f936352014-08-05 14:04:04 +10009227static int
9228os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009229/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009230{
9231 WAIT_TYPE wait_status;
9232 WAIT_STATUS_INT(wait_status) = status;
9233 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009234}
9235#endif /* WIFSIGNALED */
9236
Larry Hastings2f936352014-08-05 14:04:04 +10009237
Guido van Rossumc9641791998-08-04 15:26:23 +00009238#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009239/*[clinic input]
9240os.WIFEXITED -> bool
9241
9242 status: int
9243
9244Return True if the process returning status exited via the exit() system call.
9245[clinic start generated code]*/
9246
Larry Hastings2f936352014-08-05 14:04:04 +10009247static int
9248os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009249/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009250{
9251 WAIT_TYPE wait_status;
9252 WAIT_STATUS_INT(wait_status) = status;
9253 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009254}
9255#endif /* WIFEXITED */
9256
Larry Hastings2f936352014-08-05 14:04:04 +10009257
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009258#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009259/*[clinic input]
9260os.WEXITSTATUS -> int
9261
9262 status: int
9263
9264Return the process return code from status.
9265[clinic start generated code]*/
9266
Larry Hastings2f936352014-08-05 14:04:04 +10009267static int
9268os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009269/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009270{
9271 WAIT_TYPE wait_status;
9272 WAIT_STATUS_INT(wait_status) = status;
9273 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009274}
9275#endif /* WEXITSTATUS */
9276
Larry Hastings2f936352014-08-05 14:04:04 +10009277
Guido van Rossumc9641791998-08-04 15:26:23 +00009278#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009279/*[clinic input]
9280os.WTERMSIG -> int
9281
9282 status: int
9283
9284Return the signal that terminated the process that provided the status value.
9285[clinic start generated code]*/
9286
Larry Hastings2f936352014-08-05 14:04:04 +10009287static int
9288os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009289/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009290{
9291 WAIT_TYPE wait_status;
9292 WAIT_STATUS_INT(wait_status) = status;
9293 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009294}
9295#endif /* WTERMSIG */
9296
Larry Hastings2f936352014-08-05 14:04:04 +10009297
Guido van Rossumc9641791998-08-04 15:26:23 +00009298#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009299/*[clinic input]
9300os.WSTOPSIG -> int
9301
9302 status: int
9303
9304Return the signal that stopped the process that provided the status value.
9305[clinic start generated code]*/
9306
Larry Hastings2f936352014-08-05 14:04:04 +10009307static int
9308os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009309/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009310{
9311 WAIT_TYPE wait_status;
9312 WAIT_STATUS_INT(wait_status) = status;
9313 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009314}
9315#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009316#endif /* HAVE_SYS_WAIT_H */
9317
9318
Thomas Wouters477c8d52006-05-27 19:21:47 +00009319#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009320#ifdef _SCO_DS
9321/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9322 needed definitions in sys/statvfs.h */
9323#define _SVID3
9324#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009325#include <sys/statvfs.h>
9326
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009327static PyObject*
9328_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9330 if (v == NULL)
9331 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009332
9333#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009334 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9335 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9336 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9337 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9338 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9339 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9340 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9341 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9342 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9343 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009344#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009345 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9346 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9347 PyStructSequence_SET_ITEM(v, 2,
9348 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9349 PyStructSequence_SET_ITEM(v, 3,
9350 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9351 PyStructSequence_SET_ITEM(v, 4,
9352 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9353 PyStructSequence_SET_ITEM(v, 5,
9354 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9355 PyStructSequence_SET_ITEM(v, 6,
9356 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9357 PyStructSequence_SET_ITEM(v, 7,
9358 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9359 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9360 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009361#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009362 if (PyErr_Occurred()) {
9363 Py_DECREF(v);
9364 return NULL;
9365 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009366
Victor Stinner8c62be82010-05-06 00:08:46 +00009367 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009368}
9369
Larry Hastings2f936352014-08-05 14:04:04 +10009370
9371/*[clinic input]
9372os.fstatvfs
9373 fd: int
9374 /
9375
9376Perform an fstatvfs system call on the given fd.
9377
9378Equivalent to statvfs(fd).
9379[clinic start generated code]*/
9380
Larry Hastings2f936352014-08-05 14:04:04 +10009381static PyObject *
9382os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009383/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009384{
9385 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009386 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009387 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009388
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009389 do {
9390 Py_BEGIN_ALLOW_THREADS
9391 result = fstatvfs(fd, &st);
9392 Py_END_ALLOW_THREADS
9393 } while (result != 0 && errno == EINTR &&
9394 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009395 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009396 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009397
Victor Stinner8c62be82010-05-06 00:08:46 +00009398 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009399}
Larry Hastings2f936352014-08-05 14:04:04 +10009400#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009401
9402
Thomas Wouters477c8d52006-05-27 19:21:47 +00009403#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009404#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009405/*[clinic input]
9406os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009407
Larry Hastings2f936352014-08-05 14:04:04 +10009408 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9409
9410Perform a statvfs system call on the given path.
9411
9412path may always be specified as a string.
9413On some platforms, path may also be specified as an open file descriptor.
9414 If this functionality is unavailable, using it raises an exception.
9415[clinic start generated code]*/
9416
Larry Hastings2f936352014-08-05 14:04:04 +10009417static PyObject *
9418os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009419/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009420{
9421 int result;
9422 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009423
9424 Py_BEGIN_ALLOW_THREADS
9425#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009426 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009427#ifdef __APPLE__
9428 /* handle weak-linking on Mac OS X 10.3 */
9429 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009430 fd_specified("statvfs", path->fd);
9431 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009432 }
9433#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009434 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009435 }
9436 else
9437#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009438 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009439 Py_END_ALLOW_THREADS
9440
9441 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009442 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009443 }
9444
Larry Hastings2f936352014-08-05 14:04:04 +10009445 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009446}
Larry Hastings2f936352014-08-05 14:04:04 +10009447#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9448
Guido van Rossum94f6f721999-01-06 18:42:14 +00009449
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009450#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009451/*[clinic input]
9452os._getdiskusage
9453
9454 path: Py_UNICODE
9455
9456Return disk usage statistics about the given path as a (total, free) tuple.
9457[clinic start generated code]*/
9458
Larry Hastings2f936352014-08-05 14:04:04 +10009459static PyObject *
9460os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009461/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009462{
9463 BOOL retval;
9464 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009465
9466 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009467 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009468 Py_END_ALLOW_THREADS
9469 if (retval == 0)
9470 return PyErr_SetFromWindowsErr(0);
9471
9472 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9473}
Larry Hastings2f936352014-08-05 14:04:04 +10009474#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009475
9476
Fred Drakec9680921999-12-13 16:37:25 +00009477/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9478 * It maps strings representing configuration variable names to
9479 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009480 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009481 * rarely-used constants. There are three separate tables that use
9482 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009483 *
9484 * This code is always included, even if none of the interfaces that
9485 * need it are included. The #if hackery needed to avoid it would be
9486 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009487 */
9488struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009489 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009490 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009491};
9492
Fred Drake12c6e2d1999-12-14 21:25:03 +00009493static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009494conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009495 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009496{
Christian Heimes217cfd12007-12-02 14:31:20 +00009497 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009498 int value = _PyLong_AsInt(arg);
9499 if (value == -1 && PyErr_Occurred())
9500 return 0;
9501 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009502 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009503 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009504 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009505 /* look up the value in the table using a binary search */
9506 size_t lo = 0;
9507 size_t mid;
9508 size_t hi = tablesize;
9509 int cmp;
9510 const char *confname;
9511 if (!PyUnicode_Check(arg)) {
9512 PyErr_SetString(PyExc_TypeError,
9513 "configuration names must be strings or integers");
9514 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009516 confname = _PyUnicode_AsString(arg);
9517 if (confname == NULL)
9518 return 0;
9519 while (lo < hi) {
9520 mid = (lo + hi) / 2;
9521 cmp = strcmp(confname, table[mid].name);
9522 if (cmp < 0)
9523 hi = mid;
9524 else if (cmp > 0)
9525 lo = mid + 1;
9526 else {
9527 *valuep = table[mid].value;
9528 return 1;
9529 }
9530 }
9531 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9532 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009534}
9535
9536
9537#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9538static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009539#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009540 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009541#endif
9542#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009543 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009544#endif
Fred Drakec9680921999-12-13 16:37:25 +00009545#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009546 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009547#endif
9548#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009549 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009550#endif
9551#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009552 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009553#endif
9554#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009555 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009556#endif
9557#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009558 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009559#endif
9560#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009561 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009562#endif
9563#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009564 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009565#endif
9566#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009567 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009568#endif
9569#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009570 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009571#endif
9572#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009573 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009574#endif
9575#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009576 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009577#endif
9578#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009579 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009580#endif
9581#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009582 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009583#endif
9584#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009585 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009586#endif
9587#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009588 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009589#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009590#ifdef _PC_ACL_ENABLED
9591 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9592#endif
9593#ifdef _PC_MIN_HOLE_SIZE
9594 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9595#endif
9596#ifdef _PC_ALLOC_SIZE_MIN
9597 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9598#endif
9599#ifdef _PC_REC_INCR_XFER_SIZE
9600 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9601#endif
9602#ifdef _PC_REC_MAX_XFER_SIZE
9603 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9604#endif
9605#ifdef _PC_REC_MIN_XFER_SIZE
9606 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9607#endif
9608#ifdef _PC_REC_XFER_ALIGN
9609 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9610#endif
9611#ifdef _PC_SYMLINK_MAX
9612 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9613#endif
9614#ifdef _PC_XATTR_ENABLED
9615 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9616#endif
9617#ifdef _PC_XATTR_EXISTS
9618 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9619#endif
9620#ifdef _PC_TIMESTAMP_RESOLUTION
9621 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9622#endif
Fred Drakec9680921999-12-13 16:37:25 +00009623};
9624
Fred Drakec9680921999-12-13 16:37:25 +00009625static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009626conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009627{
9628 return conv_confname(arg, valuep, posix_constants_pathconf,
9629 sizeof(posix_constants_pathconf)
9630 / sizeof(struct constdef));
9631}
9632#endif
9633
Larry Hastings2f936352014-08-05 14:04:04 +10009634
Fred Drakec9680921999-12-13 16:37:25 +00009635#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009636/*[clinic input]
9637os.fpathconf -> long
9638
9639 fd: int
9640 name: path_confname
9641 /
9642
9643Return the configuration limit name for the file descriptor fd.
9644
9645If there is no limit, return -1.
9646[clinic start generated code]*/
9647
Larry Hastings2f936352014-08-05 14:04:04 +10009648static long
9649os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009650/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009651{
9652 long limit;
9653
9654 errno = 0;
9655 limit = fpathconf(fd, name);
9656 if (limit == -1 && errno != 0)
9657 posix_error();
9658
9659 return limit;
9660}
9661#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009662
9663
9664#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009665/*[clinic input]
9666os.pathconf -> long
9667 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9668 name: path_confname
9669
9670Return the configuration limit name for the file or directory path.
9671
9672If there is no limit, return -1.
9673On some platforms, path may also be specified as an open file descriptor.
9674 If this functionality is unavailable, using it raises an exception.
9675[clinic start generated code]*/
9676
Larry Hastings2f936352014-08-05 14:04:04 +10009677static long
9678os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009679/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009680{
Victor Stinner8c62be82010-05-06 00:08:46 +00009681 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009682
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009684#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009685 if (path->fd != -1)
9686 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009687 else
9688#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009689 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009690 if (limit == -1 && errno != 0) {
9691 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009692 /* could be a path or name problem */
9693 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009694 else
Larry Hastings2f936352014-08-05 14:04:04 +10009695 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009696 }
Larry Hastings2f936352014-08-05 14:04:04 +10009697
9698 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009699}
Larry Hastings2f936352014-08-05 14:04:04 +10009700#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009701
9702#ifdef HAVE_CONFSTR
9703static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009704#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009705 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009706#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009707#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009708 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009709#endif
9710#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009711 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009712#endif
Fred Draked86ed291999-12-15 15:34:33 +00009713#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009714 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009715#endif
9716#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009717 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009718#endif
9719#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009720 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009721#endif
9722#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009723 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009724#endif
Fred Drakec9680921999-12-13 16:37:25 +00009725#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009726 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009727#endif
9728#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009729 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009730#endif
9731#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009732 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009733#endif
9734#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009735 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009736#endif
9737#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009738 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009739#endif
9740#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009741 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009742#endif
9743#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009744 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009745#endif
9746#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009747 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009748#endif
Fred Draked86ed291999-12-15 15:34:33 +00009749#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009750 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009751#endif
Fred Drakec9680921999-12-13 16:37:25 +00009752#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009753 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009754#endif
Fred Draked86ed291999-12-15 15:34:33 +00009755#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009756 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009757#endif
9758#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009759 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009760#endif
9761#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009762 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009763#endif
9764#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009765 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009766#endif
Fred Drakec9680921999-12-13 16:37:25 +00009767#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009768 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009769#endif
9770#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009771 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009772#endif
9773#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009774 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009775#endif
9776#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009777 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009778#endif
9779#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009780 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009781#endif
9782#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009783 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009784#endif
9785#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009786 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009787#endif
9788#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009789 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009790#endif
9791#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009792 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009793#endif
9794#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009795 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009796#endif
9797#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009798 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009799#endif
9800#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009801 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009802#endif
9803#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009804 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009805#endif
9806#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009807 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009808#endif
9809#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009810 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009811#endif
9812#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009813 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009814#endif
Fred Draked86ed291999-12-15 15:34:33 +00009815#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009816 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009817#endif
9818#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009819 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009820#endif
9821#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009822 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009823#endif
9824#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009825 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009826#endif
9827#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009828 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009829#endif
9830#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009831 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009832#endif
9833#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009834 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009835#endif
9836#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009837 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009838#endif
9839#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009840 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009841#endif
9842#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009843 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009844#endif
9845#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009846 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009847#endif
9848#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009849 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009850#endif
9851#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009852 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009853#endif
Fred Drakec9680921999-12-13 16:37:25 +00009854};
9855
9856static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009857conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009858{
9859 return conv_confname(arg, valuep, posix_constants_confstr,
9860 sizeof(posix_constants_confstr)
9861 / sizeof(struct constdef));
9862}
9863
Larry Hastings2f936352014-08-05 14:04:04 +10009864
9865/*[clinic input]
9866os.confstr
9867
9868 name: confstr_confname
9869 /
9870
9871Return a string-valued system configuration variable.
9872[clinic start generated code]*/
9873
Larry Hastings2f936352014-08-05 14:04:04 +10009874static PyObject *
9875os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009876/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009877{
9878 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009879 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009880 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009881
Victor Stinnercb043522010-09-10 23:49:04 +00009882 errno = 0;
9883 len = confstr(name, buffer, sizeof(buffer));
9884 if (len == 0) {
9885 if (errno) {
9886 posix_error();
9887 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009888 }
9889 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009890 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009891 }
9892 }
Victor Stinnercb043522010-09-10 23:49:04 +00009893
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009894 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009895 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009896 char *buf = PyMem_Malloc(len);
9897 if (buf == NULL)
9898 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009899 len2 = confstr(name, buf, len);
9900 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009901 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009902 PyMem_Free(buf);
9903 }
9904 else
9905 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009906 return result;
9907}
Larry Hastings2f936352014-08-05 14:04:04 +10009908#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009909
9910
9911#ifdef HAVE_SYSCONF
9912static struct constdef posix_constants_sysconf[] = {
9913#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009914 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009915#endif
9916#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009917 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009918#endif
9919#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009920 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009921#endif
9922#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009923 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009924#endif
9925#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009926 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009927#endif
9928#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009929 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009930#endif
9931#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009932 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009933#endif
9934#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009935 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009936#endif
9937#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009938 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009939#endif
9940#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009941 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009942#endif
Fred Draked86ed291999-12-15 15:34:33 +00009943#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009944 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009945#endif
9946#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009947 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009948#endif
Fred Drakec9680921999-12-13 16:37:25 +00009949#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009950 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009951#endif
Fred Drakec9680921999-12-13 16:37:25 +00009952#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009953 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009954#endif
9955#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009956 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009957#endif
9958#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009959 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009960#endif
9961#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009962 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009963#endif
9964#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009965 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009966#endif
Fred Draked86ed291999-12-15 15:34:33 +00009967#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009968 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009969#endif
Fred Drakec9680921999-12-13 16:37:25 +00009970#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009971 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009972#endif
9973#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009974 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009975#endif
9976#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009977 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009978#endif
9979#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009980 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009981#endif
9982#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009983 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009984#endif
Fred Draked86ed291999-12-15 15:34:33 +00009985#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009986 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009987#endif
Fred Drakec9680921999-12-13 16:37:25 +00009988#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009989 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009990#endif
9991#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009992 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009993#endif
9994#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009995 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009996#endif
9997#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009998 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009999#endif
10000#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010001 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010002#endif
10003#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010004 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +000010005#endif
10006#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010007 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010008#endif
10009#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010010 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010011#endif
10012#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010013 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010014#endif
10015#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010016 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010017#endif
10018#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010019 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010020#endif
10021#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010022 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010023#endif
10024#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010025 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010026#endif
10027#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010028 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010029#endif
10030#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010031 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010032#endif
10033#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010034 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010035#endif
10036#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010037 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010038#endif
10039#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010040 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010041#endif
10042#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010043 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010044#endif
10045#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010046 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010047#endif
10048#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010049 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010050#endif
10051#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010052 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010053#endif
10054#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010055 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010056#endif
Fred Draked86ed291999-12-15 15:34:33 +000010057#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010058 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010059#endif
Fred Drakec9680921999-12-13 16:37:25 +000010060#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010061 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010062#endif
10063#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010064 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010065#endif
10066#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010067 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010068#endif
Fred Draked86ed291999-12-15 15:34:33 +000010069#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010070 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010071#endif
Fred Drakec9680921999-12-13 16:37:25 +000010072#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010073 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010074#endif
Fred Draked86ed291999-12-15 15:34:33 +000010075#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010076 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010077#endif
10078#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010079 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010080#endif
Fred Drakec9680921999-12-13 16:37:25 +000010081#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010082 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010083#endif
10084#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010085 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010086#endif
10087#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010088 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010089#endif
10090#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010091 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010092#endif
Fred Draked86ed291999-12-15 15:34:33 +000010093#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010094 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010095#endif
Fred Drakec9680921999-12-13 16:37:25 +000010096#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010097 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010098#endif
10099#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010100 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010101#endif
10102#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010103 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010104#endif
10105#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010106 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010107#endif
10108#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010109 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010110#endif
10111#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010112 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010113#endif
10114#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010115 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010116#endif
Fred Draked86ed291999-12-15 15:34:33 +000010117#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010118 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010119#endif
Fred Drakec9680921999-12-13 16:37:25 +000010120#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010121 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010122#endif
10123#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010124 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010125#endif
Fred Draked86ed291999-12-15 15:34:33 +000010126#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010127 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010128#endif
Fred Drakec9680921999-12-13 16:37:25 +000010129#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010130 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010131#endif
10132#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010133 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010134#endif
10135#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010136 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010137#endif
10138#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010139 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010140#endif
10141#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010142 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010143#endif
10144#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010145 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010146#endif
10147#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010148 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010149#endif
10150#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010151 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010152#endif
10153#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010154 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010155#endif
Fred Draked86ed291999-12-15 15:34:33 +000010156#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010157 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010158#endif
10159#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010160 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010161#endif
Fred Drakec9680921999-12-13 16:37:25 +000010162#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010163 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010164#endif
10165#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010166 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010167#endif
10168#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010169 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010170#endif
10171#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010172 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010173#endif
10174#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010175 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010176#endif
10177#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010178 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010179#endif
10180#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010181 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010182#endif
10183#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010184 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010185#endif
10186#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010187 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010188#endif
10189#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010190 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010191#endif
10192#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010193 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010194#endif
10195#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010196 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010197#endif
10198#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010199 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010200#endif
10201#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010202 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010203#endif
10204#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010205 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010206#endif
10207#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010208 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010209#endif
10210#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010211 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010212#endif
10213#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010214 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010215#endif
10216#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010217 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010218#endif
10219#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010220 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010221#endif
10222#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010223 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010224#endif
10225#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010226 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010227#endif
10228#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010229 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010230#endif
10231#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010232 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010233#endif
10234#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010235 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010236#endif
10237#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010238 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010239#endif
10240#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010241 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010242#endif
10243#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010244 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010245#endif
10246#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010247 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010248#endif
10249#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010250 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010251#endif
10252#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010253 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010254#endif
10255#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010256 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010257#endif
10258#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010259 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010260#endif
10261#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010262 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010263#endif
10264#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010265 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010266#endif
Fred Draked86ed291999-12-15 15:34:33 +000010267#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010268 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010269#endif
Fred Drakec9680921999-12-13 16:37:25 +000010270#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010271 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010272#endif
10273#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010274 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010275#endif
10276#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010277 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010278#endif
10279#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010280 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010281#endif
10282#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010283 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010284#endif
10285#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010286 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010287#endif
10288#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010289 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010290#endif
10291#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010292 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010293#endif
10294#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010295 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010296#endif
10297#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010298 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010299#endif
10300#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010301 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010302#endif
10303#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010304 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010305#endif
10306#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010307 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010308#endif
10309#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010310 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010311#endif
10312#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010313 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010314#endif
10315#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010316 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010317#endif
10318#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010319 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010320#endif
10321#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010322 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010323#endif
10324#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010325 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010326#endif
10327#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010328 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010329#endif
10330#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010331 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010332#endif
10333#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010334 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010335#endif
10336#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010337 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010338#endif
10339#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010340 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010341#endif
10342#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010343 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010344#endif
10345#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010346 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010347#endif
10348#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010349 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010350#endif
10351#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010352 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010353#endif
10354#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010355 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010356#endif
10357#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010358 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010359#endif
10360#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010361 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010362#endif
10363#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010364 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010365#endif
10366#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010367 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010368#endif
10369#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010370 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010371#endif
10372#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010373 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010374#endif
10375#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010376 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010377#endif
10378#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010379 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010380#endif
10381#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010382 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010383#endif
10384#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010385 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010386#endif
10387#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010388 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010389#endif
10390#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010391 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010392#endif
10393#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010394 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010395#endif
10396#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010397 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010398#endif
10399#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010400 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010401#endif
10402#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010403 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010404#endif
10405};
10406
10407static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010408conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010409{
10410 return conv_confname(arg, valuep, posix_constants_sysconf,
10411 sizeof(posix_constants_sysconf)
10412 / sizeof(struct constdef));
10413}
10414
Larry Hastings2f936352014-08-05 14:04:04 +100010415
10416/*[clinic input]
10417os.sysconf -> long
10418 name: sysconf_confname
10419 /
10420
10421Return an integer-valued system configuration variable.
10422[clinic start generated code]*/
10423
Larry Hastings2f936352014-08-05 14:04:04 +100010424static long
10425os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010426/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010427{
10428 long value;
10429
10430 errno = 0;
10431 value = sysconf(name);
10432 if (value == -1 && errno != 0)
10433 posix_error();
10434 return value;
10435}
10436#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010437
10438
Fred Drakebec628d1999-12-15 18:31:10 +000010439/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010440 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010441 * the exported dictionaries that are used to publish information about the
10442 * names available on the host platform.
10443 *
10444 * Sorting the table at runtime ensures that the table is properly ordered
10445 * when used, even for platforms we're not able to test on. It also makes
10446 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010447 */
Fred Drakebec628d1999-12-15 18:31:10 +000010448
10449static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010450cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010451{
10452 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010453 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010454 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010456
10457 return strcmp(c1->name, c2->name);
10458}
10459
10460static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010461setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010463{
Fred Drakebec628d1999-12-15 18:31:10 +000010464 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010465 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010466
10467 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10468 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010469 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010470 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010471
Barry Warsaw3155db32000-04-13 15:20:40 +000010472 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010473 PyObject *o = PyLong_FromLong(table[i].value);
10474 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10475 Py_XDECREF(o);
10476 Py_DECREF(d);
10477 return -1;
10478 }
10479 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010480 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010481 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010482}
10483
Fred Drakebec628d1999-12-15 18:31:10 +000010484/* Return -1 on failure, 0 on success. */
10485static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010486setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010487{
10488#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010489 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010490 sizeof(posix_constants_pathconf)
10491 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010492 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010493 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010494#endif
10495#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010496 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010497 sizeof(posix_constants_confstr)
10498 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010499 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010500 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010501#endif
10502#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010503 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010504 sizeof(posix_constants_sysconf)
10505 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010506 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010507 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010508#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010509 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010510}
Fred Draked86ed291999-12-15 15:34:33 +000010511
10512
Larry Hastings2f936352014-08-05 14:04:04 +100010513/*[clinic input]
10514os.abort
10515
10516Abort the interpreter immediately.
10517
10518This function 'dumps core' or otherwise fails in the hardest way possible
10519on the hosting operating system. This function never returns.
10520[clinic start generated code]*/
10521
Larry Hastings2f936352014-08-05 14:04:04 +100010522static PyObject *
10523os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010524/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010525{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010526 abort();
10527 /*NOTREACHED*/
10528 Py_FatalError("abort() called from Python code didn't abort!");
10529 return NULL;
10530}
Fred Drakebec628d1999-12-15 18:31:10 +000010531
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010532#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010533/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010534PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010535"startfile(filepath [, operation])\n\
10536\n\
10537Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010538\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010539When \"operation\" is not specified or \"open\", this acts like\n\
10540double-clicking the file in Explorer, or giving the file name as an\n\
10541argument to the DOS \"start\" command: the file is opened with whatever\n\
10542application (if any) its extension is associated.\n\
10543When another \"operation\" is given, it specifies what should be done with\n\
10544the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010545\n\
10546startfile returns as soon as the associated application is launched.\n\
10547There is no option to wait for the application to close, and no way\n\
10548to retrieve the application's exit status.\n\
10549\n\
10550The filepath is relative to the current directory. If you want to use\n\
10551an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010552the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010553
Steve Dower7d0e0c92015-01-24 08:18:24 -080010554/* Grab ShellExecute dynamically from shell32 */
10555static int has_ShellExecute = -1;
10556static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10557 LPCSTR, INT);
10558static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10559 LPCWSTR, INT);
10560static int
10561check_ShellExecute()
10562{
10563 HINSTANCE hShell32;
10564
10565 /* only recheck */
10566 if (-1 == has_ShellExecute) {
10567 Py_BEGIN_ALLOW_THREADS
10568 hShell32 = LoadLibraryW(L"SHELL32");
10569 Py_END_ALLOW_THREADS
10570 if (hShell32) {
10571 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10572 "ShellExecuteA");
10573 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10574 "ShellExecuteW");
10575 has_ShellExecute = Py_ShellExecuteA &&
10576 Py_ShellExecuteW;
10577 } else {
10578 has_ShellExecute = 0;
10579 }
10580 }
10581 return has_ShellExecute;
10582}
10583
10584
Tim Petersf58a7aa2000-09-22 10:05:54 +000010585static PyObject *
10586win32_startfile(PyObject *self, PyObject *args)
10587{
Victor Stinner8c62be82010-05-06 00:08:46 +000010588 PyObject *ofilepath;
10589 char *filepath;
10590 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010591 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010592 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010593
Victor Stinnereb5657a2011-09-30 01:44:27 +020010594 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010595
10596 if(!check_ShellExecute()) {
10597 /* If the OS doesn't have ShellExecute, return a
10598 NotImplementedError. */
10599 return PyErr_Format(PyExc_NotImplementedError,
10600 "startfile not available on this platform");
10601 }
10602
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 if (!PyArg_ParseTuple(args, "U|s:startfile",
10604 &unipath, &operation)) {
10605 PyErr_Clear();
10606 goto normal;
10607 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010608
Victor Stinner8c62be82010-05-06 00:08:46 +000010609 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010610 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010611 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010612 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 PyErr_Clear();
10614 operation = NULL;
10615 goto normal;
10616 }
10617 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010618
Victor Stinnereb5657a2011-09-30 01:44:27 +020010619 wpath = PyUnicode_AsUnicode(unipath);
10620 if (wpath == NULL)
10621 goto normal;
10622 if (uoperation) {
10623 woperation = PyUnicode_AsUnicode(uoperation);
10624 if (woperation == NULL)
10625 goto normal;
10626 }
10627 else
10628 woperation = NULL;
10629
Victor Stinner8c62be82010-05-06 00:08:46 +000010630 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010631 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10632 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010633 Py_END_ALLOW_THREADS
10634
Victor Stinnereb5657a2011-09-30 01:44:27 +020010635 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010637 win32_error_object("startfile", unipath);
10638 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010639 }
10640 Py_INCREF(Py_None);
10641 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010642
10643normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10645 PyUnicode_FSConverter, &ofilepath,
10646 &operation))
10647 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010648 if (win32_warn_bytes_api()) {
10649 Py_DECREF(ofilepath);
10650 return NULL;
10651 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010652 filepath = PyBytes_AsString(ofilepath);
10653 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010654 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10655 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010656 Py_END_ALLOW_THREADS
10657 if (rc <= (HINSTANCE)32) {
10658 PyObject *errval = win32_error("startfile", filepath);
10659 Py_DECREF(ofilepath);
10660 return errval;
10661 }
10662 Py_DECREF(ofilepath);
10663 Py_INCREF(Py_None);
10664 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010665}
Larry Hastings2f936352014-08-05 14:04:04 +100010666#endif /* MS_WINDOWS */
10667
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010668
Martin v. Löwis438b5342002-12-27 10:16:42 +000010669#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010670/*[clinic input]
10671os.getloadavg
10672
10673Return average recent system load information.
10674
10675Return the number of processes in the system run queue averaged over
10676the last 1, 5, and 15 minutes as a tuple of three floats.
10677Raises OSError if the load average was unobtainable.
10678[clinic start generated code]*/
10679
Larry Hastings2f936352014-08-05 14:04:04 +100010680static PyObject *
10681os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010682/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010683{
10684 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010685 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010686 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10687 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010688 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010689 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010690}
Larry Hastings2f936352014-08-05 14:04:04 +100010691#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010692
Larry Hastings2f936352014-08-05 14:04:04 +100010693
10694/*[clinic input]
10695os.device_encoding
10696 fd: int
10697
10698Return a string describing the encoding of a terminal's file descriptor.
10699
10700The file descriptor must be attached to a terminal.
10701If the device is not a terminal, return None.
10702[clinic start generated code]*/
10703
Larry Hastings2f936352014-08-05 14:04:04 +100010704static PyObject *
10705os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010706/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010707{
Brett Cannonefb00c02012-02-29 18:31:31 -050010708 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010709}
10710
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010711
Larry Hastings2f936352014-08-05 14:04:04 +100010712#ifdef HAVE_SETRESUID
10713/*[clinic input]
10714os.setresuid
10715
10716 ruid: uid_t
10717 euid: uid_t
10718 suid: uid_t
10719 /
10720
10721Set the current process's real, effective, and saved user ids.
10722[clinic start generated code]*/
10723
Larry Hastings2f936352014-08-05 14:04:04 +100010724static PyObject *
10725os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010726/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010727{
Victor Stinner8c62be82010-05-06 00:08:46 +000010728 if (setresuid(ruid, euid, suid) < 0)
10729 return posix_error();
10730 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010731}
Larry Hastings2f936352014-08-05 14:04:04 +100010732#endif /* HAVE_SETRESUID */
10733
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010734
10735#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010736/*[clinic input]
10737os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010738
Larry Hastings2f936352014-08-05 14:04:04 +100010739 rgid: gid_t
10740 egid: gid_t
10741 sgid: gid_t
10742 /
10743
10744Set the current process's real, effective, and saved group ids.
10745[clinic start generated code]*/
10746
Larry Hastings2f936352014-08-05 14:04:04 +100010747static PyObject *
10748os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010749/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010750{
Victor Stinner8c62be82010-05-06 00:08:46 +000010751 if (setresgid(rgid, egid, sgid) < 0)
10752 return posix_error();
10753 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010754}
Larry Hastings2f936352014-08-05 14:04:04 +100010755#endif /* HAVE_SETRESGID */
10756
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010757
10758#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010759/*[clinic input]
10760os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010761
Larry Hastings2f936352014-08-05 14:04:04 +100010762Return a tuple of the current process's real, effective, and saved user ids.
10763[clinic start generated code]*/
10764
Larry Hastings2f936352014-08-05 14:04:04 +100010765static PyObject *
10766os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010767/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010768{
Victor Stinner8c62be82010-05-06 00:08:46 +000010769 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010770 if (getresuid(&ruid, &euid, &suid) < 0)
10771 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010772 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10773 _PyLong_FromUid(euid),
10774 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010775}
Larry Hastings2f936352014-08-05 14:04:04 +100010776#endif /* HAVE_GETRESUID */
10777
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010778
10779#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010780/*[clinic input]
10781os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010782
Larry Hastings2f936352014-08-05 14:04:04 +100010783Return a tuple of the current process's real, effective, and saved group ids.
10784[clinic start generated code]*/
10785
Larry Hastings2f936352014-08-05 14:04:04 +100010786static PyObject *
10787os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010788/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010789{
10790 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010791 if (getresgid(&rgid, &egid, &sgid) < 0)
10792 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010793 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10794 _PyLong_FromGid(egid),
10795 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010796}
Larry Hastings2f936352014-08-05 14:04:04 +100010797#endif /* HAVE_GETRESGID */
10798
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010799
Benjamin Peterson9428d532011-09-14 11:45:52 -040010800#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010801/*[clinic input]
10802os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010803
Larry Hastings2f936352014-08-05 14:04:04 +100010804 path: path_t(allow_fd=True)
10805 attribute: path_t
10806 *
10807 follow_symlinks: bool = True
10808
10809Return the value of extended attribute attribute on path.
10810
10811path may be either a string or an open file descriptor.
10812If follow_symlinks is False, and the last element of the path is a symbolic
10813 link, getxattr will examine the symbolic link itself instead of the file
10814 the link points to.
10815
10816[clinic start generated code]*/
10817
Larry Hastings2f936352014-08-05 14:04:04 +100010818static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010819os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10820 int follow_symlinks)
10821/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010822{
10823 Py_ssize_t i;
10824 PyObject *buffer = NULL;
10825
10826 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10827 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010828
Larry Hastings9cf065c2012-06-22 16:30:09 -070010829 for (i = 0; ; i++) {
10830 void *ptr;
10831 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010832 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010833 Py_ssize_t buffer_size = buffer_sizes[i];
10834 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010835 path_error(path);
10836 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010837 }
10838 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10839 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010840 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010842
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010844 if (path->fd >= 0)
10845 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010846 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010847 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010848 else
Larry Hastings2f936352014-08-05 14:04:04 +100010849 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010850 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010851
Larry Hastings9cf065c2012-06-22 16:30:09 -070010852 if (result < 0) {
10853 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010854 if (errno == ERANGE)
10855 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010856 path_error(path);
10857 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010858 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 if (result != buffer_size) {
10861 /* Can only shrink. */
10862 _PyBytes_Resize(&buffer, result);
10863 }
10864 break;
10865 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010866
Larry Hastings9cf065c2012-06-22 16:30:09 -070010867 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010868}
10869
Larry Hastings2f936352014-08-05 14:04:04 +100010870
10871/*[clinic input]
10872os.setxattr
10873
10874 path: path_t(allow_fd=True)
10875 attribute: path_t
10876 value: Py_buffer
10877 flags: int = 0
10878 *
10879 follow_symlinks: bool = True
10880
10881Set extended attribute attribute on path to value.
10882
10883path may be either a string or an open file descriptor.
10884If follow_symlinks is False, and the last element of the path is a symbolic
10885 link, setxattr will modify the symbolic link itself instead of the file
10886 the link points to.
10887
10888[clinic start generated code]*/
10889
Benjamin Peterson799bd802011-08-31 22:15:17 -040010890static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010891os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10892 Py_buffer *value, int flags, int follow_symlinks)
10893/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010894{
Larry Hastings2f936352014-08-05 14:04:04 +100010895 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010896
Larry Hastings2f936352014-08-05 14:04:04 +100010897 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010898 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010899
Benjamin Peterson799bd802011-08-31 22:15:17 -040010900 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010901 if (path->fd > -1)
10902 result = fsetxattr(path->fd, attribute->narrow,
10903 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010904 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010905 result = setxattr(path->narrow, attribute->narrow,
10906 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010907 else
Larry Hastings2f936352014-08-05 14:04:04 +100010908 result = lsetxattr(path->narrow, attribute->narrow,
10909 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010910 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010911
Larry Hastings9cf065c2012-06-22 16:30:09 -070010912 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010913 path_error(path);
10914 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010915 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010916
Larry Hastings2f936352014-08-05 14:04:04 +100010917 Py_RETURN_NONE;
10918}
10919
10920
10921/*[clinic input]
10922os.removexattr
10923
10924 path: path_t(allow_fd=True)
10925 attribute: path_t
10926 *
10927 follow_symlinks: bool = True
10928
10929Remove extended attribute attribute on path.
10930
10931path may be either a string or an open file descriptor.
10932If follow_symlinks is False, and the last element of the path is a symbolic
10933 link, removexattr will modify the symbolic link itself instead of the file
10934 the link points to.
10935
10936[clinic start generated code]*/
10937
Larry Hastings2f936352014-08-05 14:04:04 +100010938static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010939os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10940 int follow_symlinks)
10941/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010942{
10943 ssize_t result;
10944
10945 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10946 return NULL;
10947
10948 Py_BEGIN_ALLOW_THREADS;
10949 if (path->fd > -1)
10950 result = fremovexattr(path->fd, attribute->narrow);
10951 else if (follow_symlinks)
10952 result = removexattr(path->narrow, attribute->narrow);
10953 else
10954 result = lremovexattr(path->narrow, attribute->narrow);
10955 Py_END_ALLOW_THREADS;
10956
10957 if (result) {
10958 return path_error(path);
10959 }
10960
10961 Py_RETURN_NONE;
10962}
10963
10964
10965/*[clinic input]
10966os.listxattr
10967
10968 path: path_t(allow_fd=True, nullable=True) = None
10969 *
10970 follow_symlinks: bool = True
10971
10972Return a list of extended attributes on path.
10973
10974path may be either None, a string, or an open file descriptor.
10975if path is None, listxattr will examine the current directory.
10976If follow_symlinks is False, and the last element of the path is a symbolic
10977 link, listxattr will examine the symbolic link itself instead of the file
10978 the link points to.
10979[clinic start generated code]*/
10980
Larry Hastings2f936352014-08-05 14:04:04 +100010981static PyObject *
10982os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010983/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010984{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010985 Py_ssize_t i;
10986 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010987 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010988 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010989
Larry Hastings2f936352014-08-05 14:04:04 +100010990 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010991 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010992
Larry Hastings2f936352014-08-05 14:04:04 +100010993 name = path->narrow ? path->narrow : ".";
10994
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 for (i = 0; ; i++) {
10996 char *start, *trace, *end;
10997 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010998 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010999 Py_ssize_t buffer_size = buffer_sizes[i];
11000 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020011001 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100011002 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 break;
11004 }
11005 buffer = PyMem_MALLOC(buffer_size);
11006 if (!buffer) {
11007 PyErr_NoMemory();
11008 break;
11009 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011010
Larry Hastings9cf065c2012-06-22 16:30:09 -070011011 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011012 if (path->fd > -1)
11013 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011014 else if (follow_symlinks)
11015 length = listxattr(name, buffer, buffer_size);
11016 else
11017 length = llistxattr(name, buffer, buffer_size);
11018 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011019
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011021 if (errno == ERANGE) {
11022 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011023 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011024 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011025 }
Larry Hastings2f936352014-08-05 14:04:04 +100011026 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011027 break;
11028 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011029
Larry Hastings9cf065c2012-06-22 16:30:09 -070011030 result = PyList_New(0);
11031 if (!result) {
11032 goto exit;
11033 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011034
Larry Hastings9cf065c2012-06-22 16:30:09 -070011035 end = buffer + length;
11036 for (trace = start = buffer; trace != end; trace++) {
11037 if (!*trace) {
11038 int error;
11039 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11040 trace - start);
11041 if (!attribute) {
11042 Py_DECREF(result);
11043 result = NULL;
11044 goto exit;
11045 }
11046 error = PyList_Append(result, attribute);
11047 Py_DECREF(attribute);
11048 if (error) {
11049 Py_DECREF(result);
11050 result = NULL;
11051 goto exit;
11052 }
11053 start = trace + 1;
11054 }
11055 }
11056 break;
11057 }
11058exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011059 if (buffer)
11060 PyMem_FREE(buffer);
11061 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011062}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011063#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011064
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011065
Larry Hastings2f936352014-08-05 14:04:04 +100011066/*[clinic input]
11067os.urandom
11068
11069 size: Py_ssize_t
11070 /
11071
11072Return a bytes object containing random bytes suitable for cryptographic use.
11073[clinic start generated code]*/
11074
Larry Hastings2f936352014-08-05 14:04:04 +100011075static PyObject *
11076os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011077/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011078{
11079 PyObject *bytes;
11080 int result;
11081
Georg Brandl2fb477c2012-02-21 00:33:36 +010011082 if (size < 0)
11083 return PyErr_Format(PyExc_ValueError,
11084 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011085 bytes = PyBytes_FromStringAndSize(NULL, size);
11086 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011087 return NULL;
11088
Larry Hastings2f936352014-08-05 14:04:04 +100011089 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11090 PyBytes_GET_SIZE(bytes));
11091 if (result == -1) {
11092 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011093 return NULL;
11094 }
Larry Hastings2f936352014-08-05 14:04:04 +100011095 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011096}
11097
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011098/* Terminal size querying */
11099
11100static PyTypeObject TerminalSizeType;
11101
11102PyDoc_STRVAR(TerminalSize_docstring,
11103 "A tuple of (columns, lines) for holding terminal window size");
11104
11105static PyStructSequence_Field TerminalSize_fields[] = {
11106 {"columns", "width of the terminal window in characters"},
11107 {"lines", "height of the terminal window in characters"},
11108 {NULL, NULL}
11109};
11110
11111static PyStructSequence_Desc TerminalSize_desc = {
11112 "os.terminal_size",
11113 TerminalSize_docstring,
11114 TerminalSize_fields,
11115 2,
11116};
11117
11118#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011119/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011120PyDoc_STRVAR(termsize__doc__,
11121 "Return the size of the terminal window as (columns, lines).\n" \
11122 "\n" \
11123 "The optional argument fd (default standard output) specifies\n" \
11124 "which file descriptor should be queried.\n" \
11125 "\n" \
11126 "If the file descriptor is not connected to a terminal, an OSError\n" \
11127 "is thrown.\n" \
11128 "\n" \
11129 "This function will only be defined if an implementation is\n" \
11130 "available for this system.\n" \
11131 "\n" \
11132 "shutil.get_terminal_size is the high-level function which should \n" \
11133 "normally be used, os.get_terminal_size is the low-level implementation.");
11134
11135static PyObject*
11136get_terminal_size(PyObject *self, PyObject *args)
11137{
11138 int columns, lines;
11139 PyObject *termsize;
11140
11141 int fd = fileno(stdout);
11142 /* Under some conditions stdout may not be connected and
11143 * fileno(stdout) may point to an invalid file descriptor. For example
11144 * GUI apps don't have valid standard streams by default.
11145 *
11146 * If this happens, and the optional fd argument is not present,
11147 * the ioctl below will fail returning EBADF. This is what we want.
11148 */
11149
11150 if (!PyArg_ParseTuple(args, "|i", &fd))
11151 return NULL;
11152
11153#ifdef TERMSIZE_USE_IOCTL
11154 {
11155 struct winsize w;
11156 if (ioctl(fd, TIOCGWINSZ, &w))
11157 return PyErr_SetFromErrno(PyExc_OSError);
11158 columns = w.ws_col;
11159 lines = w.ws_row;
11160 }
11161#endif /* TERMSIZE_USE_IOCTL */
11162
11163#ifdef TERMSIZE_USE_CONIO
11164 {
11165 DWORD nhandle;
11166 HANDLE handle;
11167 CONSOLE_SCREEN_BUFFER_INFO csbi;
11168 switch (fd) {
11169 case 0: nhandle = STD_INPUT_HANDLE;
11170 break;
11171 case 1: nhandle = STD_OUTPUT_HANDLE;
11172 break;
11173 case 2: nhandle = STD_ERROR_HANDLE;
11174 break;
11175 default:
11176 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11177 }
11178 handle = GetStdHandle(nhandle);
11179 if (handle == NULL)
11180 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11181 if (handle == INVALID_HANDLE_VALUE)
11182 return PyErr_SetFromWindowsErr(0);
11183
11184 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11185 return PyErr_SetFromWindowsErr(0);
11186
11187 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11188 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11189 }
11190#endif /* TERMSIZE_USE_CONIO */
11191
11192 termsize = PyStructSequence_New(&TerminalSizeType);
11193 if (termsize == NULL)
11194 return NULL;
11195 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11196 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11197 if (PyErr_Occurred()) {
11198 Py_DECREF(termsize);
11199 return NULL;
11200 }
11201 return termsize;
11202}
11203#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11204
Larry Hastings2f936352014-08-05 14:04:04 +100011205
11206/*[clinic input]
11207os.cpu_count
11208
Charles-François Natali80d62e62015-08-13 20:37:08 +010011209Return the number of CPUs in the system; return None if indeterminable.
11210
11211This number is not equivalent to the number of CPUs the current process can
11212use. The number of usable CPUs can be obtained with
11213``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011214[clinic start generated code]*/
11215
Larry Hastings2f936352014-08-05 14:04:04 +100011216static PyObject *
11217os_cpu_count_impl(PyModuleDef *module)
Charles-François Natali80d62e62015-08-13 20:37:08 +010011218/*[clinic end generated code: output=c59ee7f6bce832b8 input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011219{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011220 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011221#ifdef MS_WINDOWS
11222 SYSTEM_INFO sysinfo;
11223 GetSystemInfo(&sysinfo);
11224 ncpu = sysinfo.dwNumberOfProcessors;
11225#elif defined(__hpux)
11226 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11227#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11228 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011229#elif defined(__DragonFly__) || \
11230 defined(__OpenBSD__) || \
11231 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011232 defined(__NetBSD__) || \
11233 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011234 int mib[2];
11235 size_t len = sizeof(ncpu);
11236 mib[0] = CTL_HW;
11237 mib[1] = HW_NCPU;
11238 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11239 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011240#endif
11241 if (ncpu >= 1)
11242 return PyLong_FromLong(ncpu);
11243 else
11244 Py_RETURN_NONE;
11245}
11246
Victor Stinnerdaf45552013-08-28 00:53:59 +020011247
Larry Hastings2f936352014-08-05 14:04:04 +100011248/*[clinic input]
11249os.get_inheritable -> bool
11250
11251 fd: int
11252 /
11253
11254Get the close-on-exe flag of the specified file descriptor.
11255[clinic start generated code]*/
11256
Larry Hastings2f936352014-08-05 14:04:04 +100011257static int
11258os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011259/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011260{
Steve Dower8fc89802015-04-12 00:26:27 -040011261 int return_value;
11262 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011263 posix_error();
11264 return -1;
11265 }
11266
Steve Dower8fc89802015-04-12 00:26:27 -040011267 _Py_BEGIN_SUPPRESS_IPH
11268 return_value = _Py_get_inheritable(fd);
11269 _Py_END_SUPPRESS_IPH
11270 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011271}
11272
11273
11274/*[clinic input]
11275os.set_inheritable
11276 fd: int
11277 inheritable: int
11278 /
11279
11280Set the inheritable flag of the specified file descriptor.
11281[clinic start generated code]*/
11282
Larry Hastings2f936352014-08-05 14:04:04 +100011283static PyObject *
11284os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011285/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011286{
Steve Dower8fc89802015-04-12 00:26:27 -040011287 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011288 if (!_PyVerify_fd(fd))
11289 return posix_error();
11290
Steve Dower8fc89802015-04-12 00:26:27 -040011291 _Py_BEGIN_SUPPRESS_IPH
11292 result = _Py_set_inheritable(fd, inheritable, NULL);
11293 _Py_END_SUPPRESS_IPH
11294 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011295 return NULL;
11296 Py_RETURN_NONE;
11297}
11298
11299
11300#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011301/*[clinic input]
11302os.get_handle_inheritable -> bool
11303 handle: Py_intptr_t
11304 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011305
Larry Hastings2f936352014-08-05 14:04:04 +100011306Get the close-on-exe flag of the specified file descriptor.
11307[clinic start generated code]*/
11308
Larry Hastings2f936352014-08-05 14:04:04 +100011309static int
11310os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011311/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011312{
11313 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011314
11315 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11316 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011317 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011318 }
11319
Larry Hastings2f936352014-08-05 14:04:04 +100011320 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011321}
11322
Victor Stinnerdaf45552013-08-28 00:53:59 +020011323
Larry Hastings2f936352014-08-05 14:04:04 +100011324/*[clinic input]
11325os.set_handle_inheritable
11326 handle: Py_intptr_t
11327 inheritable: bool
11328 /
11329
11330Set the inheritable flag of the specified handle.
11331[clinic start generated code]*/
11332
Larry Hastings2f936352014-08-05 14:04:04 +100011333static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040011334os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle,
11335 int inheritable)
11336/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011337{
11338 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011339 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11340 PyErr_SetFromWindowsErr(0);
11341 return NULL;
11342 }
11343 Py_RETURN_NONE;
11344}
Larry Hastings2f936352014-08-05 14:04:04 +100011345#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011346
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011347#ifndef MS_WINDOWS
11348PyDoc_STRVAR(get_blocking__doc__,
11349 "get_blocking(fd) -> bool\n" \
11350 "\n" \
11351 "Get the blocking mode of the file descriptor:\n" \
11352 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11353
11354static PyObject*
11355posix_get_blocking(PyObject *self, PyObject *args)
11356{
11357 int fd;
11358 int blocking;
11359
11360 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11361 return NULL;
11362
11363 if (!_PyVerify_fd(fd))
11364 return posix_error();
11365
Steve Dower8fc89802015-04-12 00:26:27 -040011366 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011367 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011368 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011369 if (blocking < 0)
11370 return NULL;
11371 return PyBool_FromLong(blocking);
11372}
11373
11374PyDoc_STRVAR(set_blocking__doc__,
11375 "set_blocking(fd, blocking)\n" \
11376 "\n" \
11377 "Set the blocking mode of the specified file descriptor.\n" \
11378 "Set the O_NONBLOCK flag if blocking is False,\n" \
11379 "clear the O_NONBLOCK flag otherwise.");
11380
11381static PyObject*
11382posix_set_blocking(PyObject *self, PyObject *args)
11383{
Steve Dower8fc89802015-04-12 00:26:27 -040011384 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011385
11386 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11387 return NULL;
11388
11389 if (!_PyVerify_fd(fd))
11390 return posix_error();
11391
Steve Dower8fc89802015-04-12 00:26:27 -040011392 _Py_BEGIN_SUPPRESS_IPH
11393 result = _Py_set_blocking(fd, blocking);
11394 _Py_END_SUPPRESS_IPH
11395 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011396 return NULL;
11397 Py_RETURN_NONE;
11398}
11399#endif /* !MS_WINDOWS */
11400
11401
Victor Stinner6036e442015-03-08 01:58:04 +010011402PyDoc_STRVAR(posix_scandir__doc__,
11403"scandir(path='.') -> iterator of DirEntry objects for given path");
11404
11405static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11406
11407typedef struct {
11408 PyObject_HEAD
11409 PyObject *name;
11410 PyObject *path;
11411 PyObject *stat;
11412 PyObject *lstat;
11413#ifdef MS_WINDOWS
11414 struct _Py_stat_struct win32_lstat;
11415 __int64 win32_file_index;
11416 int got_file_index;
11417#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011418#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011419 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011420#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011421 ino_t d_ino;
11422#endif
11423} DirEntry;
11424
11425static void
11426DirEntry_dealloc(DirEntry *entry)
11427{
11428 Py_XDECREF(entry->name);
11429 Py_XDECREF(entry->path);
11430 Py_XDECREF(entry->stat);
11431 Py_XDECREF(entry->lstat);
11432 Py_TYPE(entry)->tp_free((PyObject *)entry);
11433}
11434
11435/* Forward reference */
11436static int
11437DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11438
11439/* Set exception and return -1 on error, 0 for False, 1 for True */
11440static int
11441DirEntry_is_symlink(DirEntry *self)
11442{
11443#ifdef MS_WINDOWS
11444 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011445#elif defined(HAVE_DIRENT_D_TYPE)
11446 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011447 if (self->d_type != DT_UNKNOWN)
11448 return self->d_type == DT_LNK;
11449 else
11450 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011451#else
11452 /* POSIX without d_type */
11453 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011454#endif
11455}
11456
11457static PyObject *
11458DirEntry_py_is_symlink(DirEntry *self)
11459{
11460 int result;
11461
11462 result = DirEntry_is_symlink(self);
11463 if (result == -1)
11464 return NULL;
11465 return PyBool_FromLong(result);
11466}
11467
11468static PyObject *
11469DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11470{
11471 int result;
11472 struct _Py_stat_struct st;
11473
11474#ifdef MS_WINDOWS
11475 wchar_t *path;
11476
11477 path = PyUnicode_AsUnicode(self->path);
11478 if (!path)
11479 return NULL;
11480
11481 if (follow_symlinks)
11482 result = win32_stat_w(path, &st);
11483 else
11484 result = win32_lstat_w(path, &st);
11485
11486 if (result != 0) {
11487 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11488 0, self->path);
11489 }
11490#else /* POSIX */
11491 PyObject *bytes;
11492 char *path;
11493
11494 if (!PyUnicode_FSConverter(self->path, &bytes))
11495 return NULL;
11496 path = PyBytes_AS_STRING(bytes);
11497
11498 if (follow_symlinks)
11499 result = STAT(path, &st);
11500 else
11501 result = LSTAT(path, &st);
11502 Py_DECREF(bytes);
11503
11504 if (result != 0)
11505 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11506#endif
11507
11508 return _pystat_fromstructstat(&st);
11509}
11510
11511static PyObject *
11512DirEntry_get_lstat(DirEntry *self)
11513{
11514 if (!self->lstat) {
11515#ifdef MS_WINDOWS
11516 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11517#else /* POSIX */
11518 self->lstat = DirEntry_fetch_stat(self, 0);
11519#endif
11520 }
11521 Py_XINCREF(self->lstat);
11522 return self->lstat;
11523}
11524
11525static PyObject *
11526DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11527{
11528 if (!follow_symlinks)
11529 return DirEntry_get_lstat(self);
11530
11531 if (!self->stat) {
11532 int result = DirEntry_is_symlink(self);
11533 if (result == -1)
11534 return NULL;
11535 else if (result)
11536 self->stat = DirEntry_fetch_stat(self, 1);
11537 else
11538 self->stat = DirEntry_get_lstat(self);
11539 }
11540
11541 Py_XINCREF(self->stat);
11542 return self->stat;
11543}
11544
11545static PyObject *
11546DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11547{
11548 int follow_symlinks = 1;
11549
11550 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11551 follow_symlinks_keywords, &follow_symlinks))
11552 return NULL;
11553
11554 return DirEntry_get_stat(self, follow_symlinks);
11555}
11556
11557/* Set exception and return -1 on error, 0 for False, 1 for True */
11558static int
11559DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11560{
11561 PyObject *stat = NULL;
11562 PyObject *st_mode = NULL;
11563 long mode;
11564 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011565#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011566 int is_symlink;
11567 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011568#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011569#ifdef MS_WINDOWS
11570 unsigned long dir_bits;
11571#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011572 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011573
11574#ifdef MS_WINDOWS
11575 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11576 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011577#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011578 is_symlink = self->d_type == DT_LNK;
11579 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11580#endif
11581
Victor Stinner35a97c02015-03-08 02:59:09 +010011582#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011583 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011584#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011585 stat = DirEntry_get_stat(self, follow_symlinks);
11586 if (!stat) {
11587 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11588 /* If file doesn't exist (anymore), then return False
11589 (i.e., say it's not a file/directory) */
11590 PyErr_Clear();
11591 return 0;
11592 }
11593 goto error;
11594 }
11595 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11596 if (!st_mode)
11597 goto error;
11598
11599 mode = PyLong_AsLong(st_mode);
11600 if (mode == -1 && PyErr_Occurred())
11601 goto error;
11602 Py_CLEAR(st_mode);
11603 Py_CLEAR(stat);
11604 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011605#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011606 }
11607 else if (is_symlink) {
11608 assert(mode_bits != S_IFLNK);
11609 result = 0;
11610 }
11611 else {
11612 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11613#ifdef MS_WINDOWS
11614 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11615 if (mode_bits == S_IFDIR)
11616 result = dir_bits != 0;
11617 else
11618 result = dir_bits == 0;
11619#else /* POSIX */
11620 if (mode_bits == S_IFDIR)
11621 result = self->d_type == DT_DIR;
11622 else
11623 result = self->d_type == DT_REG;
11624#endif
11625 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011626#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011627
11628 return result;
11629
11630error:
11631 Py_XDECREF(st_mode);
11632 Py_XDECREF(stat);
11633 return -1;
11634}
11635
11636static PyObject *
11637DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11638{
11639 int result;
11640
11641 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11642 if (result == -1)
11643 return NULL;
11644 return PyBool_FromLong(result);
11645}
11646
11647static PyObject *
11648DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11649{
11650 int follow_symlinks = 1;
11651
11652 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11653 follow_symlinks_keywords, &follow_symlinks))
11654 return NULL;
11655
11656 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11657}
11658
11659static PyObject *
11660DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11661{
11662 int follow_symlinks = 1;
11663
11664 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11665 follow_symlinks_keywords, &follow_symlinks))
11666 return NULL;
11667
11668 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11669}
11670
11671static PyObject *
11672DirEntry_inode(DirEntry *self)
11673{
11674#ifdef MS_WINDOWS
11675 if (!self->got_file_index) {
11676 wchar_t *path;
11677 struct _Py_stat_struct stat;
11678
11679 path = PyUnicode_AsUnicode(self->path);
11680 if (!path)
11681 return NULL;
11682
11683 if (win32_lstat_w(path, &stat) != 0) {
11684 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11685 0, self->path);
11686 }
11687
11688 self->win32_file_index = stat.st_ino;
11689 self->got_file_index = 1;
11690 }
11691 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11692#else /* POSIX */
11693#ifdef HAVE_LARGEFILE_SUPPORT
11694 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11695#else
11696 return PyLong_FromLong((long)self->d_ino);
11697#endif
11698#endif
11699}
11700
11701static PyObject *
11702DirEntry_repr(DirEntry *self)
11703{
11704 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11705}
11706
11707static PyMemberDef DirEntry_members[] = {
11708 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11709 "the entry's base filename, relative to scandir() \"path\" argument"},
11710 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11711 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11712 {NULL}
11713};
11714
11715static PyMethodDef DirEntry_methods[] = {
11716 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11717 "return True if the entry is a directory; cached per entry"
11718 },
11719 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11720 "return True if the entry is a file; cached per entry"
11721 },
11722 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11723 "return True if the entry is a symbolic link; cached per entry"
11724 },
11725 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11726 "return stat_result object for the entry; cached per entry"
11727 },
11728 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11729 "return inode of the entry; cached per entry",
11730 },
11731 {NULL}
11732};
11733
Benjamin Peterson5646de42015-04-12 17:56:34 -040011734static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011735 PyVarObject_HEAD_INIT(NULL, 0)
11736 MODNAME ".DirEntry", /* tp_name */
11737 sizeof(DirEntry), /* tp_basicsize */
11738 0, /* tp_itemsize */
11739 /* methods */
11740 (destructor)DirEntry_dealloc, /* tp_dealloc */
11741 0, /* tp_print */
11742 0, /* tp_getattr */
11743 0, /* tp_setattr */
11744 0, /* tp_compare */
11745 (reprfunc)DirEntry_repr, /* tp_repr */
11746 0, /* tp_as_number */
11747 0, /* tp_as_sequence */
11748 0, /* tp_as_mapping */
11749 0, /* tp_hash */
11750 0, /* tp_call */
11751 0, /* tp_str */
11752 0, /* tp_getattro */
11753 0, /* tp_setattro */
11754 0, /* tp_as_buffer */
11755 Py_TPFLAGS_DEFAULT, /* tp_flags */
11756 0, /* tp_doc */
11757 0, /* tp_traverse */
11758 0, /* tp_clear */
11759 0, /* tp_richcompare */
11760 0, /* tp_weaklistoffset */
11761 0, /* tp_iter */
11762 0, /* tp_iternext */
11763 DirEntry_methods, /* tp_methods */
11764 DirEntry_members, /* tp_members */
11765};
11766
11767#ifdef MS_WINDOWS
11768
11769static wchar_t *
11770join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11771{
11772 Py_ssize_t path_len;
11773 Py_ssize_t size;
11774 wchar_t *result;
11775 wchar_t ch;
11776
11777 if (!path_wide) { /* Default arg: "." */
11778 path_wide = L".";
11779 path_len = 1;
11780 }
11781 else {
11782 path_len = wcslen(path_wide);
11783 }
11784
11785 /* The +1's are for the path separator and the NUL */
11786 size = path_len + 1 + wcslen(filename) + 1;
11787 result = PyMem_New(wchar_t, size);
11788 if (!result) {
11789 PyErr_NoMemory();
11790 return NULL;
11791 }
11792 wcscpy(result, path_wide);
11793 if (path_len > 0) {
11794 ch = result[path_len - 1];
11795 if (ch != SEP && ch != ALTSEP && ch != L':')
11796 result[path_len++] = SEP;
11797 wcscpy(result + path_len, filename);
11798 }
11799 return result;
11800}
11801
11802static PyObject *
11803DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11804{
11805 DirEntry *entry;
11806 BY_HANDLE_FILE_INFORMATION file_info;
11807 ULONG reparse_tag;
11808 wchar_t *joined_path;
11809
11810 entry = PyObject_New(DirEntry, &DirEntryType);
11811 if (!entry)
11812 return NULL;
11813 entry->name = NULL;
11814 entry->path = NULL;
11815 entry->stat = NULL;
11816 entry->lstat = NULL;
11817 entry->got_file_index = 0;
11818
11819 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11820 if (!entry->name)
11821 goto error;
11822
11823 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11824 if (!joined_path)
11825 goto error;
11826
11827 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11828 PyMem_Free(joined_path);
11829 if (!entry->path)
11830 goto error;
11831
11832 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11833 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11834
11835 return (PyObject *)entry;
11836
11837error:
11838 Py_DECREF(entry);
11839 return NULL;
11840}
11841
11842#else /* POSIX */
11843
11844static char *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011845join_path_filename(const char *path_narrow, const char* filename, Py_ssize_t filename_len)
Victor Stinner6036e442015-03-08 01:58:04 +010011846{
11847 Py_ssize_t path_len;
11848 Py_ssize_t size;
11849 char *result;
11850
11851 if (!path_narrow) { /* Default arg: "." */
11852 path_narrow = ".";
11853 path_len = 1;
11854 }
11855 else {
11856 path_len = strlen(path_narrow);
11857 }
11858
11859 if (filename_len == -1)
11860 filename_len = strlen(filename);
11861
11862 /* The +1's are for the path separator and the NUL */
11863 size = path_len + 1 + filename_len + 1;
11864 result = PyMem_New(char, size);
11865 if (!result) {
11866 PyErr_NoMemory();
11867 return NULL;
11868 }
11869 strcpy(result, path_narrow);
11870 if (path_len > 0 && result[path_len - 1] != '/')
11871 result[path_len++] = '/';
11872 strcpy(result + path_len, filename);
11873 return result;
11874}
11875
11876static PyObject *
Serhiy Storchakaef1585e2015-12-25 20:01:53 +020011877DirEntry_from_posix_info(path_t *path, const char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011878 ino_t d_ino
11879#ifdef HAVE_DIRENT_D_TYPE
11880 , unsigned char d_type
11881#endif
11882 )
Victor Stinner6036e442015-03-08 01:58:04 +010011883{
11884 DirEntry *entry;
11885 char *joined_path;
11886
11887 entry = PyObject_New(DirEntry, &DirEntryType);
11888 if (!entry)
11889 return NULL;
11890 entry->name = NULL;
11891 entry->path = NULL;
11892 entry->stat = NULL;
11893 entry->lstat = NULL;
11894
11895 joined_path = join_path_filename(path->narrow, name, name_len);
11896 if (!joined_path)
11897 goto error;
11898
11899 if (!path->narrow || !PyBytes_Check(path->object)) {
11900 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11901 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11902 }
11903 else {
11904 entry->name = PyBytes_FromStringAndSize(name, name_len);
11905 entry->path = PyBytes_FromString(joined_path);
11906 }
11907 PyMem_Free(joined_path);
11908 if (!entry->name || !entry->path)
11909 goto error;
11910
Victor Stinner35a97c02015-03-08 02:59:09 +010011911#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011912 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011913#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011914 entry->d_ino = d_ino;
11915
11916 return (PyObject *)entry;
11917
11918error:
11919 Py_XDECREF(entry);
11920 return NULL;
11921}
11922
11923#endif
11924
11925
11926typedef struct {
11927 PyObject_HEAD
11928 path_t path;
11929#ifdef MS_WINDOWS
11930 HANDLE handle;
11931 WIN32_FIND_DATAW file_data;
11932 int first_time;
11933#else /* POSIX */
11934 DIR *dirp;
11935#endif
11936} ScandirIterator;
11937
11938#ifdef MS_WINDOWS
11939
11940static void
11941ScandirIterator_close(ScandirIterator *iterator)
11942{
11943 if (iterator->handle == INVALID_HANDLE_VALUE)
11944 return;
11945
11946 Py_BEGIN_ALLOW_THREADS
11947 FindClose(iterator->handle);
11948 Py_END_ALLOW_THREADS
11949 iterator->handle = INVALID_HANDLE_VALUE;
11950}
11951
11952static PyObject *
11953ScandirIterator_iternext(ScandirIterator *iterator)
11954{
11955 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11956 BOOL success;
11957
11958 /* Happens if the iterator is iterated twice */
11959 if (iterator->handle == INVALID_HANDLE_VALUE) {
11960 PyErr_SetNone(PyExc_StopIteration);
11961 return NULL;
11962 }
11963
11964 while (1) {
11965 if (!iterator->first_time) {
11966 Py_BEGIN_ALLOW_THREADS
11967 success = FindNextFileW(iterator->handle, file_data);
11968 Py_END_ALLOW_THREADS
11969 if (!success) {
11970 if (GetLastError() != ERROR_NO_MORE_FILES)
11971 return path_error(&iterator->path);
11972 /* No more files found in directory, stop iterating */
11973 break;
11974 }
11975 }
11976 iterator->first_time = 0;
11977
11978 /* Skip over . and .. */
11979 if (wcscmp(file_data->cFileName, L".") != 0 &&
11980 wcscmp(file_data->cFileName, L"..") != 0)
11981 return DirEntry_from_find_data(&iterator->path, file_data);
11982
11983 /* Loop till we get a non-dot directory or finish iterating */
11984 }
11985
11986 ScandirIterator_close(iterator);
11987
11988 PyErr_SetNone(PyExc_StopIteration);
11989 return NULL;
11990}
11991
11992#else /* POSIX */
11993
11994static void
11995ScandirIterator_close(ScandirIterator *iterator)
11996{
11997 if (!iterator->dirp)
11998 return;
11999
12000 Py_BEGIN_ALLOW_THREADS
12001 closedir(iterator->dirp);
12002 Py_END_ALLOW_THREADS
12003 iterator->dirp = NULL;
12004 return;
12005}
12006
12007static PyObject *
12008ScandirIterator_iternext(ScandirIterator *iterator)
12009{
12010 struct dirent *direntp;
12011 Py_ssize_t name_len;
12012 int is_dot;
Victor Stinner6036e442015-03-08 01:58:04 +010012013
12014 /* Happens if the iterator is iterated twice */
12015 if (!iterator->dirp) {
12016 PyErr_SetNone(PyExc_StopIteration);
12017 return NULL;
12018 }
12019
12020 while (1) {
12021 errno = 0;
12022 Py_BEGIN_ALLOW_THREADS
12023 direntp = readdir(iterator->dirp);
12024 Py_END_ALLOW_THREADS
12025
12026 if (!direntp) {
12027 if (errno != 0)
12028 return path_error(&iterator->path);
12029 /* No more files found in directory, stop iterating */
12030 break;
12031 }
12032
12033 /* Skip over . and .. */
12034 name_len = NAMLEN(direntp);
12035 is_dot = direntp->d_name[0] == '.' &&
12036 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12037 if (!is_dot) {
Victor Stinner6036e442015-03-08 01:58:04 +010012038 return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012039 name_len, direntp->d_ino
12040#ifdef HAVE_DIRENT_D_TYPE
12041 , direntp->d_type
12042#endif
12043 );
Victor Stinner6036e442015-03-08 01:58:04 +010012044 }
12045
12046 /* Loop till we get a non-dot directory or finish iterating */
12047 }
12048
12049 ScandirIterator_close(iterator);
12050
12051 PyErr_SetNone(PyExc_StopIteration);
12052 return NULL;
12053}
12054
12055#endif
12056
12057static void
12058ScandirIterator_dealloc(ScandirIterator *iterator)
12059{
12060 ScandirIterator_close(iterator);
12061 Py_XDECREF(iterator->path.object);
12062 path_cleanup(&iterator->path);
12063 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12064}
12065
Benjamin Peterson5646de42015-04-12 17:56:34 -040012066static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012067 PyVarObject_HEAD_INIT(NULL, 0)
12068 MODNAME ".ScandirIterator", /* tp_name */
12069 sizeof(ScandirIterator), /* tp_basicsize */
12070 0, /* tp_itemsize */
12071 /* methods */
12072 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12073 0, /* tp_print */
12074 0, /* tp_getattr */
12075 0, /* tp_setattr */
12076 0, /* tp_compare */
12077 0, /* tp_repr */
12078 0, /* tp_as_number */
12079 0, /* tp_as_sequence */
12080 0, /* tp_as_mapping */
12081 0, /* tp_hash */
12082 0, /* tp_call */
12083 0, /* tp_str */
12084 0, /* tp_getattro */
12085 0, /* tp_setattro */
12086 0, /* tp_as_buffer */
12087 Py_TPFLAGS_DEFAULT, /* tp_flags */
12088 0, /* tp_doc */
12089 0, /* tp_traverse */
12090 0, /* tp_clear */
12091 0, /* tp_richcompare */
12092 0, /* tp_weaklistoffset */
12093 PyObject_SelfIter, /* tp_iter */
12094 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12095};
12096
12097static PyObject *
12098posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12099{
12100 ScandirIterator *iterator;
12101 static char *keywords[] = {"path", NULL};
12102#ifdef MS_WINDOWS
12103 wchar_t *path_strW;
12104#else
12105 char *path;
12106#endif
12107
12108 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12109 if (!iterator)
12110 return NULL;
12111 memset(&iterator->path, 0, sizeof(path_t));
12112 iterator->path.function_name = "scandir";
12113 iterator->path.nullable = 1;
12114
12115#ifdef MS_WINDOWS
12116 iterator->handle = INVALID_HANDLE_VALUE;
12117#else
12118 iterator->dirp = NULL;
12119#endif
12120
12121 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12122 path_converter, &iterator->path))
12123 goto error;
12124
12125 /* path_converter doesn't keep path.object around, so do it
12126 manually for the lifetime of the iterator here (the refcount
12127 is decremented in ScandirIterator_dealloc)
12128 */
12129 Py_XINCREF(iterator->path.object);
12130
12131#ifdef MS_WINDOWS
12132 if (iterator->path.narrow) {
12133 PyErr_SetString(PyExc_TypeError,
12134 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12135 goto error;
12136 }
12137 iterator->first_time = 1;
12138
12139 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12140 if (!path_strW)
12141 goto error;
12142
12143 Py_BEGIN_ALLOW_THREADS
12144 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12145 Py_END_ALLOW_THREADS
12146
12147 PyMem_Free(path_strW);
12148
12149 if (iterator->handle == INVALID_HANDLE_VALUE) {
12150 path_error(&iterator->path);
12151 goto error;
12152 }
12153#else /* POSIX */
12154 if (iterator->path.narrow)
12155 path = iterator->path.narrow;
12156 else
12157 path = ".";
12158
12159 errno = 0;
12160 Py_BEGIN_ALLOW_THREADS
12161 iterator->dirp = opendir(path);
12162 Py_END_ALLOW_THREADS
12163
12164 if (!iterator->dirp) {
12165 path_error(&iterator->path);
12166 goto error;
12167 }
12168#endif
12169
12170 return (PyObject *)iterator;
12171
12172error:
12173 Py_DECREF(iterator);
12174 return NULL;
12175}
12176
12177
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012178#include "clinic/posixmodule.c.h"
12179
Larry Hastings7726ac92014-01-31 22:03:12 -080012180/*[clinic input]
12181dump buffer
12182[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012183/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012184
Larry Hastings31826802013-10-19 00:09:25 -070012185
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012186static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012187
12188 OS_STAT_METHODDEF
12189 OS_ACCESS_METHODDEF
12190 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012191 OS_CHDIR_METHODDEF
12192 OS_CHFLAGS_METHODDEF
12193 OS_CHMOD_METHODDEF
12194 OS_FCHMOD_METHODDEF
12195 OS_LCHMOD_METHODDEF
12196 OS_CHOWN_METHODDEF
12197 OS_FCHOWN_METHODDEF
12198 OS_LCHOWN_METHODDEF
12199 OS_LCHFLAGS_METHODDEF
12200 OS_CHROOT_METHODDEF
12201 OS_CTERMID_METHODDEF
12202 OS_GETCWD_METHODDEF
12203 OS_GETCWDB_METHODDEF
12204 OS_LINK_METHODDEF
12205 OS_LISTDIR_METHODDEF
12206 OS_LSTAT_METHODDEF
12207 OS_MKDIR_METHODDEF
12208 OS_NICE_METHODDEF
12209 OS_GETPRIORITY_METHODDEF
12210 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012211#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012212 {"readlink", (PyCFunction)posix_readlink,
12213 METH_VARARGS | METH_KEYWORDS,
12214 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012215#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012216#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012217 {"readlink", (PyCFunction)win_readlink,
12218 METH_VARARGS | METH_KEYWORDS,
12219 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012220#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012221 OS_RENAME_METHODDEF
12222 OS_REPLACE_METHODDEF
12223 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012224 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012225 OS_SYMLINK_METHODDEF
12226 OS_SYSTEM_METHODDEF
12227 OS_UMASK_METHODDEF
12228 OS_UNAME_METHODDEF
12229 OS_UNLINK_METHODDEF
12230 OS_REMOVE_METHODDEF
12231 OS_UTIME_METHODDEF
12232 OS_TIMES_METHODDEF
12233 OS__EXIT_METHODDEF
12234 OS_EXECV_METHODDEF
12235 OS_EXECVE_METHODDEF
12236 OS_SPAWNV_METHODDEF
12237 OS_SPAWNVE_METHODDEF
12238 OS_FORK1_METHODDEF
12239 OS_FORK_METHODDEF
12240 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12241 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12242 OS_SCHED_GETPARAM_METHODDEF
12243 OS_SCHED_GETSCHEDULER_METHODDEF
12244 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12245 OS_SCHED_SETPARAM_METHODDEF
12246 OS_SCHED_SETSCHEDULER_METHODDEF
12247 OS_SCHED_YIELD_METHODDEF
12248 OS_SCHED_SETAFFINITY_METHODDEF
12249 OS_SCHED_GETAFFINITY_METHODDEF
12250 OS_OPENPTY_METHODDEF
12251 OS_FORKPTY_METHODDEF
12252 OS_GETEGID_METHODDEF
12253 OS_GETEUID_METHODDEF
12254 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012255#ifdef HAVE_GETGROUPLIST
12256 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12257#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012258 OS_GETGROUPS_METHODDEF
12259 OS_GETPID_METHODDEF
12260 OS_GETPGRP_METHODDEF
12261 OS_GETPPID_METHODDEF
12262 OS_GETUID_METHODDEF
12263 OS_GETLOGIN_METHODDEF
12264 OS_KILL_METHODDEF
12265 OS_KILLPG_METHODDEF
12266 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012267#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012268 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012269#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012270 OS_SETUID_METHODDEF
12271 OS_SETEUID_METHODDEF
12272 OS_SETREUID_METHODDEF
12273 OS_SETGID_METHODDEF
12274 OS_SETEGID_METHODDEF
12275 OS_SETREGID_METHODDEF
12276 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012277#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012278 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012279#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012280 OS_GETPGID_METHODDEF
12281 OS_SETPGRP_METHODDEF
12282 OS_WAIT_METHODDEF
12283 OS_WAIT3_METHODDEF
12284 OS_WAIT4_METHODDEF
12285 OS_WAITID_METHODDEF
12286 OS_WAITPID_METHODDEF
12287 OS_GETSID_METHODDEF
12288 OS_SETSID_METHODDEF
12289 OS_SETPGID_METHODDEF
12290 OS_TCGETPGRP_METHODDEF
12291 OS_TCSETPGRP_METHODDEF
12292 OS_OPEN_METHODDEF
12293 OS_CLOSE_METHODDEF
12294 OS_CLOSERANGE_METHODDEF
12295 OS_DEVICE_ENCODING_METHODDEF
12296 OS_DUP_METHODDEF
12297 OS_DUP2_METHODDEF
12298 OS_LOCKF_METHODDEF
12299 OS_LSEEK_METHODDEF
12300 OS_READ_METHODDEF
12301 OS_READV_METHODDEF
12302 OS_PREAD_METHODDEF
12303 OS_WRITE_METHODDEF
12304 OS_WRITEV_METHODDEF
12305 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012306#ifdef HAVE_SENDFILE
12307 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12308 posix_sendfile__doc__},
12309#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012310 OS_FSTAT_METHODDEF
12311 OS_ISATTY_METHODDEF
12312 OS_PIPE_METHODDEF
12313 OS_PIPE2_METHODDEF
12314 OS_MKFIFO_METHODDEF
12315 OS_MKNOD_METHODDEF
12316 OS_MAJOR_METHODDEF
12317 OS_MINOR_METHODDEF
12318 OS_MAKEDEV_METHODDEF
12319 OS_FTRUNCATE_METHODDEF
12320 OS_TRUNCATE_METHODDEF
12321 OS_POSIX_FALLOCATE_METHODDEF
12322 OS_POSIX_FADVISE_METHODDEF
12323 OS_PUTENV_METHODDEF
12324 OS_UNSETENV_METHODDEF
12325 OS_STRERROR_METHODDEF
12326 OS_FCHDIR_METHODDEF
12327 OS_FSYNC_METHODDEF
12328 OS_SYNC_METHODDEF
12329 OS_FDATASYNC_METHODDEF
12330 OS_WCOREDUMP_METHODDEF
12331 OS_WIFCONTINUED_METHODDEF
12332 OS_WIFSTOPPED_METHODDEF
12333 OS_WIFSIGNALED_METHODDEF
12334 OS_WIFEXITED_METHODDEF
12335 OS_WEXITSTATUS_METHODDEF
12336 OS_WTERMSIG_METHODDEF
12337 OS_WSTOPSIG_METHODDEF
12338 OS_FSTATVFS_METHODDEF
12339 OS_STATVFS_METHODDEF
12340 OS_CONFSTR_METHODDEF
12341 OS_SYSCONF_METHODDEF
12342 OS_FPATHCONF_METHODDEF
12343 OS_PATHCONF_METHODDEF
12344 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012345 OS__GETFULLPATHNAME_METHODDEF
12346 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012347 OS__GETDISKUSAGE_METHODDEF
12348 OS__GETFINALPATHNAME_METHODDEF
12349 OS__GETVOLUMEPATHNAME_METHODDEF
12350 OS_GETLOADAVG_METHODDEF
12351 OS_URANDOM_METHODDEF
12352 OS_SETRESUID_METHODDEF
12353 OS_SETRESGID_METHODDEF
12354 OS_GETRESUID_METHODDEF
12355 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012356
Larry Hastings2f936352014-08-05 14:04:04 +100012357 OS_GETXATTR_METHODDEF
12358 OS_SETXATTR_METHODDEF
12359 OS_REMOVEXATTR_METHODDEF
12360 OS_LISTXATTR_METHODDEF
12361
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012362#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12363 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12364#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012365 OS_CPU_COUNT_METHODDEF
12366 OS_GET_INHERITABLE_METHODDEF
12367 OS_SET_INHERITABLE_METHODDEF
12368 OS_GET_HANDLE_INHERITABLE_METHODDEF
12369 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012370#ifndef MS_WINDOWS
12371 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12372 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12373#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012374 {"scandir", (PyCFunction)posix_scandir,
12375 METH_VARARGS | METH_KEYWORDS,
12376 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012377 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012378};
12379
12380
Brian Curtin52173d42010-12-02 18:29:18 +000012381#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012382static int
Brian Curtin52173d42010-12-02 18:29:18 +000012383enable_symlink()
12384{
12385 HANDLE tok;
12386 TOKEN_PRIVILEGES tok_priv;
12387 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012388
12389 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012390 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012391
12392 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012393 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012394
12395 tok_priv.PrivilegeCount = 1;
12396 tok_priv.Privileges[0].Luid = luid;
12397 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12398
12399 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12400 sizeof(TOKEN_PRIVILEGES),
12401 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012402 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012403
Brian Curtin3b4499c2010-12-28 14:31:47 +000012404 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12405 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012406}
12407#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12408
Barry Warsaw4a342091996-12-19 23:50:02 +000012409static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012410all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012411{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012412#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012413 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012414#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012415#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012416 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012417#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012418#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012419 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012420#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012421#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012422 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012423#endif
Fred Drakec9680921999-12-13 16:37:25 +000012424#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012425 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012426#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012427#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012428 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012429#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012430#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012431 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012432#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012433#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012434 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012435#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012436#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012437 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012438#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012439#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012441#endif
12442#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012443 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012444#endif
12445#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012446 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012447#endif
12448#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012449 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012450#endif
12451#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012453#endif
12454#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012456#endif
12457#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012459#endif
12460#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012462#endif
12463#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012464 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012465#endif
12466#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012468#endif
12469#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012471#endif
12472#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012473 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012474#endif
12475#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012477#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012478#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012480#endif
12481#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012483#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012484#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012486#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012487#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012489#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012490#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012491 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012492#endif
12493#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012494 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012495#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012496#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012497 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012498#endif
12499#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012500 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012501#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012502#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012503 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012504#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012505#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012506 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012507#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012508#ifdef O_TMPFILE
12509 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12510#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012511#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012512 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012513#endif
12514#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012516#endif
12517#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012518 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012519#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012520#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012522#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012523#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012525#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012526
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012527
Jesus Cea94363612012-06-22 18:32:07 +020012528#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012529 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012530#endif
12531#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012532 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012533#endif
12534
Tim Peters5aa91602002-01-30 05:46:57 +000012535/* MS Windows */
12536#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012537 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012538 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012539#endif
12540#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012541 /* Optimize for short life (keep in memory). */
12542 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012544#endif
12545#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012548#endif
12549#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012550 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012551 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012552#endif
12553#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012554 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012556#endif
12557
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012558/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012559#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012560 /* Send a SIGIO signal whenever input or output
12561 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012563#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012564#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012567#endif
12568#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012569 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012571#endif
12572#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012573 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012575#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012576#ifdef O_NOLINKS
12577 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012579#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012580#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012581 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012583#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012584
Victor Stinner8c62be82010-05-06 00:08:46 +000012585 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012586#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012588#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012589#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012591#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012592#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012594#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012595#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012597#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012598#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012600#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012601#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012602 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012603#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012604#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012605 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012606#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012607#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012608 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012609#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012610#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012611 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012612#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012613#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012614 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012615#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012616#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012617 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012618#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012619#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012620 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012621#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012622#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012623 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012624#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012625#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012626 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012627#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012628#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012629 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012630#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012631#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012633#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012634#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012636#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012637
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012638 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012639#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012640 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012641#endif /* ST_RDONLY */
12642#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012643 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012644#endif /* ST_NOSUID */
12645
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012646 /* GNU extensions */
12647#ifdef ST_NODEV
12648 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12649#endif /* ST_NODEV */
12650#ifdef ST_NOEXEC
12651 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12652#endif /* ST_NOEXEC */
12653#ifdef ST_SYNCHRONOUS
12654 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12655#endif /* ST_SYNCHRONOUS */
12656#ifdef ST_MANDLOCK
12657 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12658#endif /* ST_MANDLOCK */
12659#ifdef ST_WRITE
12660 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12661#endif /* ST_WRITE */
12662#ifdef ST_APPEND
12663 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12664#endif /* ST_APPEND */
12665#ifdef ST_NOATIME
12666 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12667#endif /* ST_NOATIME */
12668#ifdef ST_NODIRATIME
12669 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12670#endif /* ST_NODIRATIME */
12671#ifdef ST_RELATIME
12672 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12673#endif /* ST_RELATIME */
12674
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012675 /* FreeBSD sendfile() constants */
12676#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012678#endif
12679#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012681#endif
12682#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012684#endif
12685
Ross Lagerwall7807c352011-03-17 20:20:30 +020012686 /* constants for posix_fadvise */
12687#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012688 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012689#endif
12690#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012691 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012692#endif
12693#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012694 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012695#endif
12696#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012697 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012698#endif
12699#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012701#endif
12702#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012704#endif
12705
12706 /* constants for waitid */
12707#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12709 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12710 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012711#endif
12712#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012714#endif
12715#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012716 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012717#endif
12718#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012719 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012720#endif
12721#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012722 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012723#endif
12724#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012726#endif
12727#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012729#endif
12730#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012732#endif
12733
12734 /* constants for lockf */
12735#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012736 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012737#endif
12738#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012739 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012740#endif
12741#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012742 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012743#endif
12744#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012745 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012746#endif
12747
Guido van Rossum246bc171999-02-01 23:54:31 +000012748#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12750 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12751 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12752 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12753 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012754#endif
12755
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012756#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12758 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12759 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012760#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012761 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012762#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012763#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012764 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012765#endif
12766#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012767 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012768#endif
12769#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012770 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012771#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012772#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012773 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012774#endif
12775#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012776 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012777#endif
12778#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012780#endif
12781#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012782 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012783#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012784#endif
12785
Benjamin Peterson9428d532011-09-14 11:45:52 -040012786#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012787 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12788 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12789 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012790#endif
12791
Victor Stinner8b905bd2011-10-25 13:34:04 +020012792#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012793 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012794#endif
12795#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012796 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012797#endif
12798#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012799 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012800#endif
12801#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012802 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012803#endif
12804#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012805 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012806#endif
12807#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012808 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012809#endif
12810#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012811 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012812#endif
12813
Victor Stinner8c62be82010-05-06 00:08:46 +000012814 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012815}
12816
12817
Martin v. Löwis1a214512008-06-11 05:26:20 +000012818static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012819 PyModuleDef_HEAD_INIT,
12820 MODNAME,
12821 posix__doc__,
12822 -1,
12823 posix_methods,
12824 NULL,
12825 NULL,
12826 NULL,
12827 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012828};
12829
12830
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012831static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012832
12833#ifdef HAVE_FACCESSAT
12834 "HAVE_FACCESSAT",
12835#endif
12836
12837#ifdef HAVE_FCHDIR
12838 "HAVE_FCHDIR",
12839#endif
12840
12841#ifdef HAVE_FCHMOD
12842 "HAVE_FCHMOD",
12843#endif
12844
12845#ifdef HAVE_FCHMODAT
12846 "HAVE_FCHMODAT",
12847#endif
12848
12849#ifdef HAVE_FCHOWN
12850 "HAVE_FCHOWN",
12851#endif
12852
Larry Hastings00964ed2013-08-12 13:49:30 -040012853#ifdef HAVE_FCHOWNAT
12854 "HAVE_FCHOWNAT",
12855#endif
12856
Larry Hastings9cf065c2012-06-22 16:30:09 -070012857#ifdef HAVE_FEXECVE
12858 "HAVE_FEXECVE",
12859#endif
12860
12861#ifdef HAVE_FDOPENDIR
12862 "HAVE_FDOPENDIR",
12863#endif
12864
Georg Brandl306336b2012-06-24 12:55:33 +020012865#ifdef HAVE_FPATHCONF
12866 "HAVE_FPATHCONF",
12867#endif
12868
Larry Hastings9cf065c2012-06-22 16:30:09 -070012869#ifdef HAVE_FSTATAT
12870 "HAVE_FSTATAT",
12871#endif
12872
12873#ifdef HAVE_FSTATVFS
12874 "HAVE_FSTATVFS",
12875#endif
12876
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012877#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012878 "HAVE_FTRUNCATE",
12879#endif
12880
Larry Hastings9cf065c2012-06-22 16:30:09 -070012881#ifdef HAVE_FUTIMENS
12882 "HAVE_FUTIMENS",
12883#endif
12884
12885#ifdef HAVE_FUTIMES
12886 "HAVE_FUTIMES",
12887#endif
12888
12889#ifdef HAVE_FUTIMESAT
12890 "HAVE_FUTIMESAT",
12891#endif
12892
12893#ifdef HAVE_LINKAT
12894 "HAVE_LINKAT",
12895#endif
12896
12897#ifdef HAVE_LCHFLAGS
12898 "HAVE_LCHFLAGS",
12899#endif
12900
12901#ifdef HAVE_LCHMOD
12902 "HAVE_LCHMOD",
12903#endif
12904
12905#ifdef HAVE_LCHOWN
12906 "HAVE_LCHOWN",
12907#endif
12908
12909#ifdef HAVE_LSTAT
12910 "HAVE_LSTAT",
12911#endif
12912
12913#ifdef HAVE_LUTIMES
12914 "HAVE_LUTIMES",
12915#endif
12916
12917#ifdef HAVE_MKDIRAT
12918 "HAVE_MKDIRAT",
12919#endif
12920
12921#ifdef HAVE_MKFIFOAT
12922 "HAVE_MKFIFOAT",
12923#endif
12924
12925#ifdef HAVE_MKNODAT
12926 "HAVE_MKNODAT",
12927#endif
12928
12929#ifdef HAVE_OPENAT
12930 "HAVE_OPENAT",
12931#endif
12932
12933#ifdef HAVE_READLINKAT
12934 "HAVE_READLINKAT",
12935#endif
12936
12937#ifdef HAVE_RENAMEAT
12938 "HAVE_RENAMEAT",
12939#endif
12940
12941#ifdef HAVE_SYMLINKAT
12942 "HAVE_SYMLINKAT",
12943#endif
12944
12945#ifdef HAVE_UNLINKAT
12946 "HAVE_UNLINKAT",
12947#endif
12948
12949#ifdef HAVE_UTIMENSAT
12950 "HAVE_UTIMENSAT",
12951#endif
12952
12953#ifdef MS_WINDOWS
12954 "MS_WINDOWS",
12955#endif
12956
12957 NULL
12958};
12959
12960
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012961PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012962INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012963{
Victor Stinner8c62be82010-05-06 00:08:46 +000012964 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012965 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012966 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012967
Brian Curtin52173d42010-12-02 18:29:18 +000012968#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012969 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012970#endif
12971
Victor Stinner8c62be82010-05-06 00:08:46 +000012972 m = PyModule_Create(&posixmodule);
12973 if (m == NULL)
12974 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012975
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 /* Initialize environ dictionary */
12977 v = convertenviron();
12978 Py_XINCREF(v);
12979 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12980 return NULL;
12981 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012982
Victor Stinner8c62be82010-05-06 00:08:46 +000012983 if (all_ins(m))
12984 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012985
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 if (setup_confname_tables(m))
12987 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012988
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 Py_INCREF(PyExc_OSError);
12990 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012991
Guido van Rossumb3d39562000-01-31 18:41:26 +000012992#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012993 if (posix_putenv_garbage == NULL)
12994 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012995#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012996
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012998#if defined(HAVE_WAITID) && !defined(__APPLE__)
12999 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013000 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
13001 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020013002#endif
13003
Christian Heimes25827622013-10-12 01:27:08 +020013004 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000013005 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
13006 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13007 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013008 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13009 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013010 structseq_new = StatResultType.tp_new;
13011 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013012
Christian Heimes25827622013-10-12 01:27:08 +020013013 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013014 if (PyStructSequence_InitType2(&StatVFSResultType,
13015 &statvfs_result_desc) < 0)
13016 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013017#ifdef NEED_TICKS_PER_SECOND
13018# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013019 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013020# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013021 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013022# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013023 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013024# endif
13025#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013026
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013027#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013028 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013029 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13030 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013031 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013032#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013033
13034 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013035 if (PyStructSequence_InitType2(&TerminalSizeType,
13036 &TerminalSize_desc) < 0)
13037 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013038
13039 /* initialize scandir types */
13040 if (PyType_Ready(&ScandirIteratorType) < 0)
13041 return NULL;
13042 if (PyType_Ready(&DirEntryType) < 0)
13043 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013044 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013045#if defined(HAVE_WAITID) && !defined(__APPLE__)
13046 Py_INCREF((PyObject*) &WaitidResultType);
13047 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13048#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013049 Py_INCREF((PyObject*) &StatResultType);
13050 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13051 Py_INCREF((PyObject*) &StatVFSResultType);
13052 PyModule_AddObject(m, "statvfs_result",
13053 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013054
13055#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013056 Py_INCREF(&SchedParamType);
13057 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013058#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013059
Larry Hastings605a62d2012-06-24 04:33:36 -070013060 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013061 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13062 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013063 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13064
13065 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013066 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13067 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013068 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13069
Thomas Wouters477c8d52006-05-27 19:21:47 +000013070#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013071 /*
13072 * Step 2 of weak-linking support on Mac OS X.
13073 *
13074 * The code below removes functions that are not available on the
13075 * currently active platform.
13076 *
13077 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013078 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013079 * OSX 10.4.
13080 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013081#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013082 if (fstatvfs == NULL) {
13083 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13084 return NULL;
13085 }
13086 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013087#endif /* HAVE_FSTATVFS */
13088
13089#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013090 if (statvfs == NULL) {
13091 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13092 return NULL;
13093 }
13094 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013095#endif /* HAVE_STATVFS */
13096
13097# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013098 if (lchown == NULL) {
13099 if (PyObject_DelAttrString(m, "lchown") == -1) {
13100 return NULL;
13101 }
13102 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013103#endif /* HAVE_LCHOWN */
13104
13105
13106#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013107
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013108 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013109 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13110
Larry Hastings6fe20b32012-04-19 15:07:49 -070013111 billion = PyLong_FromLong(1000000000);
13112 if (!billion)
13113 return NULL;
13114
Larry Hastings9cf065c2012-06-22 16:30:09 -070013115 /* suppress "function not used" warnings */
13116 {
13117 int ignored;
13118 fd_specified("", -1);
13119 follow_symlinks_specified("", 1);
13120 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13121 dir_fd_converter(Py_None, &ignored);
13122 dir_fd_unavailable(Py_None, &ignored);
13123 }
13124
13125 /*
13126 * provide list of locally available functions
13127 * so os.py can populate support_* lists
13128 */
13129 list = PyList_New(0);
13130 if (!list)
13131 return NULL;
13132 for (trace = have_functions; *trace; trace++) {
13133 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13134 if (!unicode)
13135 return NULL;
13136 if (PyList_Append(list, unicode))
13137 return NULL;
13138 Py_DECREF(unicode);
13139 }
13140 PyModule_AddObject(m, "_have_functions", list);
13141
13142 initialized = 1;
13143
Victor Stinner8c62be82010-05-06 00:08:46 +000013144 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013145}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013146
13147#ifdef __cplusplus
13148}
13149#endif