blob: 710bcde812934cfb4baded9e2dd272af0283cf80 [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
952argument_unavailable_error(char *function_name, char *argument_name) {
953 PyErr_Format(PyExc_NotImplementedError,
954 "%s%s%s unavailable on this platform",
955 (function_name != NULL) ? function_name : "",
956 (function_name != NULL) ? ": ": "",
957 argument_name);
958}
959
960static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200961dir_fd_unavailable(PyObject *o, void *p)
962{
963 int dir_fd;
964 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700965 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200966 if (dir_fd != DEFAULT_DIR_FD) {
967 argument_unavailable_error(NULL, "dir_fd");
968 return 0;
969 }
970 *(int *)p = dir_fd;
971 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700972}
973
974static int
975fd_specified(char *function_name, int fd) {
976 if (fd == -1)
977 return 0;
978
979 argument_unavailable_error(function_name, "fd");
980 return 1;
981}
982
983static int
984follow_symlinks_specified(char *function_name, int follow_symlinks) {
985 if (follow_symlinks)
986 return 0;
987
988 argument_unavailable_error(function_name, "follow_symlinks");
989 return 1;
990}
991
992static int
993path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
994 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
995 PyErr_Format(PyExc_ValueError,
996 "%s: can't specify dir_fd without matching path",
997 function_name);
998 return 1;
999 }
1000 return 0;
1001}
1002
1003static int
1004dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
1005 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1006 PyErr_Format(PyExc_ValueError,
1007 "%s: can't specify both dir_fd and fd",
1008 function_name);
1009 return 1;
1010 }
1011 return 0;
1012}
1013
1014static int
1015fd_and_follow_symlinks_invalid(char *function_name, int fd,
1016 int follow_symlinks) {
1017 if ((fd > 0) && (!follow_symlinks)) {
1018 PyErr_Format(PyExc_ValueError,
1019 "%s: cannot use fd and follow_symlinks together",
1020 function_name);
1021 return 1;
1022 }
1023 return 0;
1024}
1025
1026static int
1027dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1028 int follow_symlinks) {
1029 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1030 PyErr_Format(PyExc_ValueError,
1031 "%s: cannot use dir_fd and follow_symlinks together",
1032 function_name);
1033 return 1;
1034 }
1035 return 0;
1036}
1037
Larry Hastings2f936352014-08-05 14:04:04 +10001038#ifdef MS_WINDOWS
1039 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001040#else
Larry Hastings2f936352014-08-05 14:04:04 +10001041 typedef off_t Py_off_t;
1042#endif
1043
1044static int
1045Py_off_t_converter(PyObject *arg, void *addr)
1046{
1047#ifdef HAVE_LARGEFILE_SUPPORT
1048 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1049#else
1050 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001051#endif
1052 if (PyErr_Occurred())
1053 return 0;
1054 return 1;
1055}
Larry Hastings2f936352014-08-05 14:04:04 +10001056
1057static PyObject *
1058PyLong_FromPy_off_t(Py_off_t offset)
1059{
1060#ifdef HAVE_LARGEFILE_SUPPORT
1061 return PyLong_FromLongLong(offset);
1062#else
1063 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001064#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001065}
1066
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001067
Steve Dowerd81431f2015-03-06 14:47:02 -08001068#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1069/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1070 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001071 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001072#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001074#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001075#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001076#define _NO_CONSOLE_FILENO (intptr_t)-2
1077
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001078/* the special case of checking dup2. The target fd must be in a sensible range */
1079static int
1080_PyVerify_fd_dup2(int fd1, int fd2)
1081{
Victor Stinner8c62be82010-05-06 00:08:46 +00001082 if (!_PyVerify_fd(fd1))
1083 return 0;
1084 if (fd2 == _NO_CONSOLE_FILENO)
1085 return 0;
1086 if ((unsigned)fd2 < _NHANDLE_)
1087 return 1;
1088 else
1089 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001090}
1091#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001092#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001093#endif
1094
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001095#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001096
1097static int
Brian Curtind25aef52011-06-13 15:16:04 -05001098win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001099{
1100 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1101 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1102 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001103
1104 if (0 == DeviceIoControl(
1105 reparse_point_handle,
1106 FSCTL_GET_REPARSE_POINT,
1107 NULL, 0, /* in buffer */
1108 target_buffer, sizeof(target_buffer),
1109 &n_bytes_returned,
1110 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001111 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112
1113 if (reparse_tag)
1114 *reparse_tag = rdb->ReparseTag;
1115
Brian Curtind25aef52011-06-13 15:16:04 -05001116 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001117}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001118
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001119#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001120
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001121/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001122#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001123/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001124** environ directly, we must obtain it with _NSGetEnviron(). See also
1125** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001126*/
1127#include <crt_externs.h>
1128static char **environ;
1129#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001131#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001132
Barry Warsaw53699e91996-12-10 23:23:01 +00001133static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001134convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001135{
Victor Stinner8c62be82010-05-06 00:08:46 +00001136 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001137#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001139#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001140 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001141#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001142
Victor Stinner8c62be82010-05-06 00:08:46 +00001143 d = PyDict_New();
1144 if (d == NULL)
1145 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001146#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001147 if (environ == NULL)
1148 environ = *_NSGetEnviron();
1149#endif
1150#ifdef MS_WINDOWS
1151 /* _wenviron must be initialized in this way if the program is started
1152 through main() instead of wmain(). */
1153 _wgetenv(L"");
1154 if (_wenviron == NULL)
1155 return d;
1156 /* This part ignores errors */
1157 for (e = _wenviron; *e != NULL; e++) {
1158 PyObject *k;
1159 PyObject *v;
1160 wchar_t *p = wcschr(*e, L'=');
1161 if (p == NULL)
1162 continue;
1163 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1164 if (k == NULL) {
1165 PyErr_Clear();
1166 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001167 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001168 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1169 if (v == NULL) {
1170 PyErr_Clear();
1171 Py_DECREF(k);
1172 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001173 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001174 if (PyDict_GetItem(d, k) == NULL) {
1175 if (PyDict_SetItem(d, k, v) != 0)
1176 PyErr_Clear();
1177 }
1178 Py_DECREF(k);
1179 Py_DECREF(v);
1180 }
1181#else
1182 if (environ == NULL)
1183 return d;
1184 /* This part ignores errors */
1185 for (e = environ; *e != NULL; e++) {
1186 PyObject *k;
1187 PyObject *v;
1188 char *p = strchr(*e, '=');
1189 if (p == NULL)
1190 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001191 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 if (k == NULL) {
1193 PyErr_Clear();
1194 continue;
1195 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001196 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001197 if (v == NULL) {
1198 PyErr_Clear();
1199 Py_DECREF(k);
1200 continue;
1201 }
1202 if (PyDict_GetItem(d, k) == NULL) {
1203 if (PyDict_SetItem(d, k, v) != 0)
1204 PyErr_Clear();
1205 }
1206 Py_DECREF(k);
1207 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001208 }
1209#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001210 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001211}
1212
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001213/* Set a POSIX-specific error from errno, and return NULL */
1214
Barry Warsawd58d7641998-07-23 16:14:40 +00001215static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001216posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001217{
Victor Stinner8c62be82010-05-06 00:08:46 +00001218 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001219}
Mark Hammondef8b6542001-05-13 08:04:26 +00001220
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001221#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001222static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001223win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001224{
Victor Stinner8c62be82010-05-06 00:08:46 +00001225 /* XXX We should pass the function name along in the future.
1226 (winreg.c also wants to pass the function name.)
1227 This would however require an additional param to the
1228 Windows error object, which is non-trivial.
1229 */
1230 errno = GetLastError();
1231 if (filename)
1232 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1233 else
1234 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001235}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001236
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001237static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001238win32_error_object(char* function, PyObject* filename)
1239{
1240 /* XXX - see win32_error for comments on 'function' */
1241 errno = GetLastError();
1242 if (filename)
1243 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001244 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001245 errno,
1246 filename);
1247 else
1248 return PyErr_SetFromWindowsErr(errno);
1249}
1250
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001251#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001252
Larry Hastings9cf065c2012-06-22 16:30:09 -07001253static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001254path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001255{
1256#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001257 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1258 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001259#else
Victor Stinner292c8352012-10-30 02:17:38 +01001260 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001261#endif
1262}
1263
Larry Hastings31826802013-10-19 00:09:25 -07001264
Larry Hastingsb0827312014-02-09 22:05:19 -08001265static PyObject *
1266path_error2(path_t *path, path_t *path2)
1267{
1268#ifdef MS_WINDOWS
1269 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1270 0, path->object, path2->object);
1271#else
1272 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1273 path->object, path2->object);
1274#endif
1275}
1276
1277
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001278/* POSIX generic methods */
1279
Larry Hastings2f936352014-08-05 14:04:04 +10001280static int
1281fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001282{
Victor Stinner8c62be82010-05-06 00:08:46 +00001283 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001284 int *pointer = (int *)p;
1285 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001286 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001287 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001288 *pointer = fd;
1289 return 1;
1290}
1291
1292static PyObject *
1293posix_fildes_fd(int fd, int (*func)(int))
1294{
1295 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001296 int async_err = 0;
1297
Steve Dower8fc89802015-04-12 00:26:27 -04001298 if (!_PyVerify_fd(fd))
1299 return posix_error();
1300
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001301 do {
1302 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001303 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001304 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001305 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001306 Py_END_ALLOW_THREADS
1307 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1308 if (res != 0)
1309 return (!async_err) ? posix_error() : NULL;
1310 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001311}
Guido van Rossum21142a01999-01-08 21:05:37 +00001312
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001313
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001314#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001315/* This is a reimplementation of the C library's chdir function,
1316 but one that produces Win32 errors instead of DOS error codes.
1317 chdir is essentially a wrapper around SetCurrentDirectory; however,
1318 it also needs to set "magic" environment variables indicating
1319 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001320static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001321win32_chdir(LPCSTR path)
1322{
Victor Stinner75875072013-11-24 19:23:25 +01001323 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001324 int result;
1325 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001326
Victor Stinner8c62be82010-05-06 00:08:46 +00001327 if(!SetCurrentDirectoryA(path))
1328 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001329 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001330 if (!result)
1331 return FALSE;
1332 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001333 than MAX_PATH-1 (not including the final null character). */
1334 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001335 if (strncmp(new_path, "\\\\", 2) == 0 ||
1336 strncmp(new_path, "//", 2) == 0)
1337 /* UNC path, nothing to do. */
1338 return TRUE;
1339 env[1] = new_path[0];
1340 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341}
1342
1343/* The Unicode version differs from the ANSI version
1344 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001345static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346win32_wchdir(LPCWSTR path)
1347{
Victor Stinnered537822015-12-13 21:40:26 +01001348 wchar_t path_buf[MAX_PATH], *new_path = path_buf;
Victor Stinner8c62be82010-05-06 00:08:46 +00001349 int result;
1350 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001351
Victor Stinner8c62be82010-05-06 00:08:46 +00001352 if(!SetCurrentDirectoryW(path))
1353 return FALSE;
Victor Stinnered537822015-12-13 21:40:26 +01001354 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(path_buf), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001355 if (!result)
1356 return FALSE;
Victor Stinnere847d712015-12-14 00:21:50 +01001357 if (result > Py_ARRAY_LENGTH(path_buf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001358 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001359 if (!new_path) {
1360 SetLastError(ERROR_OUTOFMEMORY);
1361 return FALSE;
1362 }
1363 result = GetCurrentDirectoryW(result, new_path);
1364 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001365 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001366 return FALSE;
1367 }
1368 }
1369 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1370 wcsncmp(new_path, L"//", 2) == 0)
1371 /* UNC path, nothing to do. */
1372 return TRUE;
1373 env[1] = new_path[0];
1374 result = SetEnvironmentVariableW(env, new_path);
Victor Stinnered537822015-12-13 21:40:26 +01001375 if (new_path != path_buf)
Victor Stinnerb6404912013-07-07 16:21:41 +02001376 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001377 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001378}
1379#endif
1380
Martin v. Löwis14694662006-02-03 12:54:16 +00001381#ifdef MS_WINDOWS
1382/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1383 - time stamps are restricted to second resolution
1384 - file modification times suffer from forth-and-back conversions between
1385 UTC and local time
1386 Therefore, we implement our own stat, based on the Win32 API directly.
1387*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001388#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001389#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001390
Guido van Rossumd8faa362007-04-27 19:54:29 +00001391static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001392attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001393{
Victor Stinner8c62be82010-05-06 00:08:46 +00001394 HANDLE hFindFile;
1395 WIN32_FIND_DATAA FileData;
1396 hFindFile = FindFirstFileA(pszFile, &FileData);
1397 if (hFindFile == INVALID_HANDLE_VALUE)
1398 return FALSE;
1399 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001400 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001401 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001402 info->dwFileAttributes = FileData.dwFileAttributes;
1403 info->ftCreationTime = FileData.ftCreationTime;
1404 info->ftLastAccessTime = FileData.ftLastAccessTime;
1405 info->ftLastWriteTime = FileData.ftLastWriteTime;
1406 info->nFileSizeHigh = FileData.nFileSizeHigh;
1407 info->nFileSizeLow = FileData.nFileSizeLow;
1408/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001409 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1410 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001411 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001412}
1413
Victor Stinner6036e442015-03-08 01:58:04 +01001414static void
1415find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1416 BY_HANDLE_FILE_INFORMATION *info,
1417 ULONG *reparse_tag)
1418{
1419 memset(info, 0, sizeof(*info));
1420 info->dwFileAttributes = pFileData->dwFileAttributes;
1421 info->ftCreationTime = pFileData->ftCreationTime;
1422 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1423 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1424 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1425 info->nFileSizeLow = pFileData->nFileSizeLow;
1426/* info->nNumberOfLinks = 1; */
1427 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1428 *reparse_tag = pFileData->dwReserved0;
1429 else
1430 *reparse_tag = 0;
1431}
1432
Guido van Rossumd8faa362007-04-27 19:54:29 +00001433static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001434attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001435{
Victor Stinner8c62be82010-05-06 00:08:46 +00001436 HANDLE hFindFile;
1437 WIN32_FIND_DATAW FileData;
1438 hFindFile = FindFirstFileW(pszFile, &FileData);
1439 if (hFindFile == INVALID_HANDLE_VALUE)
1440 return FALSE;
1441 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001442 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001443 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001444}
1445
Brian Curtind25aef52011-06-13 15:16:04 -05001446static BOOL
1447get_target_path(HANDLE hdl, wchar_t **target_path)
1448{
1449 int buf_size, result_length;
1450 wchar_t *buf;
1451
1452 /* We have a good handle to the target, use it to determine
1453 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001454 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1455 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001456 if(!buf_size)
1457 return FALSE;
1458
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001459 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001460 if (!buf) {
1461 SetLastError(ERROR_OUTOFMEMORY);
1462 return FALSE;
1463 }
1464
Steve Dower2ea51c92015-03-20 21:49:12 -07001465 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001466 buf, buf_size, VOLUME_NAME_DOS);
1467
1468 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001469 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001470 return FALSE;
1471 }
1472
1473 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001474 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001475 return FALSE;
1476 }
1477
1478 buf[result_length] = 0;
1479
1480 *target_path = buf;
1481 return TRUE;
1482}
1483
1484static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001485win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001486 BOOL traverse);
1487static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001488win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001489 BOOL traverse)
1490{
Victor Stinner26de69d2011-06-17 15:15:38 +02001491 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001492 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001493 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001494 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001495 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001496 const char *dot;
1497
1498 hFile = CreateFileA(
1499 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001500 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001501 0, /* share mode */
1502 NULL, /* security attributes */
1503 OPEN_EXISTING,
1504 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001505 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1506 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001507 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001508 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1509 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001510 NULL);
1511
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001512 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001513 /* Either the target doesn't exist, or we don't have access to
1514 get a handle to it. If the former, we need to return an error.
1515 If the latter, we can use attributes_from_dir. */
1516 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001517 return -1;
1518 /* Could not get attributes on open file. Fall back to
1519 reading the directory. */
1520 if (!attributes_from_dir(path, &info, &reparse_tag))
1521 /* Very strange. This should not fail now */
1522 return -1;
1523 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1524 if (traverse) {
1525 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001526 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001527 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001528 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001529 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001530 } else {
1531 if (!GetFileInformationByHandle(hFile, &info)) {
1532 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001533 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001534 }
1535 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001536 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1537 return -1;
1538
1539 /* Close the outer open file handle now that we're about to
1540 reopen it with different flags. */
1541 if (!CloseHandle(hFile))
1542 return -1;
1543
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001544 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001545 /* In order to call GetFinalPathNameByHandle we need to open
1546 the file without the reparse handling flag set. */
1547 hFile2 = CreateFileA(
1548 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1549 NULL, OPEN_EXISTING,
1550 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1551 NULL);
1552 if (hFile2 == INVALID_HANDLE_VALUE)
1553 return -1;
1554
1555 if (!get_target_path(hFile2, &target_path))
1556 return -1;
1557
1558 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001559 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001560 return code;
1561 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001562 } else
1563 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001564 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001565 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001566
1567 /* Set S_IEXEC if it is an .exe, .bat, ... */
1568 dot = strrchr(path, '.');
1569 if (dot) {
1570 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1571 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1572 result->st_mode |= 0111;
1573 }
1574 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575}
1576
1577static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001578win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001579 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001580{
1581 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001582 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001583 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001584 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001585 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 const wchar_t *dot;
1587
1588 hFile = CreateFileW(
1589 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001590 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001591 0, /* share mode */
1592 NULL, /* security attributes */
1593 OPEN_EXISTING,
1594 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001595 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1596 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001597 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001598 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001599 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001600 NULL);
1601
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001602 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001603 /* Either the target doesn't exist, or we don't have access to
1604 get a handle to it. If the former, we need to return an error.
1605 If the latter, we can use attributes_from_dir. */
1606 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001607 return -1;
1608 /* Could not get attributes on open file. Fall back to
1609 reading the directory. */
1610 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1611 /* Very strange. This should not fail now */
1612 return -1;
1613 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1614 if (traverse) {
1615 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001616 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001617 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001618 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001619 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001620 } else {
1621 if (!GetFileInformationByHandle(hFile, &info)) {
1622 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001623 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001624 }
1625 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001626 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1627 return -1;
1628
1629 /* Close the outer open file handle now that we're about to
1630 reopen it with different flags. */
1631 if (!CloseHandle(hFile))
1632 return -1;
1633
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001634 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001635 /* In order to call GetFinalPathNameByHandle we need to open
1636 the file without the reparse handling flag set. */
1637 hFile2 = CreateFileW(
1638 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1639 NULL, OPEN_EXISTING,
1640 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1641 NULL);
1642 if (hFile2 == INVALID_HANDLE_VALUE)
1643 return -1;
1644
1645 if (!get_target_path(hFile2, &target_path))
1646 return -1;
1647
1648 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001649 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001650 return code;
1651 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001652 } else
1653 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001654 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001655 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001656
1657 /* Set S_IEXEC if it is an .exe, .bat, ... */
1658 dot = wcsrchr(path, '.');
1659 if (dot) {
1660 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1661 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1662 result->st_mode |= 0111;
1663 }
1664 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001665}
1666
1667static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001668win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001669{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001670 /* Protocol violation: we explicitly clear errno, instead of
1671 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001672 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001673 errno = 0;
1674 return code;
1675}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001676
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001677static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001678win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001679{
1680 /* Protocol violation: we explicitly clear errno, instead of
1681 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001682 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001683 errno = 0;
1684 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001685}
Brian Curtind25aef52011-06-13 15:16:04 -05001686/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001687
1688 In Posix, stat automatically traverses symlinks and returns the stat
1689 structure for the target. In Windows, the equivalent GetFileAttributes by
1690 default does not traverse symlinks and instead returns attributes for
1691 the symlink.
1692
1693 Therefore, win32_lstat will get the attributes traditionally, and
1694 win32_stat will first explicitly resolve the symlink target and then will
1695 call win32_lstat on that result.
1696
Ezio Melotti4969f702011-03-15 05:59:46 +02001697 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001698
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001699static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001700win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001701{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001702 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001703}
1704
Victor Stinner8c62be82010-05-06 00:08:46 +00001705static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001706win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001707{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001708 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001709}
1710
1711static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001712win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001713{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001714 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001715}
1716
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001717static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001718win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001719{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001720 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001721}
1722
Martin v. Löwis14694662006-02-03 12:54:16 +00001723#endif /* MS_WINDOWS */
1724
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001725PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001726"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001727This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001728 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001729or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1730\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001731Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1732or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001733\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001734See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001735
1736static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001737 {"st_mode", "protection bits"},
1738 {"st_ino", "inode"},
1739 {"st_dev", "device"},
1740 {"st_nlink", "number of hard links"},
1741 {"st_uid", "user ID of owner"},
1742 {"st_gid", "group ID of owner"},
1743 {"st_size", "total size, in bytes"},
1744 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1745 {NULL, "integer time of last access"},
1746 {NULL, "integer time of last modification"},
1747 {NULL, "integer time of last change"},
1748 {"st_atime", "time of last access"},
1749 {"st_mtime", "time of last modification"},
1750 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001751 {"st_atime_ns", "time of last access in nanoseconds"},
1752 {"st_mtime_ns", "time of last modification in nanoseconds"},
1753 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001754#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001755 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001756#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001757#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001758 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001759#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001760#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001761 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001762#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001763#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001764 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001765#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001766#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001767 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001768#endif
1769#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001771#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001772#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1773 {"st_file_attributes", "Windows file attribute bits"},
1774#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001775 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001776};
1777
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001778#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001779#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001781#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001782#endif
1783
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001784#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001785#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1786#else
1787#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1788#endif
1789
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001790#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001791#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1792#else
1793#define ST_RDEV_IDX ST_BLOCKS_IDX
1794#endif
1795
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001796#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1797#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1798#else
1799#define ST_FLAGS_IDX ST_RDEV_IDX
1800#endif
1801
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001802#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001803#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001804#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001805#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001806#endif
1807
1808#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1809#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1810#else
1811#define ST_BIRTHTIME_IDX ST_GEN_IDX
1812#endif
1813
Zachary Ware63f277b2014-06-19 09:46:37 -05001814#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1815#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1816#else
1817#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1818#endif
1819
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001820static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001821 "stat_result", /* name */
1822 stat_result__doc__, /* doc */
1823 stat_result_fields,
1824 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001825};
1826
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001827PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001828"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1829This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001830 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001831or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001832\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001833See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001834
1835static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001836 {"f_bsize", },
1837 {"f_frsize", },
1838 {"f_blocks", },
1839 {"f_bfree", },
1840 {"f_bavail", },
1841 {"f_files", },
1842 {"f_ffree", },
1843 {"f_favail", },
1844 {"f_flag", },
1845 {"f_namemax",},
1846 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001847};
1848
1849static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001850 "statvfs_result", /* name */
1851 statvfs_result__doc__, /* doc */
1852 statvfs_result_fields,
1853 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001854};
1855
Ross Lagerwall7807c352011-03-17 20:20:30 +02001856#if defined(HAVE_WAITID) && !defined(__APPLE__)
1857PyDoc_STRVAR(waitid_result__doc__,
1858"waitid_result: Result from waitid.\n\n\
1859This object may be accessed either as a tuple of\n\
1860 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1861or via the attributes si_pid, si_uid, and so on.\n\
1862\n\
1863See os.waitid for more information.");
1864
1865static PyStructSequence_Field waitid_result_fields[] = {
1866 {"si_pid", },
1867 {"si_uid", },
1868 {"si_signo", },
1869 {"si_status", },
1870 {"si_code", },
1871 {0}
1872};
1873
1874static PyStructSequence_Desc waitid_result_desc = {
1875 "waitid_result", /* name */
1876 waitid_result__doc__, /* doc */
1877 waitid_result_fields,
1878 5
1879};
1880static PyTypeObject WaitidResultType;
1881#endif
1882
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001883static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001884static PyTypeObject StatResultType;
1885static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001886#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001887static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001888#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001889static newfunc structseq_new;
1890
1891static PyObject *
1892statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1893{
Victor Stinner8c62be82010-05-06 00:08:46 +00001894 PyStructSequence *result;
1895 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001896
Victor Stinner8c62be82010-05-06 00:08:46 +00001897 result = (PyStructSequence*)structseq_new(type, args, kwds);
1898 if (!result)
1899 return NULL;
1900 /* If we have been initialized from a tuple,
1901 st_?time might be set to None. Initialize it
1902 from the int slots. */
1903 for (i = 7; i <= 9; i++) {
1904 if (result->ob_item[i+3] == Py_None) {
1905 Py_DECREF(Py_None);
1906 Py_INCREF(result->ob_item[i]);
1907 result->ob_item[i+3] = result->ob_item[i];
1908 }
1909 }
1910 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001911}
1912
1913
1914
1915/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001916static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001917
1918PyDoc_STRVAR(stat_float_times__doc__,
1919"stat_float_times([newval]) -> oldval\n\n\
1920Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001921\n\
1922If value is True, future calls to stat() return floats; if it is False,\n\
1923future calls return ints.\n\
1924If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001925
Larry Hastings2f936352014-08-05 14:04:04 +10001926/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001927static PyObject*
1928stat_float_times(PyObject* self, PyObject *args)
1929{
Victor Stinner8c62be82010-05-06 00:08:46 +00001930 int newval = -1;
1931 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1932 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001933 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1934 "stat_float_times() is deprecated",
1935 1))
1936 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001937 if (newval == -1)
1938 /* Return old value */
1939 return PyBool_FromLong(_stat_float_times);
1940 _stat_float_times = newval;
1941 Py_INCREF(Py_None);
1942 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001943}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001944
Larry Hastings6fe20b32012-04-19 15:07:49 -07001945static PyObject *billion = NULL;
1946
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001947static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001948fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001949{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001950 PyObject *s = _PyLong_FromTime_t(sec);
1951 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1952 PyObject *s_in_ns = NULL;
1953 PyObject *ns_total = NULL;
1954 PyObject *float_s = NULL;
1955
1956 if (!(s && ns_fractional))
1957 goto exit;
1958
1959 s_in_ns = PyNumber_Multiply(s, billion);
1960 if (!s_in_ns)
1961 goto exit;
1962
1963 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1964 if (!ns_total)
1965 goto exit;
1966
Victor Stinner4195b5c2012-02-08 23:03:19 +01001967 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001968 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1969 if (!float_s)
1970 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001971 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001972 else {
1973 float_s = s;
1974 Py_INCREF(float_s);
1975 }
1976
1977 PyStructSequence_SET_ITEM(v, index, s);
1978 PyStructSequence_SET_ITEM(v, index+3, float_s);
1979 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1980 s = NULL;
1981 float_s = NULL;
1982 ns_total = NULL;
1983exit:
1984 Py_XDECREF(s);
1985 Py_XDECREF(ns_fractional);
1986 Py_XDECREF(s_in_ns);
1987 Py_XDECREF(ns_total);
1988 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001989}
1990
Tim Peters5aa91602002-01-30 05:46:57 +00001991/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001992 (used by posix_stat() and posix_fstat()) */
1993static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001994_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001995{
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 unsigned long ansec, mnsec, cnsec;
1997 PyObject *v = PyStructSequence_New(&StatResultType);
1998 if (v == NULL)
1999 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00002000
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00002002#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002003 PyStructSequence_SET_ITEM(v, 1,
2004 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002005#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002006 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002007#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002008#ifdef MS_WINDOWS
2009 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002010#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002011 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002013 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002014#if defined(MS_WINDOWS)
2015 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2016 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2017#else
2018 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2019 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2020#endif
Fred Drake699f3522000-06-29 21:12:41 +00002021#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002022 PyStructSequence_SET_ITEM(v, 6,
2023 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002024#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002025 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002026#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002027
Martin v. Löwis14694662006-02-03 12:54:16 +00002028#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002029 ansec = st->st_atim.tv_nsec;
2030 mnsec = st->st_mtim.tv_nsec;
2031 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002032#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002033 ansec = st->st_atimespec.tv_nsec;
2034 mnsec = st->st_mtimespec.tv_nsec;
2035 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002036#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002037 ansec = st->st_atime_nsec;
2038 mnsec = st->st_mtime_nsec;
2039 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002040#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002041 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002042#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002043 fill_time(v, 7, st->st_atime, ansec);
2044 fill_time(v, 8, st->st_mtime, mnsec);
2045 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002046
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002047#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002048 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2049 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002050#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002051#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002052 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2053 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002054#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002055#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002056 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2057 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002058#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002059#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002060 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2061 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002062#endif
2063#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002064 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002065 PyObject *val;
2066 unsigned long bsec,bnsec;
2067 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002068#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002069 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002070#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002071 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002072#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002073 if (_stat_float_times) {
2074 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2075 } else {
2076 val = PyLong_FromLong((long)bsec);
2077 }
2078 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2079 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002080 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002081#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002082#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002083 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2084 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002085#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002086#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2087 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2088 PyLong_FromUnsignedLong(st->st_file_attributes));
2089#endif
Fred Drake699f3522000-06-29 21:12:41 +00002090
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 if (PyErr_Occurred()) {
2092 Py_DECREF(v);
2093 return NULL;
2094 }
Fred Drake699f3522000-06-29 21:12:41 +00002095
Victor Stinner8c62be82010-05-06 00:08:46 +00002096 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002097}
2098
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002099/* POSIX methods */
2100
Guido van Rossum94f6f721999-01-06 18:42:14 +00002101
2102static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002103posix_do_stat(char *function_name, path_t *path,
2104 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002106 STRUCT_STAT st;
2107 int result;
2108
2109#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2110 if (follow_symlinks_specified(function_name, follow_symlinks))
2111 return NULL;
2112#endif
2113
2114 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2115 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2116 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2117 return NULL;
2118
2119 Py_BEGIN_ALLOW_THREADS
2120 if (path->fd != -1)
2121 result = FSTAT(path->fd, &st);
2122 else
2123#ifdef MS_WINDOWS
2124 if (path->wide) {
2125 if (follow_symlinks)
2126 result = win32_stat_w(path->wide, &st);
2127 else
2128 result = win32_lstat_w(path->wide, &st);
2129 }
2130 else
2131#endif
2132#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2133 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2134 result = LSTAT(path->narrow, &st);
2135 else
2136#endif
2137#ifdef HAVE_FSTATAT
2138 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2139 result = fstatat(dir_fd, path->narrow, &st,
2140 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2141 else
2142#endif
2143 result = STAT(path->narrow, &st);
2144 Py_END_ALLOW_THREADS
2145
Victor Stinner292c8352012-10-30 02:17:38 +01002146 if (result != 0) {
2147 return path_error(path);
2148 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002149
2150 return _pystat_fromstructstat(&st);
2151}
2152
Larry Hastings2f936352014-08-05 14:04:04 +10002153/*[python input]
2154
2155for s in """
2156
2157FACCESSAT
2158FCHMODAT
2159FCHOWNAT
2160FSTATAT
2161LINKAT
2162MKDIRAT
2163MKFIFOAT
2164MKNODAT
2165OPENAT
2166READLINKAT
2167SYMLINKAT
2168UNLINKAT
2169
2170""".strip().split():
2171 s = s.strip()
2172 print("""
2173#ifdef HAVE_{s}
2174 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002175#else
Larry Hastings2f936352014-08-05 14:04:04 +10002176 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002177#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002178""".rstrip().format(s=s))
2179
2180for s in """
2181
2182FCHDIR
2183FCHMOD
2184FCHOWN
2185FDOPENDIR
2186FEXECVE
2187FPATHCONF
2188FSTATVFS
2189FTRUNCATE
2190
2191""".strip().split():
2192 s = s.strip()
2193 print("""
2194#ifdef HAVE_{s}
2195 #define PATH_HAVE_{s} 1
2196#else
2197 #define PATH_HAVE_{s} 0
2198#endif
2199
2200""".rstrip().format(s=s))
2201[python start generated code]*/
2202
2203#ifdef HAVE_FACCESSAT
2204 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2205#else
2206 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2207#endif
2208
2209#ifdef HAVE_FCHMODAT
2210 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2211#else
2212 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2213#endif
2214
2215#ifdef HAVE_FCHOWNAT
2216 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2217#else
2218 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2219#endif
2220
2221#ifdef HAVE_FSTATAT
2222 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2223#else
2224 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2225#endif
2226
2227#ifdef HAVE_LINKAT
2228 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2229#else
2230 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2231#endif
2232
2233#ifdef HAVE_MKDIRAT
2234 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2235#else
2236 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2237#endif
2238
2239#ifdef HAVE_MKFIFOAT
2240 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2241#else
2242 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2243#endif
2244
2245#ifdef HAVE_MKNODAT
2246 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2247#else
2248 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2249#endif
2250
2251#ifdef HAVE_OPENAT
2252 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2253#else
2254 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2255#endif
2256
2257#ifdef HAVE_READLINKAT
2258 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2259#else
2260 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2261#endif
2262
2263#ifdef HAVE_SYMLINKAT
2264 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2265#else
2266 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2267#endif
2268
2269#ifdef HAVE_UNLINKAT
2270 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2271#else
2272 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2273#endif
2274
2275#ifdef HAVE_FCHDIR
2276 #define PATH_HAVE_FCHDIR 1
2277#else
2278 #define PATH_HAVE_FCHDIR 0
2279#endif
2280
2281#ifdef HAVE_FCHMOD
2282 #define PATH_HAVE_FCHMOD 1
2283#else
2284 #define PATH_HAVE_FCHMOD 0
2285#endif
2286
2287#ifdef HAVE_FCHOWN
2288 #define PATH_HAVE_FCHOWN 1
2289#else
2290 #define PATH_HAVE_FCHOWN 0
2291#endif
2292
2293#ifdef HAVE_FDOPENDIR
2294 #define PATH_HAVE_FDOPENDIR 1
2295#else
2296 #define PATH_HAVE_FDOPENDIR 0
2297#endif
2298
2299#ifdef HAVE_FEXECVE
2300 #define PATH_HAVE_FEXECVE 1
2301#else
2302 #define PATH_HAVE_FEXECVE 0
2303#endif
2304
2305#ifdef HAVE_FPATHCONF
2306 #define PATH_HAVE_FPATHCONF 1
2307#else
2308 #define PATH_HAVE_FPATHCONF 0
2309#endif
2310
2311#ifdef HAVE_FSTATVFS
2312 #define PATH_HAVE_FSTATVFS 1
2313#else
2314 #define PATH_HAVE_FSTATVFS 0
2315#endif
2316
2317#ifdef HAVE_FTRUNCATE
2318 #define PATH_HAVE_FTRUNCATE 1
2319#else
2320 #define PATH_HAVE_FTRUNCATE 0
2321#endif
2322/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002323
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002324#ifdef MS_WINDOWS
2325 #undef PATH_HAVE_FTRUNCATE
2326 #define PATH_HAVE_FTRUNCATE 1
2327#endif
Larry Hastings31826802013-10-19 00:09:25 -07002328
Larry Hastings61272b72014-01-07 12:41:53 -08002329/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002330
2331class path_t_converter(CConverter):
2332
2333 type = "path_t"
2334 impl_by_reference = True
2335 parse_by_reference = True
2336
2337 converter = 'path_converter'
2338
2339 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002340 # right now path_t doesn't support default values.
2341 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002342 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002343 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002344
Larry Hastings2f936352014-08-05 14:04:04 +10002345 if self.c_default not in (None, 'Py_None'):
2346 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002347
2348 self.nullable = nullable
2349 self.allow_fd = allow_fd
2350
Larry Hastings7726ac92014-01-31 22:03:12 -08002351 def pre_render(self):
2352 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002353 if isinstance(value, str):
2354 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002355 return str(int(bool(value)))
2356
2357 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002358 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002359 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002360 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002361 strify(self.nullable),
2362 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002363 )
2364
2365 def cleanup(self):
2366 return "path_cleanup(&" + self.name + ");\n"
2367
2368
2369class dir_fd_converter(CConverter):
2370 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002371
Larry Hastings2f936352014-08-05 14:04:04 +10002372 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002373 if self.default in (unspecified, None):
2374 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002375 if isinstance(requires, str):
2376 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2377 else:
2378 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002379
Larry Hastings2f936352014-08-05 14:04:04 +10002380class fildes_converter(CConverter):
2381 type = 'int'
2382 converter = 'fildes_converter'
2383
2384class uid_t_converter(CConverter):
2385 type = "uid_t"
2386 converter = '_Py_Uid_Converter'
2387
2388class gid_t_converter(CConverter):
2389 type = "gid_t"
2390 converter = '_Py_Gid_Converter'
2391
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002392class dev_t_converter(CConverter):
2393 type = 'dev_t'
2394 converter = '_Py_Dev_Converter'
2395
2396class dev_t_return_converter(unsigned_long_return_converter):
2397 type = 'dev_t'
2398 conversion_fn = '_PyLong_FromDev'
2399 unsigned_cast = '(dev_t)'
2400
Larry Hastings2f936352014-08-05 14:04:04 +10002401class FSConverter_converter(CConverter):
2402 type = 'PyObject *'
2403 converter = 'PyUnicode_FSConverter'
2404 def converter_init(self):
2405 if self.default is not unspecified:
2406 fail("FSConverter_converter does not support default values")
2407 self.c_default = 'NULL'
2408
2409 def cleanup(self):
2410 return "Py_XDECREF(" + self.name + ");\n"
2411
2412class pid_t_converter(CConverter):
2413 type = 'pid_t'
2414 format_unit = '" _Py_PARSE_PID "'
2415
2416class idtype_t_converter(int_converter):
2417 type = 'idtype_t'
2418
2419class id_t_converter(CConverter):
2420 type = 'id_t'
2421 format_unit = '" _Py_PARSE_PID "'
2422
2423class Py_intptr_t_converter(CConverter):
2424 type = 'Py_intptr_t'
2425 format_unit = '" _Py_PARSE_INTPTR "'
2426
2427class Py_off_t_converter(CConverter):
2428 type = 'Py_off_t'
2429 converter = 'Py_off_t_converter'
2430
2431class Py_off_t_return_converter(long_return_converter):
2432 type = 'Py_off_t'
2433 conversion_fn = 'PyLong_FromPy_off_t'
2434
2435class path_confname_converter(CConverter):
2436 type="int"
2437 converter="conv_path_confname"
2438
2439class confstr_confname_converter(path_confname_converter):
2440 converter='conv_confstr_confname'
2441
2442class sysconf_confname_converter(path_confname_converter):
2443 converter="conv_sysconf_confname"
2444
2445class sched_param_converter(CConverter):
2446 type = 'struct sched_param'
2447 converter = 'convert_sched_param'
2448 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002449
Larry Hastings61272b72014-01-07 12:41:53 -08002450[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002451/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002452
Larry Hastings61272b72014-01-07 12:41:53 -08002453/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002454
Larry Hastings2a727912014-01-16 11:32:01 -08002455os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002456
2457 path : path_t(allow_fd=True)
2458 Path to be examined; can be string, bytes, or open-file-descriptor int.
2459
2460 *
2461
Larry Hastings2f936352014-08-05 14:04:04 +10002462 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002463 If not None, it should be a file descriptor open to a directory,
2464 and path should be a relative string; path will then be relative to
2465 that directory.
2466
2467 follow_symlinks: bool = True
2468 If False, and the last element of the path is a symbolic link,
2469 stat will examine the symbolic link itself instead of the file
2470 the link points to.
2471
2472Perform a stat system call on the given path.
2473
2474dir_fd and follow_symlinks may not be implemented
2475 on your platform. If they are unavailable, using them will raise a
2476 NotImplementedError.
2477
2478It's an error to use dir_fd or follow_symlinks when specifying path as
2479 an open file descriptor.
2480
Larry Hastings61272b72014-01-07 12:41:53 -08002481[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002482
Larry Hastings31826802013-10-19 00:09:25 -07002483static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002484os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd,
2485 int follow_symlinks)
2486/*[clinic end generated code: output=e4f7569f95d523ca input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002487{
2488 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2489}
2490
Larry Hastings2f936352014-08-05 14:04:04 +10002491
2492/*[clinic input]
2493os.lstat
2494
2495 path : path_t
2496
2497 *
2498
2499 dir_fd : dir_fd(requires='fstatat') = None
2500
2501Perform a stat system call on the given path, without following symbolic links.
2502
2503Like stat(), but do not follow symbolic links.
2504Equivalent to stat(path, follow_symlinks=False).
2505[clinic start generated code]*/
2506
Larry Hastings2f936352014-08-05 14:04:04 +10002507static PyObject *
2508os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002509/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002510{
2511 int follow_symlinks = 0;
2512 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2513}
Larry Hastings31826802013-10-19 00:09:25 -07002514
Larry Hastings2f936352014-08-05 14:04:04 +10002515
Larry Hastings61272b72014-01-07 12:41:53 -08002516/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002517os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002518
2519 path: path_t(allow_fd=True)
2520 Path to be tested; can be string, bytes, or open-file-descriptor int.
2521
2522 mode: int
2523 Operating-system mode bitfield. Can be F_OK to test existence,
2524 or the inclusive-OR of R_OK, W_OK, and X_OK.
2525
2526 *
2527
Larry Hastings2f936352014-08-05 14:04:04 +10002528 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002529 If not None, it should be a file descriptor open to a directory,
2530 and path should be relative; path will then be relative to that
2531 directory.
2532
2533 effective_ids: bool = False
2534 If True, access will use the effective uid/gid instead of
2535 the real uid/gid.
2536
2537 follow_symlinks: bool = True
2538 If False, and the last element of the path is a symbolic link,
2539 access will examine the symbolic link itself instead of the file
2540 the link points to.
2541
2542Use the real uid/gid to test for access to a path.
2543
2544{parameters}
2545dir_fd, effective_ids, and follow_symlinks may not be implemented
2546 on your platform. If they are unavailable, using them will raise a
2547 NotImplementedError.
2548
2549Note that most operations will use the effective uid/gid, therefore this
2550 routine can be used in a suid/sgid environment to test if the invoking user
2551 has the specified access to the path.
2552
Larry Hastings61272b72014-01-07 12:41:53 -08002553[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002554
Larry Hastings2f936352014-08-05 14:04:04 +10002555static int
Larry Hastings89964c42015-04-14 18:07:59 -04002556os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2557 int effective_ids, int follow_symlinks)
2558/*[clinic end generated code: output=abaa53340210088d input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002559{
Larry Hastings2f936352014-08-05 14:04:04 +10002560 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002561
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002562#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002563 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002564#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002565 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002566#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002567
Larry Hastings9cf065c2012-06-22 16:30:09 -07002568#ifndef HAVE_FACCESSAT
2569 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002570 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002571
2572 if (effective_ids) {
2573 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002574 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 }
2576#endif
2577
2578#ifdef MS_WINDOWS
2579 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002580 if (path->wide != NULL)
2581 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002582 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002583 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002584 Py_END_ALLOW_THREADS
2585
2586 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002587 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002588 * * we didn't get a -1, and
2589 * * write access wasn't requested,
2590 * * or the file isn't read-only,
2591 * * or it's a directory.
2592 * (Directories cannot be read-only on Windows.)
2593 */
Larry Hastings2f936352014-08-05 14:04:04 +10002594 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002595 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002596 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002597 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002598#else
2599
2600 Py_BEGIN_ALLOW_THREADS
2601#ifdef HAVE_FACCESSAT
2602 if ((dir_fd != DEFAULT_DIR_FD) ||
2603 effective_ids ||
2604 !follow_symlinks) {
2605 int flags = 0;
2606 if (!follow_symlinks)
2607 flags |= AT_SYMLINK_NOFOLLOW;
2608 if (effective_ids)
2609 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002610 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002611 }
2612 else
2613#endif
Larry Hastings31826802013-10-19 00:09:25 -07002614 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002615 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002616 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002617#endif
2618
Larry Hastings9cf065c2012-06-22 16:30:09 -07002619 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002620}
2621
Guido van Rossumd371ff11999-01-25 16:12:23 +00002622#ifndef F_OK
2623#define F_OK 0
2624#endif
2625#ifndef R_OK
2626#define R_OK 4
2627#endif
2628#ifndef W_OK
2629#define W_OK 2
2630#endif
2631#ifndef X_OK
2632#define X_OK 1
2633#endif
2634
Larry Hastings31826802013-10-19 00:09:25 -07002635
Guido van Rossumd371ff11999-01-25 16:12:23 +00002636#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002637/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002638os.ttyname -> DecodeFSDefault
2639
2640 fd: int
2641 Integer file descriptor handle.
2642
2643 /
2644
2645Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002646[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002647
Larry Hastings31826802013-10-19 00:09:25 -07002648static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002649os_ttyname_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002650/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002651{
2652 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002653
Larry Hastings31826802013-10-19 00:09:25 -07002654 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002655 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002656 posix_error();
2657 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002658}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002659#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002660
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002661#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002662/*[clinic input]
2663os.ctermid
2664
2665Return the name of the controlling terminal for this process.
2666[clinic start generated code]*/
2667
Larry Hastings2f936352014-08-05 14:04:04 +10002668static PyObject *
2669os_ctermid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002670/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002671{
Victor Stinner8c62be82010-05-06 00:08:46 +00002672 char *ret;
2673 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002674
Greg Wardb48bc172000-03-01 21:51:56 +00002675#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002676 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002677#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002678 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002679#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002680 if (ret == NULL)
2681 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002682 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002683}
Larry Hastings2f936352014-08-05 14:04:04 +10002684#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002685
Larry Hastings2f936352014-08-05 14:04:04 +10002686
2687/*[clinic input]
2688os.chdir
2689
2690 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2691
2692Change the current working directory to the specified path.
2693
2694path may always be specified as a string.
2695On some platforms, path may also be specified as an open file descriptor.
2696 If this functionality is unavailable, using it raises an exception.
2697[clinic start generated code]*/
2698
Larry Hastings2f936352014-08-05 14:04:04 +10002699static PyObject *
2700os_chdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002701/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002702{
2703 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002704
2705 Py_BEGIN_ALLOW_THREADS
2706#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002707 if (path->wide)
2708 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 else
Larry Hastings2f936352014-08-05 14:04:04 +10002710 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002711 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712#else
2713#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002714 if (path->fd != -1)
2715 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002716 else
2717#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002718 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002719#endif
2720 Py_END_ALLOW_THREADS
2721
2722 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002723 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002724 }
2725
Larry Hastings2f936352014-08-05 14:04:04 +10002726 Py_RETURN_NONE;
2727}
2728
2729
2730#ifdef HAVE_FCHDIR
2731/*[clinic input]
2732os.fchdir
2733
2734 fd: fildes
2735
2736Change to the directory of the given file descriptor.
2737
2738fd must be opened on a directory, not a file.
2739Equivalent to os.chdir(fd).
2740
2741[clinic start generated code]*/
2742
Fred Drake4d1e64b2002-04-15 19:40:07 +00002743static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002744os_fchdir_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002745/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002746{
Larry Hastings2f936352014-08-05 14:04:04 +10002747 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002748}
2749#endif /* HAVE_FCHDIR */
2750
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002751
Larry Hastings2f936352014-08-05 14:04:04 +10002752/*[clinic input]
2753os.chmod
2754
2755 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2756 Path to be modified. May always be specified as a str or bytes.
2757 On some platforms, path may also be specified as an open file descriptor.
2758 If this functionality is unavailable, using it raises an exception.
2759
2760 mode: int
2761 Operating-system mode bitfield.
2762
2763 *
2764
2765 dir_fd : dir_fd(requires='fchmodat') = None
2766 If not None, it should be a file descriptor open to a directory,
2767 and path should be relative; path will then be relative to that
2768 directory.
2769
2770 follow_symlinks: bool = True
2771 If False, and the last element of the path is a symbolic link,
2772 chmod will modify the symbolic link itself instead of the file
2773 the link points to.
2774
2775Change the access permissions of a file.
2776
2777It is an error to use dir_fd or follow_symlinks when specifying path as
2778 an open file descriptor.
2779dir_fd and follow_symlinks may not be implemented on your platform.
2780 If they are unavailable, using them will raise a NotImplementedError.
2781
2782[clinic start generated code]*/
2783
Larry Hastings2f936352014-08-05 14:04:04 +10002784static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002785os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd,
2786 int follow_symlinks)
2787/*[clinic end generated code: output=05e7f73b1a843ba2 input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002788{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002789 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002790
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002791#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002792 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002793#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002794
Larry Hastings9cf065c2012-06-22 16:30:09 -07002795#ifdef HAVE_FCHMODAT
2796 int fchmodat_nofollow_unsupported = 0;
2797#endif
2798
Larry Hastings9cf065c2012-06-22 16:30:09 -07002799#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2800 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002801 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002802#endif
2803
2804#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002805 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002806 if (path->wide)
2807 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002808 else
Larry Hastings2f936352014-08-05 14:04:04 +10002809 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002810 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 result = 0;
2812 else {
2813 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002814 attr &= ~FILE_ATTRIBUTE_READONLY;
2815 else
2816 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002817 if (path->wide)
2818 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002819 else
Larry Hastings2f936352014-08-05 14:04:04 +10002820 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002821 }
2822 Py_END_ALLOW_THREADS
2823
2824 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002825 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002826 }
2827#else /* MS_WINDOWS */
2828 Py_BEGIN_ALLOW_THREADS
2829#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002830 if (path->fd != -1)
2831 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002832 else
2833#endif
2834#ifdef HAVE_LCHMOD
2835 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002836 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002837 else
2838#endif
2839#ifdef HAVE_FCHMODAT
2840 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2841 /*
2842 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2843 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002844 * and then says it isn't implemented yet.
2845 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002846 *
2847 * Once it is supported, os.chmod will automatically
2848 * support dir_fd and follow_symlinks=False. (Hopefully.)
2849 * Until then, we need to be careful what exception we raise.
2850 */
Larry Hastings2f936352014-08-05 14:04:04 +10002851 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002852 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2853 /*
2854 * But wait! We can't throw the exception without allowing threads,
2855 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2856 */
2857 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002858 result &&
2859 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2860 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002861 }
2862 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002863#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002864 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002865 Py_END_ALLOW_THREADS
2866
2867 if (result) {
2868#ifdef HAVE_FCHMODAT
2869 if (fchmodat_nofollow_unsupported) {
2870 if (dir_fd != DEFAULT_DIR_FD)
2871 dir_fd_and_follow_symlinks_invalid("chmod",
2872 dir_fd, follow_symlinks);
2873 else
2874 follow_symlinks_specified("chmod", follow_symlinks);
2875 }
2876 else
2877#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002878 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002879 }
2880#endif
2881
Larry Hastings2f936352014-08-05 14:04:04 +10002882 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002883}
2884
Larry Hastings9cf065c2012-06-22 16:30:09 -07002885
Christian Heimes4e30a842007-11-30 22:12:06 +00002886#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002887/*[clinic input]
2888os.fchmod
2889
2890 fd: int
2891 mode: int
2892
2893Change the access permissions of the file given by file descriptor fd.
2894
2895Equivalent to os.chmod(fd, mode).
2896[clinic start generated code]*/
2897
Larry Hastings2f936352014-08-05 14:04:04 +10002898static PyObject *
2899os_fchmod_impl(PyModuleDef *module, int fd, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002900/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002901{
2902 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002903 int async_err = 0;
2904
2905 do {
2906 Py_BEGIN_ALLOW_THREADS
2907 res = fchmod(fd, mode);
2908 Py_END_ALLOW_THREADS
2909 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2910 if (res != 0)
2911 return (!async_err) ? posix_error() : NULL;
2912
Victor Stinner8c62be82010-05-06 00:08:46 +00002913 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002914}
2915#endif /* HAVE_FCHMOD */
2916
Larry Hastings2f936352014-08-05 14:04:04 +10002917
Christian Heimes4e30a842007-11-30 22:12:06 +00002918#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002919/*[clinic input]
2920os.lchmod
2921
2922 path: path_t
2923 mode: int
2924
2925Change the access permissions of a file, without following symbolic links.
2926
2927If path is a symlink, this affects the link itself rather than the target.
2928Equivalent to chmod(path, mode, follow_symlinks=False)."
2929[clinic start generated code]*/
2930
Larry Hastings2f936352014-08-05 14:04:04 +10002931static PyObject *
2932os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002933/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002934{
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002936 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002937 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002938 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002939 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002940 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002941 return NULL;
2942 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002943 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002944}
2945#endif /* HAVE_LCHMOD */
2946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002947
Thomas Wouterscf297e42007-02-23 15:07:44 +00002948#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002949/*[clinic input]
2950os.chflags
2951
2952 path: path_t
2953 flags: unsigned_long(bitwise=True)
2954 follow_symlinks: bool=True
2955
2956Set file flags.
2957
2958If follow_symlinks is False, and the last element of the path is a symbolic
2959 link, chflags will change flags on the symbolic link itself instead of the
2960 file the link points to.
2961follow_symlinks may not be implemented on your platform. If it is
2962unavailable, using it will raise a NotImplementedError.
2963
2964[clinic start generated code]*/
2965
Larry Hastings2f936352014-08-05 14:04:04 +10002966static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04002967os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags,
2968 int follow_symlinks)
2969/*[clinic end generated code: output=ff2d6e73534a95b9 input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002970{
2971 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002972
2973#ifndef HAVE_LCHFLAGS
2974 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002975 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002976#endif
2977
Victor Stinner8c62be82010-05-06 00:08:46 +00002978 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002979#ifdef HAVE_LCHFLAGS
2980 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002981 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002982 else
2983#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002984 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002985 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002986
Larry Hastings2f936352014-08-05 14:04:04 +10002987 if (result)
2988 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002989
Larry Hastings2f936352014-08-05 14:04:04 +10002990 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002991}
2992#endif /* HAVE_CHFLAGS */
2993
Larry Hastings2f936352014-08-05 14:04:04 +10002994
Thomas Wouterscf297e42007-02-23 15:07:44 +00002995#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002996/*[clinic input]
2997os.lchflags
2998
2999 path: path_t
3000 flags: unsigned_long(bitwise=True)
3001
3002Set file flags.
3003
3004This function will not follow symbolic links.
3005Equivalent to chflags(path, flags, follow_symlinks=False).
3006[clinic start generated code]*/
3007
Larry Hastings2f936352014-08-05 14:04:04 +10003008static PyObject *
3009os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003010/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003011{
Victor Stinner8c62be82010-05-06 00:08:46 +00003012 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003013 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003014 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003015 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003016 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003017 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003018 }
Victor Stinner292c8352012-10-30 02:17:38 +01003019 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003020}
3021#endif /* HAVE_LCHFLAGS */
3022
Larry Hastings2f936352014-08-05 14:04:04 +10003023
Martin v. Löwis244edc82001-10-04 22:44:26 +00003024#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003025/*[clinic input]
3026os.chroot
3027 path: path_t
3028
3029Change root directory to path.
3030
3031[clinic start generated code]*/
3032
Larry Hastings2f936352014-08-05 14:04:04 +10003033static PyObject *
3034os_chroot_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003035/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003036{
3037 int res;
3038 Py_BEGIN_ALLOW_THREADS
3039 res = chroot(path->narrow);
3040 Py_END_ALLOW_THREADS
3041 if (res < 0)
3042 return path_error(path);
3043 Py_RETURN_NONE;
3044}
3045#endif /* HAVE_CHROOT */
3046
Martin v. Löwis244edc82001-10-04 22:44:26 +00003047
Guido van Rossum21142a01999-01-08 21:05:37 +00003048#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003049/*[clinic input]
3050os.fsync
3051
3052 fd: fildes
3053
3054Force write of fd to disk.
3055[clinic start generated code]*/
3056
Larry Hastings2f936352014-08-05 14:04:04 +10003057static PyObject *
3058os_fsync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003059/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003060{
3061 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003062}
3063#endif /* HAVE_FSYNC */
3064
Larry Hastings2f936352014-08-05 14:04:04 +10003065
Ross Lagerwall7807c352011-03-17 20:20:30 +02003066#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003067/*[clinic input]
3068os.sync
3069
3070Force write of everything to disk.
3071[clinic start generated code]*/
3072
Larry Hastings2f936352014-08-05 14:04:04 +10003073static PyObject *
3074os_sync_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003075/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003076{
3077 Py_BEGIN_ALLOW_THREADS
3078 sync();
3079 Py_END_ALLOW_THREADS
3080 Py_RETURN_NONE;
3081}
Larry Hastings2f936352014-08-05 14:04:04 +10003082#endif /* HAVE_SYNC */
3083
Ross Lagerwall7807c352011-03-17 20:20:30 +02003084
Guido van Rossum21142a01999-01-08 21:05:37 +00003085#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003086#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003087extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3088#endif
3089
Larry Hastings2f936352014-08-05 14:04:04 +10003090/*[clinic input]
3091os.fdatasync
3092
3093 fd: fildes
3094
3095Force write of fd to disk without forcing update of metadata.
3096[clinic start generated code]*/
3097
Larry Hastings2f936352014-08-05 14:04:04 +10003098static PyObject *
3099os_fdatasync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003100/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003101{
3102 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003103}
3104#endif /* HAVE_FDATASYNC */
3105
3106
Fredrik Lundh10723342000-07-10 16:38:09 +00003107#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003108/*[clinic input]
3109os.chown
3110
3111 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3112 Path to be examined; can be string, bytes, or open-file-descriptor int.
3113
3114 uid: uid_t
3115
3116 gid: gid_t
3117
3118 *
3119
3120 dir_fd : dir_fd(requires='fchownat') = None
3121 If not None, it should be a file descriptor open to a directory,
3122 and path should be relative; path will then be relative to that
3123 directory.
3124
3125 follow_symlinks: bool = True
3126 If False, and the last element of the path is a symbolic link,
3127 stat will examine the symbolic link itself instead of the file
3128 the link points to.
3129
3130Change the owner and group id of path to the numeric uid and gid.\
3131
3132path may always be specified as a string.
3133On some platforms, path may also be specified as an open file descriptor.
3134 If this functionality is unavailable, using it raises an exception.
3135If dir_fd is not None, it should be a file descriptor open to a directory,
3136 and path should be relative; path will then be relative to that directory.
3137If follow_symlinks is False, and the last element of the path is a symbolic
3138 link, chown will modify the symbolic link itself instead of the file the
3139 link points to.
3140It is an error to use dir_fd or follow_symlinks when specifying path as
3141 an open file descriptor.
3142dir_fd and follow_symlinks may not be implemented on your platform.
3143 If they are unavailable, using them will raise a NotImplementedError.
3144
3145[clinic start generated code]*/
3146
Larry Hastings2f936352014-08-05 14:04:04 +10003147static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003148os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid,
3149 int dir_fd, int follow_symlinks)
3150/*[clinic end generated code: output=e0a4559f394dbd91 input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003151{
3152 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003153
3154#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3155 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003156 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003157#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003158 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3159 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3160 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003161
3162#ifdef __APPLE__
3163 /*
3164 * This is for Mac OS X 10.3, which doesn't have lchown.
3165 * (But we still have an lchown symbol because of weak-linking.)
3166 * It doesn't have fchownat either. So there's no possibility
3167 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003168 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 if ((!follow_symlinks) && (lchown == NULL)) {
3170 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003171 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003172 }
3173#endif
3174
Victor Stinner8c62be82010-05-06 00:08:46 +00003175 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003176#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003177 if (path->fd != -1)
3178 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179 else
3180#endif
3181#ifdef HAVE_LCHOWN
3182 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003183 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184 else
3185#endif
3186#ifdef HAVE_FCHOWNAT
3187 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003188 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003189 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3190 else
3191#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003192 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003193 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003194
Larry Hastings2f936352014-08-05 14:04:04 +10003195 if (result)
3196 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003197
Larry Hastings2f936352014-08-05 14:04:04 +10003198 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003199}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003200#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003201
Larry Hastings2f936352014-08-05 14:04:04 +10003202
Christian Heimes4e30a842007-11-30 22:12:06 +00003203#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003204/*[clinic input]
3205os.fchown
3206
3207 fd: int
3208 uid: uid_t
3209 gid: gid_t
3210
3211Change the owner and group id of the file specified by file descriptor.
3212
3213Equivalent to os.chown(fd, uid, gid).
3214
3215[clinic start generated code]*/
3216
Larry Hastings2f936352014-08-05 14:04:04 +10003217static PyObject *
3218os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003219/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003220{
Victor Stinner8c62be82010-05-06 00:08:46 +00003221 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003222 int async_err = 0;
3223
3224 do {
3225 Py_BEGIN_ALLOW_THREADS
3226 res = fchown(fd, uid, gid);
3227 Py_END_ALLOW_THREADS
3228 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3229 if (res != 0)
3230 return (!async_err) ? posix_error() : NULL;
3231
Victor Stinner8c62be82010-05-06 00:08:46 +00003232 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003233}
3234#endif /* HAVE_FCHOWN */
3235
Larry Hastings2f936352014-08-05 14:04:04 +10003236
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003237#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003238/*[clinic input]
3239os.lchown
3240
3241 path : path_t
3242 uid: uid_t
3243 gid: gid_t
3244
3245Change the owner and group id of path to the numeric uid and gid.
3246
3247This function will not follow symbolic links.
3248Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3249[clinic start generated code]*/
3250
Larry Hastings2f936352014-08-05 14:04:04 +10003251static PyObject *
3252os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003253/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003254{
Victor Stinner8c62be82010-05-06 00:08:46 +00003255 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003256 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003257 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003258 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003259 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003260 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003261 }
Larry Hastings2f936352014-08-05 14:04:04 +10003262 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003263}
3264#endif /* HAVE_LCHOWN */
3265
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003266
Barry Warsaw53699e91996-12-10 23:23:01 +00003267static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003268posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003269{
Victor Stinner4403d7d2015-04-25 00:16:10 +02003270 char *buf, *tmpbuf;
3271 char *cwd;
3272 const size_t chunk = 1024;
3273 size_t buflen = 0;
3274 PyObject *obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003275
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003276#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003277 if (!use_bytes) {
Victor Stinner4403d7d2015-04-25 00:16:10 +02003278 wchar_t wbuf[MAXPATHLEN];
Victor Stinner8c62be82010-05-06 00:08:46 +00003279 wchar_t *wbuf2 = wbuf;
3280 PyObject *resobj;
3281 DWORD len;
3282 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003283 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003284 /* If the buffer is large enough, len does not include the
3285 terminating \0. If the buffer is too small, len includes
3286 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003287 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003288 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003289 if (wbuf2)
3290 len = GetCurrentDirectoryW(len, wbuf2);
3291 }
3292 Py_END_ALLOW_THREADS
3293 if (!wbuf2) {
3294 PyErr_NoMemory();
3295 return NULL;
3296 }
3297 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003298 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003299 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003300 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 }
3302 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003303 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003304 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003305 return resobj;
3306 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003307
3308 if (win32_warn_bytes_api())
3309 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003310#endif
3311
Victor Stinner4403d7d2015-04-25 00:16:10 +02003312 buf = cwd = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003313 Py_BEGIN_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003314 do {
3315 buflen += chunk;
3316 tmpbuf = PyMem_RawRealloc(buf, buflen);
3317 if (tmpbuf == NULL)
3318 break;
3319
3320 buf = tmpbuf;
3321 cwd = getcwd(buf, buflen);
3322 } while (cwd == NULL && errno == ERANGE);
Victor Stinner8c62be82010-05-06 00:08:46 +00003323 Py_END_ALLOW_THREADS
Victor Stinner4403d7d2015-04-25 00:16:10 +02003324
3325 if (cwd == NULL) {
3326 PyMem_RawFree(buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003327 return posix_error();
Victor Stinner4403d7d2015-04-25 00:16:10 +02003328 }
3329
Victor Stinner8c62be82010-05-06 00:08:46 +00003330 if (use_bytes)
Victor Stinner4403d7d2015-04-25 00:16:10 +02003331 obj = PyBytes_FromStringAndSize(buf, strlen(buf));
3332 else
3333 obj = PyUnicode_DecodeFSDefault(buf);
3334 PyMem_RawFree(buf);
3335
3336 return obj;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003337}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003338
Larry Hastings2f936352014-08-05 14:04:04 +10003339
3340/*[clinic input]
3341os.getcwd
3342
3343Return a unicode string representing the current working directory.
3344[clinic start generated code]*/
3345
Larry Hastings2f936352014-08-05 14:04:04 +10003346static PyObject *
3347os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003348/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003349{
3350 return posix_getcwd(0);
3351}
3352
Larry Hastings2f936352014-08-05 14:04:04 +10003353
3354/*[clinic input]
3355os.getcwdb
3356
3357Return a bytes string representing the current working directory.
3358[clinic start generated code]*/
3359
Larry Hastings2f936352014-08-05 14:04:04 +10003360static PyObject *
3361os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003362/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003363{
3364 return posix_getcwd(1);
3365}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003366
Larry Hastings2f936352014-08-05 14:04:04 +10003367
Larry Hastings9cf065c2012-06-22 16:30:09 -07003368#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3369#define HAVE_LINK 1
3370#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003371
Guido van Rossumb6775db1994-08-01 11:34:53 +00003372#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003373/*[clinic input]
3374
3375os.link
3376
3377 src : path_t
3378 dst : path_t
3379 *
3380 src_dir_fd : dir_fd = None
3381 dst_dir_fd : dir_fd = None
3382 follow_symlinks: bool = True
3383
3384Create a hard link to a file.
3385
3386If either src_dir_fd or dst_dir_fd is not None, it should be a file
3387 descriptor open to a directory, and the respective path string (src or dst)
3388 should be relative; the path will then be relative to that directory.
3389If follow_symlinks is False, and the last element of src is a symbolic
3390 link, link will create a link to the symbolic link itself instead of the
3391 file the link points to.
3392src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3393 platform. If they are unavailable, using them will raise a
3394 NotImplementedError.
3395[clinic start generated code]*/
3396
Larry Hastings2f936352014-08-05 14:04:04 +10003397static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04003398os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
3399 int dst_dir_fd, int follow_symlinks)
3400/*[clinic end generated code: output=f47a7e88f7b391b6 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003401{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003402#ifdef MS_WINDOWS
3403 BOOL result;
3404#else
3405 int result;
3406#endif
3407
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408#ifndef HAVE_LINKAT
3409 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3410 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003411 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412 }
3413#endif
3414
Larry Hastings2f936352014-08-05 14:04:04 +10003415 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416 PyErr_SetString(PyExc_NotImplementedError,
3417 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003418 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003419 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003420
Brian Curtin1b9df392010-11-24 20:24:31 +00003421#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003422 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003423 if (src->wide)
3424 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003425 else
Larry Hastings2f936352014-08-05 14:04:04 +10003426 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003428
Larry Hastings2f936352014-08-05 14:04:04 +10003429 if (!result)
3430 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003431#else
3432 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003433#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003434 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3435 (dst_dir_fd != DEFAULT_DIR_FD) ||
3436 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003437 result = linkat(src_dir_fd, src->narrow,
3438 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003439 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3440 else
3441#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003442 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003443 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003444
Larry Hastings2f936352014-08-05 14:04:04 +10003445 if (result)
3446 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003447#endif
3448
Larry Hastings2f936352014-08-05 14:04:04 +10003449 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003450}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003451#endif
3452
Brian Curtin1b9df392010-11-24 20:24:31 +00003453
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003454#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003455static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003456_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003457{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003458 PyObject *v;
3459 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3460 BOOL result;
3461 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003462 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003463 char *bufptr = namebuf;
3464 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003465 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466 PyObject *po = NULL;
3467 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003468
Gregory P. Smith40a21602013-03-20 20:52:50 -07003469 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003470 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003471 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003472
Gregory P. Smith40a21602013-03-20 20:52:50 -07003473 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003474 po_wchars = L".";
3475 len = 1;
3476 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003477 po_wchars = path->wide;
3478 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003479 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003481 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 if (!wnamebuf) {
3483 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003484 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003486 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003487 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003488 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003489 if (wch != SEP && wch != ALTSEP && wch != L':')
3490 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 wcscpy(wnamebuf + len, L"*.*");
3492 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003493 if ((list = PyList_New(0)) == NULL) {
3494 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003496 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003498 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003499 if (hFindFile == INVALID_HANDLE_VALUE) {
3500 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 if (error == ERROR_FILE_NOT_FOUND)
3502 goto exit;
3503 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003504 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003505 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003506 }
3507 do {
3508 /* Skip over . and .. */
3509 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3510 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003511 v = PyUnicode_FromWideChar(wFileData.cFileName,
3512 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003513 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003514 Py_DECREF(list);
3515 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003516 break;
3517 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003520 Py_DECREF(list);
3521 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 break;
3523 }
3524 Py_DECREF(v);
3525 }
3526 Py_BEGIN_ALLOW_THREADS
3527 result = FindNextFileW(hFindFile, &wFileData);
3528 Py_END_ALLOW_THREADS
3529 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3530 it got to the end of the directory. */
3531 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003533 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003534 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003535 }
3536 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003537
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003539 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003540 strcpy(namebuf, path->narrow);
3541 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003542 if (len > 0) {
3543 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003544 if (ch != '\\' && ch != '/' && ch != ':')
3545 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 strcpy(namebuf + len, "*.*");
3547 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003548
Larry Hastings9cf065c2012-06-22 16:30:09 -07003549 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003550 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003551
Antoine Pitroub73caab2010-08-09 23:39:31 +00003552 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003554 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003555 if (hFindFile == INVALID_HANDLE_VALUE) {
3556 int error = GetLastError();
3557 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 goto exit;
3559 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003560 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003561 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003562 }
3563 do {
3564 /* Skip over . and .. */
3565 if (strcmp(FileData.cFileName, ".") != 0 &&
3566 strcmp(FileData.cFileName, "..") != 0) {
3567 v = PyBytes_FromString(FileData.cFileName);
3568 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003569 Py_DECREF(list);
3570 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003571 break;
3572 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003574 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003575 Py_DECREF(list);
3576 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003577 break;
3578 }
3579 Py_DECREF(v);
3580 }
3581 Py_BEGIN_ALLOW_THREADS
3582 result = FindNextFile(hFindFile, &FileData);
3583 Py_END_ALLOW_THREADS
3584 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3585 it got to the end of the directory. */
3586 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003588 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003589 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003590 }
3591 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003592
Larry Hastings9cf065c2012-06-22 16:30:09 -07003593exit:
3594 if (hFindFile != INVALID_HANDLE_VALUE) {
3595 if (FindClose(hFindFile) == FALSE) {
3596 if (list != NULL) {
3597 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003598 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 }
3600 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003601 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003602 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003603
Larry Hastings9cf065c2012-06-22 16:30:09 -07003604 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003605} /* end of _listdir_windows_no_opendir */
3606
3607#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3608
3609static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003611{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003612 PyObject *v;
3613 DIR *dirp = NULL;
3614 struct dirent *ep;
3615 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003616#ifdef HAVE_FDOPENDIR
3617 int fd = -1;
3618#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003619
Victor Stinner8c62be82010-05-06 00:08:46 +00003620 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003622 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003623 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003624 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003625 if (fd == -1)
3626 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003627
Larry Hastingsfdaea062012-06-25 04:42:23 -07003628 return_str = 1;
3629
Larry Hastings9cf065c2012-06-22 16:30:09 -07003630 Py_BEGIN_ALLOW_THREADS
3631 dirp = fdopendir(fd);
3632 Py_END_ALLOW_THREADS
3633 }
3634 else
3635#endif
3636 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003637 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003638 if (path->narrow) {
3639 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003640 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003641 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003642 }
3643 else {
3644 name = ".";
3645 return_str = 1;
3646 }
3647
Larry Hastings9cf065c2012-06-22 16:30:09 -07003648 Py_BEGIN_ALLOW_THREADS
3649 dirp = opendir(name);
3650 Py_END_ALLOW_THREADS
3651 }
3652
3653 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003654 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003655#ifdef HAVE_FDOPENDIR
3656 if (fd != -1) {
3657 Py_BEGIN_ALLOW_THREADS
3658 close(fd);
3659 Py_END_ALLOW_THREADS
3660 }
3661#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 goto exit;
3663 }
3664 if ((list = PyList_New(0)) == NULL) {
3665 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003666 }
3667 for (;;) {
3668 errno = 0;
3669 Py_BEGIN_ALLOW_THREADS
3670 ep = readdir(dirp);
3671 Py_END_ALLOW_THREADS
3672 if (ep == NULL) {
3673 if (errno == 0) {
3674 break;
3675 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003677 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003678 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003679 }
3680 }
3681 if (ep->d_name[0] == '.' &&
3682 (NAMLEN(ep) == 1 ||
3683 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3684 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003685 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003686 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3687 else
3688 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003690 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003691 break;
3692 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003695 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003696 break;
3697 }
3698 Py_DECREF(v);
3699 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003700
Larry Hastings9cf065c2012-06-22 16:30:09 -07003701exit:
3702 if (dirp != NULL) {
3703 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003704#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003705 if (fd > -1)
3706 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003707#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003708 closedir(dirp);
3709 Py_END_ALLOW_THREADS
3710 }
3711
Larry Hastings9cf065c2012-06-22 16:30:09 -07003712 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003713} /* end of _posix_listdir */
3714#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003715
Larry Hastings2f936352014-08-05 14:04:04 +10003716
3717/*[clinic input]
3718os.listdir
3719
3720 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3721
3722Return a list containing the names of the files in the directory.
3723
3724path can be specified as either str or bytes. If path is bytes,
3725 the filenames returned will also be bytes; in all other circumstances
3726 the filenames returned will be str.
3727If path is None, uses the path='.'.
3728On some platforms, path may also be specified as an open file descriptor;\
3729 the file descriptor must refer to a directory.
3730 If this functionality is unavailable, using it raises NotImplementedError.
3731
3732The list is in arbitrary order. It does not include the special
3733entries '.' and '..' even if they are present in the directory.
3734
3735
3736[clinic start generated code]*/
3737
Larry Hastings2f936352014-08-05 14:04:04 +10003738static PyObject *
3739os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003740/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003741{
3742#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3743 return _listdir_windows_no_opendir(path, NULL);
3744#else
3745 return _posix_listdir(path, NULL);
3746#endif
3747}
3748
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003749#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003750/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003751/*[clinic input]
3752os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003753
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003754 path: path_t
3755 /
3756
3757[clinic start generated code]*/
3758
3759static PyObject *
3760os__getfullpathname_impl(PyModuleDef *module, path_t *path)
3761/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/
3762{
3763 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003764 {
Victor Stinner75875072013-11-24 19:23:25 +01003765 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003766 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 DWORD result;
3768 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003769
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003770 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003771 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003772 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003773 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003774 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003775 if (!woutbufp)
3776 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003777 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003778 }
3779 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003780 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003782 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003784 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003785 return v;
3786 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003787 else {
3788 char outbuf[MAX_PATH];
3789 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003790
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003791 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3792 outbuf, &temp)) {
3793 win32_error_object("GetFullPathName", path->object);
3794 return NULL;
3795 }
3796 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003797 }
Larry Hastings2f936352014-08-05 14:04:04 +10003798}
Brian Curtind40e6f72010-07-08 21:39:08 +00003799
Brian Curtind25aef52011-06-13 15:16:04 -05003800
Larry Hastings2f936352014-08-05 14:04:04 +10003801/*[clinic input]
3802os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003803
Larry Hastings2f936352014-08-05 14:04:04 +10003804 path: unicode
3805 /
3806
3807A helper function for samepath on windows.
3808[clinic start generated code]*/
3809
Larry Hastings2f936352014-08-05 14:04:04 +10003810static PyObject *
3811os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003812/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003813{
3814 HANDLE hFile;
3815 int buf_size;
3816 wchar_t *target_path;
3817 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003818 PyObject *result;
3819 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003820
Larry Hastings2f936352014-08-05 14:04:04 +10003821 path_wchar = PyUnicode_AsUnicode(path);
3822 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003823 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003824
Brian Curtind40e6f72010-07-08 21:39:08 +00003825 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003826 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003827 0, /* desired access */
3828 0, /* share mode */
3829 NULL, /* security attributes */
3830 OPEN_EXISTING,
3831 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3832 FILE_FLAG_BACKUP_SEMANTICS,
3833 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003834
Victor Stinnereb5657a2011-09-30 01:44:27 +02003835 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003836 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003837
3838 /* We have a good handle to the target, use it to determine the
3839 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003840 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003841
3842 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003843 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003844
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003845 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003846 if(!target_path)
3847 return PyErr_NoMemory();
3848
Steve Dower2ea51c92015-03-20 21:49:12 -07003849 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3850 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003851 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003852 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003853
3854 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003855 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003856
3857 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003858 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003859 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003860 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003861}
Brian Curtin62857742010-09-06 17:07:27 +00003862
Brian Curtin95d028f2011-06-09 09:10:38 -05003863PyDoc_STRVAR(posix__isdir__doc__,
3864"Return true if the pathname refers to an existing directory.");
3865
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003866/*[clinic input]
3867os._isdir
3868
3869 path: path_t
3870 /
3871
3872[clinic start generated code]*/
3873
Brian Curtin9c669cc2011-06-08 18:17:18 -05003874static PyObject *
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003875os__isdir_impl(PyModuleDef *module, path_t *path)
3876/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003877{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003878 DWORD attributes;
3879
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003880 if (!path->narrow)
3881 attributes = GetFileAttributesW(path->wide);
3882 else
3883 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003884
Brian Curtin9c669cc2011-06-08 18:17:18 -05003885 if (attributes == INVALID_FILE_ATTRIBUTES)
3886 Py_RETURN_FALSE;
3887
Brian Curtin9c669cc2011-06-08 18:17:18 -05003888 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3889 Py_RETURN_TRUE;
3890 else
3891 Py_RETURN_FALSE;
3892}
Tim Golden6b528062013-08-01 12:44:00 +01003893
Tim Golden6b528062013-08-01 12:44:00 +01003894
Larry Hastings2f936352014-08-05 14:04:04 +10003895/*[clinic input]
3896os._getvolumepathname
3897
3898 path: unicode
3899
3900A helper function for ismount on Win32.
3901[clinic start generated code]*/
3902
Larry Hastings2f936352014-08-05 14:04:04 +10003903static PyObject *
3904os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003905/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003906{
3907 PyObject *result;
3908 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003909 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003910 BOOL ret;
3911
Larry Hastings2f936352014-08-05 14:04:04 +10003912 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3913 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003914 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003915 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003916
3917 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003918 buflen = Py_MAX(buflen, MAX_PATH);
3919
3920 if (buflen > DWORD_MAX) {
3921 PyErr_SetString(PyExc_OverflowError, "path too long");
3922 return NULL;
3923 }
3924
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003925 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003926 if (mountpath == NULL)
3927 return PyErr_NoMemory();
3928
3929 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003930 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003931 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003932 Py_END_ALLOW_THREADS
3933
3934 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003935 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003936 goto exit;
3937 }
3938 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3939
3940exit:
3941 PyMem_Free(mountpath);
3942 return result;
3943}
Tim Golden6b528062013-08-01 12:44:00 +01003944
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003945#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003946
Larry Hastings2f936352014-08-05 14:04:04 +10003947
3948/*[clinic input]
3949os.mkdir
3950
3951 path : path_t
3952
3953 mode: int = 0o777
3954
3955 *
3956
3957 dir_fd : dir_fd(requires='mkdirat') = None
3958
3959# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3960
3961Create a directory.
3962
3963If dir_fd is not None, it should be a file descriptor open to a directory,
3964 and path should be relative; path will then be relative to that directory.
3965dir_fd may not be implemented on your platform.
3966 If it is unavailable, using it will raise a NotImplementedError.
3967
3968The mode argument is ignored on Windows.
3969[clinic start generated code]*/
3970
Larry Hastings2f936352014-08-05 14:04:04 +10003971static PyObject *
3972os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003973/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003974{
3975 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003976
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003977#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003978 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003979 if (path->wide)
3980 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003981 else
Larry Hastings2f936352014-08-05 14:04:04 +10003982 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003983 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003984
Larry Hastings2f936352014-08-05 14:04:04 +10003985 if (!result)
3986 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003988 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003989#if HAVE_MKDIRAT
3990 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003991 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003992 else
3993#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003994#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003995 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003996#else
Larry Hastings2f936352014-08-05 14:04:04 +10003997 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003998#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003999 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004000 if (result < 0)
4001 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004002#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004003 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004004}
4005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004006
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004007/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4008#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004009#include <sys/resource.h>
4010#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004011
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004012
4013#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004014/*[clinic input]
4015os.nice
4016
4017 increment: int
4018 /
4019
4020Add increment to the priority of process and return the new priority.
4021[clinic start generated code]*/
4022
Larry Hastings2f936352014-08-05 14:04:04 +10004023static PyObject *
4024os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004025/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004026{
4027 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004028
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 /* There are two flavours of 'nice': one that returns the new
4030 priority (as required by almost all standards out there) and the
4031 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4032 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004033
Victor Stinner8c62be82010-05-06 00:08:46 +00004034 If we are of the nice family that returns the new priority, we
4035 need to clear errno before the call, and check if errno is filled
4036 before calling posix_error() on a returnvalue of -1, because the
4037 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004038
Victor Stinner8c62be82010-05-06 00:08:46 +00004039 errno = 0;
4040 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004041#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004042 if (value == 0)
4043 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004044#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004045 if (value == -1 && errno != 0)
4046 /* either nice() or getpriority() returned an error */
4047 return posix_error();
4048 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004049}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004050#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004051
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004052
4053#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004054/*[clinic input]
4055os.getpriority
4056
4057 which: int
4058 who: int
4059
4060Return program scheduling priority.
4061[clinic start generated code]*/
4062
Larry Hastings2f936352014-08-05 14:04:04 +10004063static PyObject *
4064os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004065/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004066{
4067 int retval;
4068
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004069 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004070 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004071 if (errno != 0)
4072 return posix_error();
4073 return PyLong_FromLong((long)retval);
4074}
4075#endif /* HAVE_GETPRIORITY */
4076
4077
4078#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004079/*[clinic input]
4080os.setpriority
4081
4082 which: int
4083 who: int
4084 priority: int
4085
4086Set program scheduling priority.
4087[clinic start generated code]*/
4088
Larry Hastings2f936352014-08-05 14:04:04 +10004089static PyObject *
4090os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004091/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004092{
4093 int retval;
4094
4095 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004096 if (retval == -1)
4097 return posix_error();
4098 Py_RETURN_NONE;
4099}
4100#endif /* HAVE_SETPRIORITY */
4101
4102
Barry Warsaw53699e91996-12-10 23:23:01 +00004103static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004104internal_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 +00004105{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004107 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004108
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004109#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004110 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004111 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004112#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004114#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004115
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4117 (dst_dir_fd != DEFAULT_DIR_FD);
4118#ifndef HAVE_RENAMEAT
4119 if (dir_fd_specified) {
4120 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004121 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 }
4123#endif
4124
Larry Hastings2f936352014-08-05 14:04:04 +10004125 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004126 PyErr_Format(PyExc_ValueError,
4127 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004128 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004129 }
4130
4131#ifdef MS_WINDOWS
4132 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004133 if (src->wide)
4134 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 else
Larry Hastings2f936352014-08-05 14:04:04 +10004136 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004137 Py_END_ALLOW_THREADS
4138
Larry Hastings2f936352014-08-05 14:04:04 +10004139 if (!result)
4140 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141
4142#else
4143 Py_BEGIN_ALLOW_THREADS
4144#ifdef HAVE_RENAMEAT
4145 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004146 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004147 else
4148#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004149 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004150 Py_END_ALLOW_THREADS
4151
Larry Hastings2f936352014-08-05 14:04:04 +10004152 if (result)
4153 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004154#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004155 Py_RETURN_NONE;
4156}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004157
Larry Hastings2f936352014-08-05 14:04:04 +10004158
4159/*[clinic input]
4160os.rename
4161
4162 src : path_t
4163 dst : path_t
4164 *
4165 src_dir_fd : dir_fd = None
4166 dst_dir_fd : dir_fd = None
4167
4168Rename a file or directory.
4169
4170If either src_dir_fd or dst_dir_fd is not None, it should be a file
4171 descriptor open to a directory, and the respective path string (src or dst)
4172 should be relative; the path will then be relative to that directory.
4173src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4174 If they are unavailable, using them will raise a NotImplementedError.
4175[clinic start generated code]*/
4176
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004177static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004178os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
4179 int dst_dir_fd)
4180/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004181{
Larry Hastings2f936352014-08-05 14:04:04 +10004182 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004183}
4184
Larry Hastings2f936352014-08-05 14:04:04 +10004185
4186/*[clinic input]
4187os.replace = os.rename
4188
4189Rename a file or directory, overwriting the destination.
4190
4191If either src_dir_fd or dst_dir_fd is not None, it should be a file
4192 descriptor open to a directory, and the respective path string (src or dst)
4193 should be relative; the path will then be relative to that directory.
4194src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4195 If they are unavailable, using them will raise a NotImplementedError."
4196[clinic start generated code]*/
4197
Larry Hastings2f936352014-08-05 14:04:04 +10004198static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004199os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst,
4200 int src_dir_fd, int dst_dir_fd)
4201/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004202{
4203 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4204}
4205
4206
4207/*[clinic input]
4208os.rmdir
4209
4210 path: path_t
4211 *
4212 dir_fd: dir_fd(requires='unlinkat') = None
4213
4214Remove a directory.
4215
4216If dir_fd is not None, it should be a file descriptor open to a directory,
4217 and path should be relative; path will then be relative to that directory.
4218dir_fd may not be implemented on your platform.
4219 If it is unavailable, using it will raise a NotImplementedError.
4220[clinic start generated code]*/
4221
Larry Hastings2f936352014-08-05 14:04:04 +10004222static PyObject *
4223os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004224/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004225{
4226 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004227
4228 Py_BEGIN_ALLOW_THREADS
4229#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004230 if (path->wide)
4231 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004232 else
Larry Hastings2f936352014-08-05 14:04:04 +10004233 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004234 result = !result; /* Windows, success=1, UNIX, success=0 */
4235#else
4236#ifdef HAVE_UNLINKAT
4237 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004238 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004239 else
4240#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004241 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004242#endif
4243 Py_END_ALLOW_THREADS
4244
Larry Hastings2f936352014-08-05 14:04:04 +10004245 if (result)
4246 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004247
Larry Hastings2f936352014-08-05 14:04:04 +10004248 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004249}
4250
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004251
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004252#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004253#ifdef MS_WINDOWS
4254/*[clinic input]
4255os.system -> long
4256
4257 command: Py_UNICODE
4258
4259Execute the command in a subshell.
4260[clinic start generated code]*/
4261
Larry Hastings2f936352014-08-05 14:04:04 +10004262static long
4263os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004264/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004265{
4266 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004268 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004269 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004270 return result;
4271}
4272#else /* MS_WINDOWS */
4273/*[clinic input]
4274os.system -> long
4275
4276 command: FSConverter
4277
4278Execute the command in a subshell.
4279[clinic start generated code]*/
4280
Larry Hastings2f936352014-08-05 14:04:04 +10004281static long
4282os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004283/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004284{
4285 long result;
4286 char *bytes = PyBytes_AsString(command);
4287 Py_BEGIN_ALLOW_THREADS
4288 result = system(bytes);
4289 Py_END_ALLOW_THREADS
4290 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004291}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004292#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004293#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004294
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004295
Larry Hastings2f936352014-08-05 14:04:04 +10004296/*[clinic input]
4297os.umask
4298
4299 mask: int
4300 /
4301
4302Set the current numeric umask and return the previous umask.
4303[clinic start generated code]*/
4304
Larry Hastings2f936352014-08-05 14:04:04 +10004305static PyObject *
4306os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004307/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004308{
4309 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004310 if (i < 0)
4311 return posix_error();
4312 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004313}
4314
Brian Curtind40e6f72010-07-08 21:39:08 +00004315#ifdef MS_WINDOWS
4316
4317/* override the default DeleteFileW behavior so that directory
4318symlinks can be removed with this function, the same as with
4319Unix symlinks */
4320BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4321{
4322 WIN32_FILE_ATTRIBUTE_DATA info;
4323 WIN32_FIND_DATAW find_data;
4324 HANDLE find_data_handle;
4325 int is_directory = 0;
4326 int is_link = 0;
4327
4328 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4329 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004330
Brian Curtind40e6f72010-07-08 21:39:08 +00004331 /* Get WIN32_FIND_DATA structure for the path to determine if
4332 it is a symlink */
4333 if(is_directory &&
4334 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4335 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4336
4337 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004338 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4339 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4340 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4341 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004342 FindClose(find_data_handle);
4343 }
4344 }
4345 }
4346
4347 if (is_directory && is_link)
4348 return RemoveDirectoryW(lpFileName);
4349
4350 return DeleteFileW(lpFileName);
4351}
4352#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004353
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004354
Larry Hastings2f936352014-08-05 14:04:04 +10004355/*[clinic input]
4356os.unlink
4357
4358 path: path_t
4359 *
4360 dir_fd: dir_fd(requires='unlinkat')=None
4361
4362Remove a file (same as remove()).
4363
4364If dir_fd is not None, it should be a file descriptor open to a directory,
4365 and path should be relative; path will then be relative to that directory.
4366dir_fd may not be implemented on your platform.
4367 If it is unavailable, using it will raise a NotImplementedError.
4368
4369[clinic start generated code]*/
4370
Larry Hastings2f936352014-08-05 14:04:04 +10004371static PyObject *
4372os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004373/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004374{
4375 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004376
4377 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004378 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004380 if (path->wide)
4381 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004382 else
Larry Hastings2f936352014-08-05 14:04:04 +10004383 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384 result = !result; /* Windows, success=1, UNIX, success=0 */
4385#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004386#ifdef HAVE_UNLINKAT
4387 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004388 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004389 else
4390#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004391 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004393 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004394 Py_END_ALLOW_THREADS
4395
Larry Hastings2f936352014-08-05 14:04:04 +10004396 if (result)
4397 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004398
Larry Hastings2f936352014-08-05 14:04:04 +10004399 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004400}
4401
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004402
Larry Hastings2f936352014-08-05 14:04:04 +10004403/*[clinic input]
4404os.remove = os.unlink
4405
4406Remove a file (same as unlink()).
4407
4408If dir_fd is not None, it should be a file descriptor open to a directory,
4409 and path should be relative; path will then be relative to that directory.
4410dir_fd may not be implemented on your platform.
4411 If it is unavailable, using it will raise a NotImplementedError.
4412[clinic start generated code]*/
4413
Larry Hastings2f936352014-08-05 14:04:04 +10004414static PyObject *
4415os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004416/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004417{
4418 return os_unlink_impl(module, path, dir_fd);
4419}
4420
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004421
Larry Hastings605a62d2012-06-24 04:33:36 -07004422static PyStructSequence_Field uname_result_fields[] = {
4423 {"sysname", "operating system name"},
4424 {"nodename", "name of machine on network (implementation-defined)"},
4425 {"release", "operating system release"},
4426 {"version", "operating system version"},
4427 {"machine", "hardware identifier"},
4428 {NULL}
4429};
4430
4431PyDoc_STRVAR(uname_result__doc__,
4432"uname_result: Result from os.uname().\n\n\
4433This object may be accessed either as a tuple of\n\
4434 (sysname, nodename, release, version, machine),\n\
4435or via the attributes sysname, nodename, release, version, and machine.\n\
4436\n\
4437See os.uname for more information.");
4438
4439static PyStructSequence_Desc uname_result_desc = {
4440 "uname_result", /* name */
4441 uname_result__doc__, /* doc */
4442 uname_result_fields,
4443 5
4444};
4445
4446static PyTypeObject UnameResultType;
4447
4448
4449#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004450/*[clinic input]
4451os.uname
4452
4453Return an object identifying the current operating system.
4454
4455The object behaves like a named tuple with the following fields:
4456 (sysname, nodename, release, version, machine)
4457
4458[clinic start generated code]*/
4459
Larry Hastings2f936352014-08-05 14:04:04 +10004460static PyObject *
4461os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004462/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004463{
Victor Stinner8c62be82010-05-06 00:08:46 +00004464 struct utsname u;
4465 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004466 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004467
Victor Stinner8c62be82010-05-06 00:08:46 +00004468 Py_BEGIN_ALLOW_THREADS
4469 res = uname(&u);
4470 Py_END_ALLOW_THREADS
4471 if (res < 0)
4472 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004473
4474 value = PyStructSequence_New(&UnameResultType);
4475 if (value == NULL)
4476 return NULL;
4477
4478#define SET(i, field) \
4479 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004480 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004481 if (!o) { \
4482 Py_DECREF(value); \
4483 return NULL; \
4484 } \
4485 PyStructSequence_SET_ITEM(value, i, o); \
4486 } \
4487
4488 SET(0, u.sysname);
4489 SET(1, u.nodename);
4490 SET(2, u.release);
4491 SET(3, u.version);
4492 SET(4, u.machine);
4493
4494#undef SET
4495
4496 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004497}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004498#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004499
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004500
Larry Hastings9cf065c2012-06-22 16:30:09 -07004501
4502typedef struct {
4503 int now;
4504 time_t atime_s;
4505 long atime_ns;
4506 time_t mtime_s;
4507 long mtime_ns;
4508} utime_t;
4509
4510/*
Victor Stinner484df002014-10-09 13:52:31 +02004511 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004512 * they also intentionally leak the declaration of a pointer named "time"
4513 */
4514#define UTIME_TO_TIMESPEC \
4515 struct timespec ts[2]; \
4516 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004517 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004518 time = NULL; \
4519 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004520 ts[0].tv_sec = ut->atime_s; \
4521 ts[0].tv_nsec = ut->atime_ns; \
4522 ts[1].tv_sec = ut->mtime_s; \
4523 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004524 time = ts; \
4525 } \
4526
4527#define UTIME_TO_TIMEVAL \
4528 struct timeval tv[2]; \
4529 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004530 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004531 time = NULL; \
4532 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004533 tv[0].tv_sec = ut->atime_s; \
4534 tv[0].tv_usec = ut->atime_ns / 1000; \
4535 tv[1].tv_sec = ut->mtime_s; \
4536 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004537 time = tv; \
4538 } \
4539
4540#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004541 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004543 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004544 time = NULL; \
4545 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004546 u.actime = ut->atime_s; \
4547 u.modtime = ut->mtime_s; \
4548 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004549 }
4550
4551#define UTIME_TO_TIME_T \
4552 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004553 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004554 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004555 time = NULL; \
4556 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004557 timet[0] = ut->atime_s; \
4558 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004559 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004560 } \
4561
4562
Victor Stinner528a9ab2015-09-03 21:30:26 +02004563#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004564
4565static int
Victor Stinner484df002014-10-09 13:52:31 +02004566utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004567{
4568#ifdef HAVE_UTIMENSAT
4569 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4570 UTIME_TO_TIMESPEC;
4571 return utimensat(dir_fd, path, time, flags);
4572#elif defined(HAVE_FUTIMESAT)
4573 UTIME_TO_TIMEVAL;
4574 /*
4575 * follow_symlinks will never be false here;
4576 * we only allow !follow_symlinks and dir_fd together
4577 * if we have utimensat()
4578 */
4579 assert(follow_symlinks);
4580 return futimesat(dir_fd, path, time);
4581#endif
4582}
4583
Larry Hastings2f936352014-08-05 14:04:04 +10004584 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4585#else
4586 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004587#endif
4588
Victor Stinner528a9ab2015-09-03 21:30:26 +02004589#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004590
4591static int
Victor Stinner484df002014-10-09 13:52:31 +02004592utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004593{
4594#ifdef HAVE_FUTIMENS
4595 UTIME_TO_TIMESPEC;
4596 return futimens(fd, time);
4597#else
4598 UTIME_TO_TIMEVAL;
4599 return futimes(fd, time);
4600#endif
4601}
4602
Larry Hastings2f936352014-08-05 14:04:04 +10004603 #define PATH_UTIME_HAVE_FD 1
4604#else
4605 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004606#endif
4607
4608
4609#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4610 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4611
4612#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4613
4614static int
Victor Stinner484df002014-10-09 13:52:31 +02004615utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004616{
4617#ifdef HAVE_UTIMENSAT
4618 UTIME_TO_TIMESPEC;
4619 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4620#else
4621 UTIME_TO_TIMEVAL;
4622 return lutimes(path, time);
4623#endif
4624}
4625
4626#endif
4627
4628#ifndef MS_WINDOWS
4629
4630static int
Victor Stinner484df002014-10-09 13:52:31 +02004631utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004632{
4633#ifdef HAVE_UTIMENSAT
4634 UTIME_TO_TIMESPEC;
4635 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4636#elif defined(HAVE_UTIMES)
4637 UTIME_TO_TIMEVAL;
4638 return utimes(path, time);
4639#elif defined(HAVE_UTIME_H)
4640 UTIME_TO_UTIMBUF;
4641 return utime(path, time);
4642#else
4643 UTIME_TO_TIME_T;
4644 return utime(path, time);
4645#endif
4646}
4647
4648#endif
4649
Larry Hastings76ad59b2012-05-03 00:30:07 -07004650static int
4651split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4652{
4653 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004654 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004655 divmod = PyNumber_Divmod(py_long, billion);
4656 if (!divmod)
4657 goto exit;
4658 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4659 if ((*s == -1) && PyErr_Occurred())
4660 goto exit;
4661 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004662 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004663 goto exit;
4664
4665 result = 1;
4666exit:
4667 Py_XDECREF(divmod);
4668 return result;
4669}
4670
Larry Hastings2f936352014-08-05 14:04:04 +10004671
4672/*[clinic input]
4673os.utime
4674
4675 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4676 times: object = NULL
4677 *
4678 ns: object = NULL
4679 dir_fd: dir_fd(requires='futimensat') = None
4680 follow_symlinks: bool=True
4681
Martin Panter0ff89092015-09-09 01:56:53 +00004682# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004683
4684Set the access and modified time of path.
4685
4686path may always be specified as a string.
4687On some platforms, path may also be specified as an open file descriptor.
4688 If this functionality is unavailable, using it raises an exception.
4689
4690If times is not None, it must be a tuple (atime, mtime);
4691 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004692If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004693 atime_ns and mtime_ns should be expressed as integer nanoseconds
4694 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004695If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004696Specifying tuples for both times and ns is an error.
4697
4698If dir_fd is not None, it should be a file descriptor open to a directory,
4699 and path should be relative; path will then be relative to that directory.
4700If follow_symlinks is False, and the last element of the path is a symbolic
4701 link, utime will modify the symbolic link itself instead of the file the
4702 link points to.
4703It is an error to use dir_fd or follow_symlinks when specifying path
4704 as an open file descriptor.
4705dir_fd and follow_symlinks may not be available on your platform.
4706 If they are unavailable, using them will raise a NotImplementedError.
4707
4708[clinic start generated code]*/
4709
Larry Hastings2f936352014-08-05 14:04:04 +10004710static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004711os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times,
4712 PyObject *ns, int dir_fd, int follow_symlinks)
Martin Panter0ff89092015-09-09 01:56:53 +00004713/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004714{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715#ifdef MS_WINDOWS
4716 HANDLE hFile;
4717 FILETIME atime, mtime;
4718#else
4719 int result;
4720#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004721
Larry Hastings9cf065c2012-06-22 16:30:09 -07004722 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004723 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004724
Christian Heimesb3c87242013-08-01 00:08:16 +02004725 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004726
Larry Hastings9cf065c2012-06-22 16:30:09 -07004727 if (times && (times != Py_None) && ns) {
4728 PyErr_SetString(PyExc_ValueError,
4729 "utime: you may specify either 'times'"
4730 " or 'ns' but not both");
4731 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004732 }
4733
4734 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004735 time_t a_sec, m_sec;
4736 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004737 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004738 PyErr_SetString(PyExc_TypeError,
4739 "utime: 'times' must be either"
4740 " a tuple of two ints or None");
4741 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004744 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004745 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004746 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004747 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004748 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004749 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004750 utime.atime_s = a_sec;
4751 utime.atime_ns = a_nsec;
4752 utime.mtime_s = m_sec;
4753 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004754 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004756 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004757 PyErr_SetString(PyExc_TypeError,
4758 "utime: 'ns' must be a tuple of two ints");
4759 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004762 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004764 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004765 &utime.mtime_s, &utime.mtime_ns)) {
4766 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004767 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004768 }
4769 else {
4770 /* times and ns are both None/unspecified. use "now". */
4771 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004772 }
4773
Larry Hastings9cf065c2012-06-22 16:30:09 -07004774#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4775 if (follow_symlinks_specified("utime", follow_symlinks))
4776 goto exit;
4777#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004778
Larry Hastings2f936352014-08-05 14:04:04 +10004779 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4780 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4781 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004783
Larry Hastings9cf065c2012-06-22 16:30:09 -07004784#if !defined(HAVE_UTIMENSAT)
4785 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004786 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 "utime: cannot use dir_fd and follow_symlinks "
4788 "together on this platform");
4789 goto exit;
4790 }
4791#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004792
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004793#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004795 if (path->wide)
4796 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004797 NULL, OPEN_EXISTING,
4798 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004799 else
Larry Hastings2f936352014-08-05 14:04:04 +10004800 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 NULL, OPEN_EXISTING,
4802 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004803 Py_END_ALLOW_THREADS
4804 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004805 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004806 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004807 }
4808
Larry Hastings9cf065c2012-06-22 16:30:09 -07004809 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004810 GetSystemTimeAsFileTime(&mtime);
4811 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004813 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004814 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4815 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004816 }
4817 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4818 /* Avoid putting the file name into the error here,
4819 as that may confuse the user into believing that
4820 something is wrong with the file, when it also
4821 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004822 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004823 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004824 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004825#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004826 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004827
Larry Hastings9cf065c2012-06-22 16:30:09 -07004828#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4829 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004830 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004832#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833
Victor Stinner528a9ab2015-09-03 21:30:26 +02004834#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004836 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004837 else
4838#endif
4839
Victor Stinner528a9ab2015-09-03 21:30:26 +02004840#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004841 if (path->fd != -1)
4842 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004843 else
4844#endif
4845
Larry Hastings2f936352014-08-05 14:04:04 +10004846 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004847
4848 Py_END_ALLOW_THREADS
4849
4850 if (result < 0) {
4851 /* see previous comment about not putting filename in error here */
4852 return_value = posix_error();
4853 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004854 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004855
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004856#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004857
4858 Py_INCREF(Py_None);
4859 return_value = Py_None;
4860
4861exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004862#ifdef MS_WINDOWS
4863 if (hFile != INVALID_HANDLE_VALUE)
4864 CloseHandle(hFile);
4865#endif
4866 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004867}
4868
Guido van Rossum3b066191991-06-04 19:40:25 +00004869/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004870
Larry Hastings2f936352014-08-05 14:04:04 +10004871
4872/*[clinic input]
4873os._exit
4874
4875 status: int
4876
4877Exit to the system with specified status, without normal exit processing.
4878[clinic start generated code]*/
4879
Larry Hastings2f936352014-08-05 14:04:04 +10004880static PyObject *
4881os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004882/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004883{
4884 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004885 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004886}
4887
Martin v. Löwis114619e2002-10-07 06:44:21 +00004888#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4889static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004890free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004891{
Victor Stinner8c62be82010-05-06 00:08:46 +00004892 Py_ssize_t i;
4893 for (i = 0; i < count; i++)
4894 PyMem_Free(array[i]);
4895 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004896}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004897
Antoine Pitrou69f71142009-05-24 21:25:49 +00004898static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004899int fsconvert_strdup(PyObject *o, char**out)
4900{
Victor Stinner8c62be82010-05-06 00:08:46 +00004901 PyObject *bytes;
4902 Py_ssize_t size;
4903 if (!PyUnicode_FSConverter(o, &bytes))
4904 return 0;
4905 size = PyBytes_GET_SIZE(bytes);
4906 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004907 if (!*out) {
4908 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004910 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004911 memcpy(*out, PyBytes_AsString(bytes), size+1);
4912 Py_DECREF(bytes);
4913 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004914}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004915#endif
4916
Ross Lagerwall7807c352011-03-17 20:20:30 +02004917#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004918static char**
4919parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4920{
Victor Stinner8c62be82010-05-06 00:08:46 +00004921 char **envlist;
4922 Py_ssize_t i, pos, envc;
4923 PyObject *keys=NULL, *vals=NULL;
4924 PyObject *key, *val, *key2, *val2;
4925 char *p, *k, *v;
4926 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004927
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 i = PyMapping_Size(env);
4929 if (i < 0)
4930 return NULL;
4931 envlist = PyMem_NEW(char *, i + 1);
4932 if (envlist == NULL) {
4933 PyErr_NoMemory();
4934 return NULL;
4935 }
4936 envc = 0;
4937 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004938 if (!keys)
4939 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004941 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004942 goto error;
4943 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4944 PyErr_Format(PyExc_TypeError,
4945 "env.keys() or env.values() is not a list");
4946 goto error;
4947 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004948
Victor Stinner8c62be82010-05-06 00:08:46 +00004949 for (pos = 0; pos < i; pos++) {
4950 key = PyList_GetItem(keys, pos);
4951 val = PyList_GetItem(vals, pos);
4952 if (!key || !val)
4953 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004954
Victor Stinner8c62be82010-05-06 00:08:46 +00004955 if (PyUnicode_FSConverter(key, &key2) == 0)
4956 goto error;
4957 if (PyUnicode_FSConverter(val, &val2) == 0) {
4958 Py_DECREF(key2);
4959 goto error;
4960 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004961
Victor Stinner8c62be82010-05-06 00:08:46 +00004962 k = PyBytes_AsString(key2);
4963 v = PyBytes_AsString(val2);
4964 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004965
Victor Stinner8c62be82010-05-06 00:08:46 +00004966 p = PyMem_NEW(char, len);
4967 if (p == NULL) {
4968 PyErr_NoMemory();
4969 Py_DECREF(key2);
4970 Py_DECREF(val2);
4971 goto error;
4972 }
4973 PyOS_snprintf(p, len, "%s=%s", k, v);
4974 envlist[envc++] = p;
4975 Py_DECREF(key2);
4976 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004977 }
4978 Py_DECREF(vals);
4979 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004980
Victor Stinner8c62be82010-05-06 00:08:46 +00004981 envlist[envc] = 0;
4982 *envc_ptr = envc;
4983 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004984
4985error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004986 Py_XDECREF(keys);
4987 Py_XDECREF(vals);
4988 while (--envc >= 0)
4989 PyMem_DEL(envlist[envc]);
4990 PyMem_DEL(envlist);
4991 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004992}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004993
Ross Lagerwall7807c352011-03-17 20:20:30 +02004994static char**
4995parse_arglist(PyObject* argv, Py_ssize_t *argc)
4996{
4997 int i;
4998 char **argvlist = PyMem_NEW(char *, *argc+1);
4999 if (argvlist == NULL) {
5000 PyErr_NoMemory();
5001 return NULL;
5002 }
5003 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005004 PyObject* item = PySequence_ITEM(argv, i);
5005 if (item == NULL)
5006 goto fail;
5007 if (!fsconvert_strdup(item, &argvlist[i])) {
5008 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005009 goto fail;
5010 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005011 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005012 }
5013 argvlist[*argc] = NULL;
5014 return argvlist;
5015fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005016 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005017 free_string_array(argvlist, *argc);
5018 return NULL;
5019}
5020#endif
5021
Larry Hastings2f936352014-08-05 14:04:04 +10005022
Ross Lagerwall7807c352011-03-17 20:20:30 +02005023#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005024/*[clinic input]
5025os.execv
5026
5027 path: FSConverter
5028 Path of executable file.
5029 argv: object
5030 Tuple or list of strings.
5031 /
5032
5033Execute an executable path with arguments, replacing current process.
5034[clinic start generated code]*/
5035
Larry Hastings2f936352014-08-05 14:04:04 +10005036static PyObject *
5037os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005038/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005039{
5040 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005041 char **argvlist;
5042 Py_ssize_t argc;
5043
5044 /* execv has two arguments: (path, argv), where
5045 argv is a list or tuple of strings. */
5046
Larry Hastings2f936352014-08-05 14:04:04 +10005047 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005048 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5049 PyErr_SetString(PyExc_TypeError,
5050 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005051 return NULL;
5052 }
5053 argc = PySequence_Size(argv);
5054 if (argc < 1) {
5055 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005056 return NULL;
5057 }
5058
5059 argvlist = parse_arglist(argv, &argc);
5060 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005061 return NULL;
5062 }
5063
Larry Hastings2f936352014-08-05 14:04:04 +10005064 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005065
5066 /* If we get here it's definitely an error */
5067
5068 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005069 return posix_error();
5070}
5071
Larry Hastings2f936352014-08-05 14:04:04 +10005072
5073/*[clinic input]
5074os.execve
5075
5076 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5077 Path of executable file.
5078 argv: object
5079 Tuple or list of strings.
5080 env: object
5081 Dictionary of strings mapping to strings.
5082
5083Execute an executable path with arguments, replacing current process.
5084[clinic start generated code]*/
5085
Larry Hastings2f936352014-08-05 14:04:04 +10005086static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005087os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv,
5088 PyObject *env)
5089/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005090{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005091 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005093 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005094
Victor Stinner8c62be82010-05-06 00:08:46 +00005095 /* execve has three arguments: (path, argv, env), where
5096 argv is a list or tuple of strings and env is a dictionary
5097 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005098
Ross Lagerwall7807c352011-03-17 20:20:30 +02005099 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005100 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005101 "execve: argv must be a tuple or list");
5102 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005104 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005105 if (!PyMapping_Check(env)) {
5106 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005107 "execve: environment must be a mapping object");
5108 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005109 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005110
Ross Lagerwall7807c352011-03-17 20:20:30 +02005111 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005113 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005115
Victor Stinner8c62be82010-05-06 00:08:46 +00005116 envlist = parse_envlist(env, &envc);
5117 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005118 goto fail;
5119
Larry Hastings9cf065c2012-06-22 16:30:09 -07005120#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005121 if (path->fd > -1)
5122 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005123 else
5124#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005125 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005126
5127 /* If we get here it's definitely an error */
5128
Larry Hastings2f936352014-08-05 14:04:04 +10005129 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005130
5131 while (--envc >= 0)
5132 PyMem_DEL(envlist[envc]);
5133 PyMem_DEL(envlist);
5134 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005135 if (argvlist)
5136 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005137 return NULL;
5138}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005139#endif /* HAVE_EXECV */
5140
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005141
Guido van Rossuma1065681999-01-25 23:20:23 +00005142#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005143/*[clinic input]
5144os.spawnv
5145
5146 mode: int
5147 Mode of process creation.
5148 path: FSConverter
5149 Path of executable file.
5150 argv: object
5151 Tuple or list of strings.
5152 /
5153
5154Execute the program specified by path in a new process.
5155[clinic start generated code]*/
5156
Larry Hastings2f936352014-08-05 14:04:04 +10005157static PyObject *
5158os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005159/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005160{
5161 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005163 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005164 Py_ssize_t argc;
5165 Py_intptr_t spawnval;
5166 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005167
Victor Stinner8c62be82010-05-06 00:08:46 +00005168 /* spawnv has three arguments: (mode, path, argv), where
5169 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005170
Larry Hastings2f936352014-08-05 14:04:04 +10005171 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005172 if (PyList_Check(argv)) {
5173 argc = PyList_Size(argv);
5174 getitem = PyList_GetItem;
5175 }
5176 else if (PyTuple_Check(argv)) {
5177 argc = PyTuple_Size(argv);
5178 getitem = PyTuple_GetItem;
5179 }
5180 else {
5181 PyErr_SetString(PyExc_TypeError,
5182 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005183 return NULL;
5184 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005185
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 argvlist = PyMem_NEW(char *, argc+1);
5187 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005188 return PyErr_NoMemory();
5189 }
5190 for (i = 0; i < argc; i++) {
5191 if (!fsconvert_strdup((*getitem)(argv, i),
5192 &argvlist[i])) {
5193 free_string_array(argvlist, i);
5194 PyErr_SetString(
5195 PyExc_TypeError,
5196 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005197 return NULL;
5198 }
5199 }
5200 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005201
Victor Stinner8c62be82010-05-06 00:08:46 +00005202 if (mode == _OLD_P_OVERLAY)
5203 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005204
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005206 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005210
Victor Stinner8c62be82010-05-06 00:08:46 +00005211 if (spawnval == -1)
5212 return posix_error();
5213 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005214 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005215}
5216
5217
Larry Hastings2f936352014-08-05 14:04:04 +10005218/*[clinic input]
5219os.spawnve
5220
5221 mode: int
5222 Mode of process creation.
5223 path: FSConverter
5224 Path of executable file.
5225 argv: object
5226 Tuple or list of strings.
5227 env: object
5228 Dictionary of strings mapping to strings.
5229 /
5230
5231Execute the program specified by path in a new process.
5232[clinic start generated code]*/
5233
Larry Hastings2f936352014-08-05 14:04:04 +10005234static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005235os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path,
5236 PyObject *argv, PyObject *env)
5237/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005238{
5239 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005240 char **argvlist;
5241 char **envlist;
5242 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005243 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005244 Py_intptr_t spawnval;
5245 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5246 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005247
Victor Stinner8c62be82010-05-06 00:08:46 +00005248 /* spawnve has four arguments: (mode, path, argv, env), where
5249 argv is a list or tuple of strings and env is a dictionary
5250 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005251
Larry Hastings2f936352014-08-05 14:04:04 +10005252 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005253 if (PyList_Check(argv)) {
5254 argc = PyList_Size(argv);
5255 getitem = PyList_GetItem;
5256 }
5257 else if (PyTuple_Check(argv)) {
5258 argc = PyTuple_Size(argv);
5259 getitem = PyTuple_GetItem;
5260 }
5261 else {
5262 PyErr_SetString(PyExc_TypeError,
5263 "spawnve() arg 2 must be a tuple or list");
5264 goto fail_0;
5265 }
5266 if (!PyMapping_Check(env)) {
5267 PyErr_SetString(PyExc_TypeError,
5268 "spawnve() arg 3 must be a mapping object");
5269 goto fail_0;
5270 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005271
Victor Stinner8c62be82010-05-06 00:08:46 +00005272 argvlist = PyMem_NEW(char *, argc+1);
5273 if (argvlist == NULL) {
5274 PyErr_NoMemory();
5275 goto fail_0;
5276 }
5277 for (i = 0; i < argc; i++) {
5278 if (!fsconvert_strdup((*getitem)(argv, i),
5279 &argvlist[i]))
5280 {
5281 lastarg = i;
5282 goto fail_1;
5283 }
5284 }
5285 lastarg = argc;
5286 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005287
Victor Stinner8c62be82010-05-06 00:08:46 +00005288 envlist = parse_envlist(env, &envc);
5289 if (envlist == NULL)
5290 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005291
Victor Stinner8c62be82010-05-06 00:08:46 +00005292 if (mode == _OLD_P_OVERLAY)
5293 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005294
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005296 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005298
Victor Stinner8c62be82010-05-06 00:08:46 +00005299 if (spawnval == -1)
5300 (void) posix_error();
5301 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005302 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005303
Victor Stinner8c62be82010-05-06 00:08:46 +00005304 while (--envc >= 0)
5305 PyMem_DEL(envlist[envc]);
5306 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005307 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005309 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005310 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005311}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005312
Guido van Rossuma1065681999-01-25 23:20:23 +00005313#endif /* HAVE_SPAWNV */
5314
5315
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005316#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005317/*[clinic input]
5318os.fork1
5319
5320Fork a child process with a single multiplexed (i.e., not bound) thread.
5321
5322Return 0 to child process and PID of child to parent process.
5323[clinic start generated code]*/
5324
Larry Hastings2f936352014-08-05 14:04:04 +10005325static PyObject *
5326os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005327/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005328{
Victor Stinner8c62be82010-05-06 00:08:46 +00005329 pid_t pid;
5330 int result = 0;
5331 _PyImport_AcquireLock();
5332 pid = fork1();
5333 if (pid == 0) {
5334 /* child: this clobbers and resets the import lock. */
5335 PyOS_AfterFork();
5336 } else {
5337 /* parent: release the import lock. */
5338 result = _PyImport_ReleaseLock();
5339 }
5340 if (pid == -1)
5341 return posix_error();
5342 if (result < 0) {
5343 /* Don't clobber the OSError if the fork failed. */
5344 PyErr_SetString(PyExc_RuntimeError,
5345 "not holding the import lock");
5346 return NULL;
5347 }
5348 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005349}
Larry Hastings2f936352014-08-05 14:04:04 +10005350#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005351
5352
Guido van Rossumad0ee831995-03-01 10:34:45 +00005353#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005354/*[clinic input]
5355os.fork
5356
5357Fork a child process.
5358
5359Return 0 to child process and PID of child to parent process.
5360[clinic start generated code]*/
5361
Larry Hastings2f936352014-08-05 14:04:04 +10005362static PyObject *
5363os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005364/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005365{
Victor Stinner8c62be82010-05-06 00:08:46 +00005366 pid_t pid;
5367 int result = 0;
5368 _PyImport_AcquireLock();
5369 pid = fork();
5370 if (pid == 0) {
5371 /* child: this clobbers and resets the import lock. */
5372 PyOS_AfterFork();
5373 } else {
5374 /* parent: release the import lock. */
5375 result = _PyImport_ReleaseLock();
5376 }
5377 if (pid == -1)
5378 return posix_error();
5379 if (result < 0) {
5380 /* Don't clobber the OSError if the fork failed. */
5381 PyErr_SetString(PyExc_RuntimeError,
5382 "not holding the import lock");
5383 return NULL;
5384 }
5385 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005386}
Larry Hastings2f936352014-08-05 14:04:04 +10005387#endif /* HAVE_FORK */
5388
Guido van Rossum85e3b011991-06-03 12:42:10 +00005389
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005390#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005391#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005392/*[clinic input]
5393os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005394
Larry Hastings2f936352014-08-05 14:04:04 +10005395 policy: int
5396
5397Get the maximum scheduling priority for policy.
5398[clinic start generated code]*/
5399
Larry Hastings2f936352014-08-05 14:04:04 +10005400static PyObject *
5401os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005402/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005403{
5404 int max;
5405
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005406 max = sched_get_priority_max(policy);
5407 if (max < 0)
5408 return posix_error();
5409 return PyLong_FromLong(max);
5410}
5411
Larry Hastings2f936352014-08-05 14:04:04 +10005412
5413/*[clinic input]
5414os.sched_get_priority_min
5415
5416 policy: int
5417
5418Get the minimum scheduling priority for policy.
5419[clinic start generated code]*/
5420
Larry Hastings2f936352014-08-05 14:04:04 +10005421static PyObject *
5422os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005423/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005424{
5425 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005426 if (min < 0)
5427 return posix_error();
5428 return PyLong_FromLong(min);
5429}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005430#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5431
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005432
Larry Hastings2f936352014-08-05 14:04:04 +10005433#ifdef HAVE_SCHED_SETSCHEDULER
5434/*[clinic input]
5435os.sched_getscheduler
5436 pid: pid_t
5437 /
5438
5439Get the scheduling policy for the process identifiedy by pid.
5440
5441Passing 0 for pid returns the scheduling policy for the calling process.
5442[clinic start generated code]*/
5443
Larry Hastings2f936352014-08-05 14:04:04 +10005444static PyObject *
5445os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005446/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005447{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005448 int policy;
5449
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005450 policy = sched_getscheduler(pid);
5451 if (policy < 0)
5452 return posix_error();
5453 return PyLong_FromLong(policy);
5454}
Larry Hastings2f936352014-08-05 14:04:04 +10005455#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005456
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005457
5458#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005459/*[clinic input]
5460class os.sched_param "PyObject *" "&SchedParamType"
5461
5462@classmethod
5463os.sched_param.__new__
5464
5465 sched_priority: object
5466 A scheduling parameter.
5467
5468Current has only one field: sched_priority");
5469[clinic start generated code]*/
5470
Larry Hastings2f936352014-08-05 14:04:04 +10005471static PyObject *
5472os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005473/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005474{
5475 PyObject *res;
5476
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005477 res = PyStructSequence_New(type);
5478 if (!res)
5479 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005480 Py_INCREF(sched_priority);
5481 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005482 return res;
5483}
5484
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005485
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005486PyDoc_VAR(os_sched_param__doc__);
5487
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005488static PyStructSequence_Field sched_param_fields[] = {
5489 {"sched_priority", "the scheduling priority"},
5490 {0}
5491};
5492
5493static PyStructSequence_Desc sched_param_desc = {
5494 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005495 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005496 sched_param_fields,
5497 1
5498};
5499
5500static int
5501convert_sched_param(PyObject *param, struct sched_param *res)
5502{
5503 long priority;
5504
5505 if (Py_TYPE(param) != &SchedParamType) {
5506 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5507 return 0;
5508 }
5509 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5510 if (priority == -1 && PyErr_Occurred())
5511 return 0;
5512 if (priority > INT_MAX || priority < INT_MIN) {
5513 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5514 return 0;
5515 }
5516 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5517 return 1;
5518}
Larry Hastings2f936352014-08-05 14:04:04 +10005519#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005520
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005521
5522#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005523/*[clinic input]
5524os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005525
Larry Hastings2f936352014-08-05 14:04:04 +10005526 pid: pid_t
5527 policy: int
5528 param: sched_param
5529 /
5530
5531Set the scheduling policy for the process identified by pid.
5532
5533If pid is 0, the calling process is changed.
5534param is an instance of sched_param.
5535[clinic start generated code]*/
5536
Larry Hastings2f936352014-08-05 14:04:04 +10005537static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005538os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy,
5539 struct sched_param *param)
5540/*[clinic end generated code: output=37053e5c528c35c9 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005541{
Jesus Cea9c822272011-09-10 01:40:52 +02005542 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005543 ** sched_setscheduler() returns 0 in Linux, but the previous
5544 ** scheduling policy under Solaris/Illumos, and others.
5545 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005546 */
Larry Hastings2f936352014-08-05 14:04:04 +10005547 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005548 return posix_error();
5549 Py_RETURN_NONE;
5550}
Larry Hastings2f936352014-08-05 14:04:04 +10005551#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005552
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005553
5554#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005555/*[clinic input]
5556os.sched_getparam
5557 pid: pid_t
5558 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005559
Larry Hastings2f936352014-08-05 14:04:04 +10005560Returns scheduling parameters for the process identified by pid.
5561
5562If pid is 0, returns parameters for the calling process.
5563Return value is an instance of sched_param.
5564[clinic start generated code]*/
5565
Larry Hastings2f936352014-08-05 14:04:04 +10005566static PyObject *
5567os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005568/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005569{
5570 struct sched_param param;
5571 PyObject *result;
5572 PyObject *priority;
5573
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005574 if (sched_getparam(pid, &param))
5575 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005576 result = PyStructSequence_New(&SchedParamType);
5577 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005578 return NULL;
5579 priority = PyLong_FromLong(param.sched_priority);
5580 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005581 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005582 return NULL;
5583 }
Larry Hastings2f936352014-08-05 14:04:04 +10005584 PyStructSequence_SET_ITEM(result, 0, priority);
5585 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005586}
5587
Larry Hastings2f936352014-08-05 14:04:04 +10005588
5589/*[clinic input]
5590os.sched_setparam
5591 pid: pid_t
5592 param: sched_param
5593 /
5594
5595Set scheduling parameters for the process identified by pid.
5596
5597If pid is 0, sets parameters for the calling process.
5598param should be an instance of sched_param.
5599[clinic start generated code]*/
5600
Larry Hastings2f936352014-08-05 14:04:04 +10005601static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005602os_sched_setparam_impl(PyModuleDef *module, pid_t pid,
5603 struct sched_param *param)
5604/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005605{
5606 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005607 return posix_error();
5608 Py_RETURN_NONE;
5609}
Larry Hastings2f936352014-08-05 14:04:04 +10005610#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005611
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005612
5613#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005614/*[clinic input]
5615os.sched_rr_get_interval -> double
5616 pid: pid_t
5617 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005618
Larry Hastings2f936352014-08-05 14:04:04 +10005619Return the round-robin quantum for the process identified by pid, in seconds.
5620
5621Value returned is a float.
5622[clinic start generated code]*/
5623
Larry Hastings2f936352014-08-05 14:04:04 +10005624static double
5625os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005626/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005627{
5628 struct timespec interval;
5629 if (sched_rr_get_interval(pid, &interval)) {
5630 posix_error();
5631 return -1.0;
5632 }
5633 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5634}
5635#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005636
Larry Hastings2f936352014-08-05 14:04:04 +10005637
5638/*[clinic input]
5639os.sched_yield
5640
5641Voluntarily relinquish the CPU.
5642[clinic start generated code]*/
5643
Larry Hastings2f936352014-08-05 14:04:04 +10005644static PyObject *
5645os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005646/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005647{
5648 if (sched_yield())
5649 return posix_error();
5650 Py_RETURN_NONE;
5651}
5652
Benjamin Peterson2740af82011-08-02 17:41:34 -05005653#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005654/* The minimum number of CPUs allocated in a cpu_set_t */
5655static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005656
Larry Hastings2f936352014-08-05 14:04:04 +10005657/*[clinic input]
5658os.sched_setaffinity
5659 pid: pid_t
5660 mask : object
5661 /
5662
5663Set the CPU affinity of the process identified by pid to mask.
5664
5665mask should be an iterable of integers identifying CPUs.
5666[clinic start generated code]*/
5667
Larry Hastings2f936352014-08-05 14:04:04 +10005668static PyObject *
5669os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005670/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005671{
Antoine Pitrou84869872012-08-04 16:16:35 +02005672 int ncpus;
5673 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005674 cpu_set_t *cpu_set = NULL;
5675 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005676
Larry Hastings2f936352014-08-05 14:04:04 +10005677 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005678 if (iterator == NULL)
5679 return NULL;
5680
5681 ncpus = NCPUS_START;
5682 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005683 cpu_set = CPU_ALLOC(ncpus);
5684 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005685 PyErr_NoMemory();
5686 goto error;
5687 }
Larry Hastings2f936352014-08-05 14:04:04 +10005688 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005689
5690 while ((item = PyIter_Next(iterator))) {
5691 long cpu;
5692 if (!PyLong_Check(item)) {
5693 PyErr_Format(PyExc_TypeError,
5694 "expected an iterator of ints, "
5695 "but iterator yielded %R",
5696 Py_TYPE(item));
5697 Py_DECREF(item);
5698 goto error;
5699 }
5700 cpu = PyLong_AsLong(item);
5701 Py_DECREF(item);
5702 if (cpu < 0) {
5703 if (!PyErr_Occurred())
5704 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5705 goto error;
5706 }
5707 if (cpu > INT_MAX - 1) {
5708 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5709 goto error;
5710 }
5711 if (cpu >= ncpus) {
5712 /* Grow CPU mask to fit the CPU number */
5713 int newncpus = ncpus;
5714 cpu_set_t *newmask;
5715 size_t newsetsize;
5716 while (newncpus <= cpu) {
5717 if (newncpus > INT_MAX / 2)
5718 newncpus = cpu + 1;
5719 else
5720 newncpus = newncpus * 2;
5721 }
5722 newmask = CPU_ALLOC(newncpus);
5723 if (newmask == NULL) {
5724 PyErr_NoMemory();
5725 goto error;
5726 }
5727 newsetsize = CPU_ALLOC_SIZE(newncpus);
5728 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005729 memcpy(newmask, cpu_set, setsize);
5730 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005731 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005732 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005733 ncpus = newncpus;
5734 }
Larry Hastings2f936352014-08-05 14:04:04 +10005735 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005736 }
5737 Py_CLEAR(iterator);
5738
Larry Hastings2f936352014-08-05 14:04:04 +10005739 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005740 posix_error();
5741 goto error;
5742 }
Larry Hastings2f936352014-08-05 14:04:04 +10005743 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005744 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005745
5746error:
Larry Hastings2f936352014-08-05 14:04:04 +10005747 if (cpu_set)
5748 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005749 Py_XDECREF(iterator);
5750 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005751}
5752
Larry Hastings2f936352014-08-05 14:04:04 +10005753
5754/*[clinic input]
5755os.sched_getaffinity
5756 pid: pid_t
5757 /
5758
5759Return the affinity of the process identified by pid.
5760
5761The affinity is returned as a set of CPU identifiers.
5762[clinic start generated code]*/
5763
Larry Hastings2f936352014-08-05 14:04:04 +10005764static PyObject *
5765os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005766/*[clinic end generated code: output=b431a8f310e369e7 input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005767{
Antoine Pitrou84869872012-08-04 16:16:35 +02005768 int cpu, ncpus, count;
5769 size_t setsize;
5770 cpu_set_t *mask = NULL;
5771 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005772
Antoine Pitrou84869872012-08-04 16:16:35 +02005773 ncpus = NCPUS_START;
5774 while (1) {
5775 setsize = CPU_ALLOC_SIZE(ncpus);
5776 mask = CPU_ALLOC(ncpus);
5777 if (mask == NULL)
5778 return PyErr_NoMemory();
5779 if (sched_getaffinity(pid, setsize, mask) == 0)
5780 break;
5781 CPU_FREE(mask);
5782 if (errno != EINVAL)
5783 return posix_error();
5784 if (ncpus > INT_MAX / 2) {
5785 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5786 "a large enough CPU set");
5787 return NULL;
5788 }
5789 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005790 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005791
5792 res = PySet_New(NULL);
5793 if (res == NULL)
5794 goto error;
5795 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5796 if (CPU_ISSET_S(cpu, setsize, mask)) {
5797 PyObject *cpu_num = PyLong_FromLong(cpu);
5798 --count;
5799 if (cpu_num == NULL)
5800 goto error;
5801 if (PySet_Add(res, cpu_num)) {
5802 Py_DECREF(cpu_num);
5803 goto error;
5804 }
5805 Py_DECREF(cpu_num);
5806 }
5807 }
5808 CPU_FREE(mask);
5809 return res;
5810
5811error:
5812 if (mask)
5813 CPU_FREE(mask);
5814 Py_XDECREF(res);
5815 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005816}
5817
Benjamin Peterson2740af82011-08-02 17:41:34 -05005818#endif /* HAVE_SCHED_SETAFFINITY */
5819
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005820#endif /* HAVE_SCHED_H */
5821
Larry Hastings2f936352014-08-05 14:04:04 +10005822
Neal Norwitzb59798b2003-03-21 01:43:31 +00005823/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005824/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5825#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005826#define DEV_PTY_FILE "/dev/ptc"
5827#define HAVE_DEV_PTMX
5828#else
5829#define DEV_PTY_FILE "/dev/ptmx"
5830#endif
5831
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005832#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005833#ifdef HAVE_PTY_H
5834#include <pty.h>
5835#else
5836#ifdef HAVE_LIBUTIL_H
5837#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005838#else
5839#ifdef HAVE_UTIL_H
5840#include <util.h>
5841#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005842#endif /* HAVE_LIBUTIL_H */
5843#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005844#ifdef HAVE_STROPTS_H
5845#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005846#endif
5847#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005848
Larry Hastings2f936352014-08-05 14:04:04 +10005849
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005850#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005851/*[clinic input]
5852os.openpty
5853
5854Open a pseudo-terminal.
5855
5856Return a tuple of (master_fd, slave_fd) containing open file descriptors
5857for both the master and slave ends.
5858[clinic start generated code]*/
5859
Larry Hastings2f936352014-08-05 14:04:04 +10005860static PyObject *
5861os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005862/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005863{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005864 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005865#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005866 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005867#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005868#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005870#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005871 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005872#endif
5873#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005874
Thomas Wouters70c21a12000-07-14 14:28:33 +00005875#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005877 goto posix_error;
5878
5879 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5880 goto error;
5881 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5882 goto error;
5883
Neal Norwitzb59798b2003-03-21 01:43:31 +00005884#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005885 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5886 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005887 goto posix_error;
5888 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5889 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005890
Victor Stinnerdaf45552013-08-28 00:53:59 +02005891 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005893 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005894
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005895#else
Victor Stinner000de532013-11-25 23:19:58 +01005896 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005897 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005898 goto posix_error;
5899
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005901
Victor Stinner8c62be82010-05-06 00:08:46 +00005902 /* change permission of slave */
5903 if (grantpt(master_fd) < 0) {
5904 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005905 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005907
Victor Stinner8c62be82010-05-06 00:08:46 +00005908 /* unlock slave */
5909 if (unlockpt(master_fd) < 0) {
5910 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005913
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005915
Victor Stinner8c62be82010-05-06 00:08:46 +00005916 slave_name = ptsname(master_fd); /* get name of slave */
5917 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005918 goto posix_error;
5919
5920 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005921 if (slave_fd == -1)
5922 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005923
5924 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5925 goto posix_error;
5926
Neal Norwitzb59798b2003-03-21 01:43:31 +00005927#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005928 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5929 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005930#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005931 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005932#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005933#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005934#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005935
Victor Stinner8c62be82010-05-06 00:08:46 +00005936 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005937
Victor Stinnerdaf45552013-08-28 00:53:59 +02005938posix_error:
5939 posix_error();
5940error:
5941 if (master_fd != -1)
5942 close(master_fd);
5943 if (slave_fd != -1)
5944 close(slave_fd);
5945 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005946}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005947#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005948
Larry Hastings2f936352014-08-05 14:04:04 +10005949
Fred Drake8cef4cf2000-06-28 16:40:38 +00005950#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005951/*[clinic input]
5952os.forkpty
5953
5954Fork a new process with a new pseudo-terminal as controlling tty.
5955
5956Returns a tuple of (pid, master_fd).
5957Like fork(), return pid of 0 to the child process,
5958and pid of child to the parent process.
5959To both, return fd of newly opened pseudo-terminal.
5960[clinic start generated code]*/
5961
Larry Hastings2f936352014-08-05 14:04:04 +10005962static PyObject *
5963os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005964/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005965{
Victor Stinner8c62be82010-05-06 00:08:46 +00005966 int master_fd = -1, result = 0;
5967 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005968
Victor Stinner8c62be82010-05-06 00:08:46 +00005969 _PyImport_AcquireLock();
5970 pid = forkpty(&master_fd, NULL, NULL, NULL);
5971 if (pid == 0) {
5972 /* child: this clobbers and resets the import lock. */
5973 PyOS_AfterFork();
5974 } else {
5975 /* parent: release the import lock. */
5976 result = _PyImport_ReleaseLock();
5977 }
5978 if (pid == -1)
5979 return posix_error();
5980 if (result < 0) {
5981 /* Don't clobber the OSError if the fork failed. */
5982 PyErr_SetString(PyExc_RuntimeError,
5983 "not holding the import lock");
5984 return NULL;
5985 }
5986 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005987}
Larry Hastings2f936352014-08-05 14:04:04 +10005988#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005989
Ross Lagerwall7807c352011-03-17 20:20:30 +02005990
Guido van Rossumad0ee831995-03-01 10:34:45 +00005991#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005992/*[clinic input]
5993os.getegid
5994
5995Return the current process's effective group id.
5996[clinic start generated code]*/
5997
Larry Hastings2f936352014-08-05 14:04:04 +10005998static PyObject *
5999os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006000/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006001{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006002 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006003}
Larry Hastings2f936352014-08-05 14:04:04 +10006004#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006006
Guido van Rossumad0ee831995-03-01 10:34:45 +00006007#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006008/*[clinic input]
6009os.geteuid
6010
6011Return the current process's effective user id.
6012[clinic start generated code]*/
6013
Larry Hastings2f936352014-08-05 14:04:04 +10006014static PyObject *
6015os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006016/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006017{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006018 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006019}
Larry Hastings2f936352014-08-05 14:04:04 +10006020#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006022
Guido van Rossumad0ee831995-03-01 10:34:45 +00006023#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006024/*[clinic input]
6025os.getgid
6026
6027Return the current process's group id.
6028[clinic start generated code]*/
6029
Larry Hastings2f936352014-08-05 14:04:04 +10006030static PyObject *
6031os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006032/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006033{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006034 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006035}
Larry Hastings2f936352014-08-05 14:04:04 +10006036#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006037
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006038
Larry Hastings2f936352014-08-05 14:04:04 +10006039/*[clinic input]
6040os.getpid
6041
6042Return the current process id.
6043[clinic start generated code]*/
6044
Larry Hastings2f936352014-08-05 14:04:04 +10006045static PyObject *
6046os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006047/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006048{
Victor Stinner8c62be82010-05-06 00:08:46 +00006049 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006050}
6051
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006052#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006053
6054/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006055PyDoc_STRVAR(posix_getgrouplist__doc__,
6056"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6057Returns a list of groups to which a user belongs.\n\n\
6058 user: username to lookup\n\
6059 group: base group id of the user");
6060
6061static PyObject *
6062posix_getgrouplist(PyObject *self, PyObject *args)
6063{
6064#ifdef NGROUPS_MAX
6065#define MAX_GROUPS NGROUPS_MAX
6066#else
6067 /* defined to be 16 on Solaris7, so this should be a small number */
6068#define MAX_GROUPS 64
6069#endif
6070
6071 const char *user;
6072 int i, ngroups;
6073 PyObject *list;
6074#ifdef __APPLE__
6075 int *groups, basegid;
6076#else
6077 gid_t *groups, basegid;
6078#endif
6079 ngroups = MAX_GROUPS;
6080
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006081#ifdef __APPLE__
6082 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006083 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006084#else
6085 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6086 _Py_Gid_Converter, &basegid))
6087 return NULL;
6088#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006089
6090#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006091 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006092#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006093 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006094#endif
6095 if (groups == NULL)
6096 return PyErr_NoMemory();
6097
6098 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6099 PyMem_Del(groups);
6100 return posix_error();
6101 }
6102
6103 list = PyList_New(ngroups);
6104 if (list == NULL) {
6105 PyMem_Del(groups);
6106 return NULL;
6107 }
6108
6109 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006110#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006111 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006112#else
6113 PyObject *o = _PyLong_FromGid(groups[i]);
6114#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006115 if (o == NULL) {
6116 Py_DECREF(list);
6117 PyMem_Del(groups);
6118 return NULL;
6119 }
6120 PyList_SET_ITEM(list, i, o);
6121 }
6122
6123 PyMem_Del(groups);
6124
6125 return list;
6126}
Larry Hastings2f936352014-08-05 14:04:04 +10006127#endif /* HAVE_GETGROUPLIST */
6128
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006129
Fred Drakec9680921999-12-13 16:37:25 +00006130#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006131/*[clinic input]
6132os.getgroups
6133
6134Return list of supplemental group IDs for the process.
6135[clinic start generated code]*/
6136
Larry Hastings2f936352014-08-05 14:04:04 +10006137static PyObject *
6138os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006139/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006140{
6141 PyObject *result = NULL;
6142
Fred Drakec9680921999-12-13 16:37:25 +00006143#ifdef NGROUPS_MAX
6144#define MAX_GROUPS NGROUPS_MAX
6145#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006146 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006147#define MAX_GROUPS 64
6148#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006149 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006150
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006151 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006152 * This is a helper variable to store the intermediate result when
6153 * that happens.
6154 *
6155 * To keep the code readable the OSX behaviour is unconditional,
6156 * according to the POSIX spec this should be safe on all unix-y
6157 * systems.
6158 */
6159 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006160 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006161
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006162#ifdef __APPLE__
6163 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6164 * there are more groups than can fit in grouplist. Therefore, on OS X
6165 * always first call getgroups with length 0 to get the actual number
6166 * of groups.
6167 */
6168 n = getgroups(0, NULL);
6169 if (n < 0) {
6170 return posix_error();
6171 } else if (n <= MAX_GROUPS) {
6172 /* groups will fit in existing array */
6173 alt_grouplist = grouplist;
6174 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006175 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006176 if (alt_grouplist == NULL) {
6177 errno = EINVAL;
6178 return posix_error();
6179 }
6180 }
6181
6182 n = getgroups(n, alt_grouplist);
6183 if (n == -1) {
6184 if (alt_grouplist != grouplist) {
6185 PyMem_Free(alt_grouplist);
6186 }
6187 return posix_error();
6188 }
6189#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006190 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006191 if (n < 0) {
6192 if (errno == EINVAL) {
6193 n = getgroups(0, NULL);
6194 if (n == -1) {
6195 return posix_error();
6196 }
6197 if (n == 0) {
6198 /* Avoid malloc(0) */
6199 alt_grouplist = grouplist;
6200 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006201 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006202 if (alt_grouplist == NULL) {
6203 errno = EINVAL;
6204 return posix_error();
6205 }
6206 n = getgroups(n, alt_grouplist);
6207 if (n == -1) {
6208 PyMem_Free(alt_grouplist);
6209 return posix_error();
6210 }
6211 }
6212 } else {
6213 return posix_error();
6214 }
6215 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006216#endif
6217
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006218 result = PyList_New(n);
6219 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006220 int i;
6221 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006222 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006223 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006224 Py_DECREF(result);
6225 result = NULL;
6226 break;
Fred Drakec9680921999-12-13 16:37:25 +00006227 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006228 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006229 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006230 }
6231
6232 if (alt_grouplist != grouplist) {
6233 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006234 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006235
Fred Drakec9680921999-12-13 16:37:25 +00006236 return result;
6237}
Larry Hastings2f936352014-08-05 14:04:04 +10006238#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006239
Antoine Pitroub7572f02009-12-02 20:46:48 +00006240#ifdef HAVE_INITGROUPS
6241PyDoc_STRVAR(posix_initgroups__doc__,
6242"initgroups(username, gid) -> None\n\n\
6243Call the system initgroups() to initialize the group access list with all of\n\
6244the groups of which the specified username is a member, plus the specified\n\
6245group id.");
6246
Larry Hastings2f936352014-08-05 14:04:04 +10006247/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006248static PyObject *
6249posix_initgroups(PyObject *self, PyObject *args)
6250{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006251 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006252 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006253 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006254#ifdef __APPLE__
6255 int gid;
6256#else
6257 gid_t gid;
6258#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006259
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006260#ifdef __APPLE__
6261 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6262 PyUnicode_FSConverter, &oname,
6263 &gid))
6264#else
6265 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6266 PyUnicode_FSConverter, &oname,
6267 _Py_Gid_Converter, &gid))
6268#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006269 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006270 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006271
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006272 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006273 Py_DECREF(oname);
6274 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006276
Victor Stinner8c62be82010-05-06 00:08:46 +00006277 Py_INCREF(Py_None);
6278 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006279}
Larry Hastings2f936352014-08-05 14:04:04 +10006280#endif /* HAVE_INITGROUPS */
6281
Antoine Pitroub7572f02009-12-02 20:46:48 +00006282
Martin v. Löwis606edc12002-06-13 21:09:11 +00006283#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006284/*[clinic input]
6285os.getpgid
6286
6287 pid: pid_t
6288
6289Call the system call getpgid(), and return the result.
6290[clinic start generated code]*/
6291
Larry Hastings2f936352014-08-05 14:04:04 +10006292static PyObject *
6293os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006294/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006295{
6296 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006297 if (pgid < 0)
6298 return posix_error();
6299 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006300}
6301#endif /* HAVE_GETPGID */
6302
6303
Guido van Rossumb6775db1994-08-01 11:34:53 +00006304#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006305/*[clinic input]
6306os.getpgrp
6307
6308Return the current process group id.
6309[clinic start generated code]*/
6310
Larry Hastings2f936352014-08-05 14:04:04 +10006311static PyObject *
6312os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006313/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006314{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006315#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006317#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006318 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006319#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006320}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006321#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006322
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006323
Guido van Rossumb6775db1994-08-01 11:34:53 +00006324#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006325/*[clinic input]
6326os.setpgrp
6327
6328Make the current process the leader of its process group.
6329[clinic start generated code]*/
6330
Larry Hastings2f936352014-08-05 14:04:04 +10006331static PyObject *
6332os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006333/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006334{
Guido van Rossum64933891994-10-20 21:56:42 +00006335#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006337#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006339#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006340 return posix_error();
6341 Py_INCREF(Py_None);
6342 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006343}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006344#endif /* HAVE_SETPGRP */
6345
Guido van Rossumad0ee831995-03-01 10:34:45 +00006346#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006347
6348#ifdef MS_WINDOWS
6349#include <tlhelp32.h>
6350
6351static PyObject*
6352win32_getppid()
6353{
6354 HANDLE snapshot;
6355 pid_t mypid;
6356 PyObject* result = NULL;
6357 BOOL have_record;
6358 PROCESSENTRY32 pe;
6359
6360 mypid = getpid(); /* This function never fails */
6361
6362 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6363 if (snapshot == INVALID_HANDLE_VALUE)
6364 return PyErr_SetFromWindowsErr(GetLastError());
6365
6366 pe.dwSize = sizeof(pe);
6367 have_record = Process32First(snapshot, &pe);
6368 while (have_record) {
6369 if (mypid == (pid_t)pe.th32ProcessID) {
6370 /* We could cache the ulong value in a static variable. */
6371 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6372 break;
6373 }
6374
6375 have_record = Process32Next(snapshot, &pe);
6376 }
6377
6378 /* If our loop exits and our pid was not found (result will be NULL)
6379 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6380 * error anyway, so let's raise it. */
6381 if (!result)
6382 result = PyErr_SetFromWindowsErr(GetLastError());
6383
6384 CloseHandle(snapshot);
6385
6386 return result;
6387}
6388#endif /*MS_WINDOWS*/
6389
Larry Hastings2f936352014-08-05 14:04:04 +10006390
6391/*[clinic input]
6392os.getppid
6393
6394Return the parent's process id.
6395
6396If the parent process has already exited, Windows machines will still
6397return its id; others systems will return the id of the 'init' process (1).
6398[clinic start generated code]*/
6399
Larry Hastings2f936352014-08-05 14:04:04 +10006400static PyObject *
6401os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006402/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006403{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006404#ifdef MS_WINDOWS
6405 return win32_getppid();
6406#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006407 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006408#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006409}
6410#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006411
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006412
Fred Drake12c6e2d1999-12-14 21:25:03 +00006413#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006414/*[clinic input]
6415os.getlogin
6416
6417Return the actual login name.
6418[clinic start generated code]*/
6419
Larry Hastings2f936352014-08-05 14:04:04 +10006420static PyObject *
6421os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006422/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006423{
Victor Stinner8c62be82010-05-06 00:08:46 +00006424 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006425#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006426 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006427 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006428
6429 if (GetUserNameW(user_name, &num_chars)) {
6430 /* num_chars is the number of unicode chars plus null terminator */
6431 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006432 }
6433 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006434 result = PyErr_SetFromWindowsErr(GetLastError());
6435#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006436 char *name;
6437 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006438
Victor Stinner8c62be82010-05-06 00:08:46 +00006439 errno = 0;
6440 name = getlogin();
6441 if (name == NULL) {
6442 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006443 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006444 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006445 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006446 }
6447 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006448 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006449 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006450#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006451 return result;
6452}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006453#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006454
Larry Hastings2f936352014-08-05 14:04:04 +10006455
Guido van Rossumad0ee831995-03-01 10:34:45 +00006456#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006457/*[clinic input]
6458os.getuid
6459
6460Return the current process's user id.
6461[clinic start generated code]*/
6462
Larry Hastings2f936352014-08-05 14:04:04 +10006463static PyObject *
6464os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006465/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006466{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006467 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006468}
Larry Hastings2f936352014-08-05 14:04:04 +10006469#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006470
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006471
Brian Curtineb24d742010-04-12 17:16:38 +00006472#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006473#define HAVE_KILL
6474#endif /* MS_WINDOWS */
6475
6476#ifdef HAVE_KILL
6477/*[clinic input]
6478os.kill
6479
6480 pid: pid_t
6481 signal: Py_ssize_t
6482 /
6483
6484Kill a process with a signal.
6485[clinic start generated code]*/
6486
Larry Hastings2f936352014-08-05 14:04:04 +10006487static PyObject *
6488os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006489/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006490#ifndef MS_WINDOWS
6491{
6492 if (kill(pid, (int)signal) == -1)
6493 return posix_error();
6494 Py_RETURN_NONE;
6495}
6496#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006497{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006498 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006499 DWORD sig = (DWORD)signal;
6500 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006502
Victor Stinner8c62be82010-05-06 00:08:46 +00006503 /* Console processes which share a common console can be sent CTRL+C or
6504 CTRL+BREAK events, provided they handle said events. */
6505 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006506 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006507 err = GetLastError();
6508 PyErr_SetFromWindowsErr(err);
6509 }
6510 else
6511 Py_RETURN_NONE;
6512 }
Brian Curtineb24d742010-04-12 17:16:38 +00006513
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6515 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006516 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006517 if (handle == NULL) {
6518 err = GetLastError();
6519 return PyErr_SetFromWindowsErr(err);
6520 }
Brian Curtineb24d742010-04-12 17:16:38 +00006521
Victor Stinner8c62be82010-05-06 00:08:46 +00006522 if (TerminateProcess(handle, sig) == 0) {
6523 err = GetLastError();
6524 result = PyErr_SetFromWindowsErr(err);
6525 } else {
6526 Py_INCREF(Py_None);
6527 result = Py_None;
6528 }
Brian Curtineb24d742010-04-12 17:16:38 +00006529
Victor Stinner8c62be82010-05-06 00:08:46 +00006530 CloseHandle(handle);
6531 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006532}
Larry Hastings2f936352014-08-05 14:04:04 +10006533#endif /* !MS_WINDOWS */
6534#endif /* HAVE_KILL */
6535
6536
6537#ifdef HAVE_KILLPG
6538/*[clinic input]
6539os.killpg
6540
6541 pgid: pid_t
6542 signal: int
6543 /
6544
6545Kill a process group with a signal.
6546[clinic start generated code]*/
6547
Larry Hastings2f936352014-08-05 14:04:04 +10006548static PyObject *
6549os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006550/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006551{
6552 /* XXX some man pages make the `pgid` parameter an int, others
6553 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6554 take the same type. Moreover, pid_t is always at least as wide as
6555 int (else compilation of this module fails), which is safe. */
6556 if (killpg(pgid, signal) == -1)
6557 return posix_error();
6558 Py_RETURN_NONE;
6559}
6560#endif /* HAVE_KILLPG */
6561
Brian Curtineb24d742010-04-12 17:16:38 +00006562
Guido van Rossumc0125471996-06-28 18:55:32 +00006563#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006564#ifdef HAVE_SYS_LOCK_H
6565#include <sys/lock.h>
6566#endif
6567
Larry Hastings2f936352014-08-05 14:04:04 +10006568/*[clinic input]
6569os.plock
6570 op: int
6571 /
6572
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006573Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006574[clinic start generated code]*/
6575
Larry Hastings2f936352014-08-05 14:04:04 +10006576static PyObject *
6577os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006578/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006579{
Victor Stinner8c62be82010-05-06 00:08:46 +00006580 if (plock(op) == -1)
6581 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006582 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006583}
Larry Hastings2f936352014-08-05 14:04:04 +10006584#endif /* HAVE_PLOCK */
6585
Guido van Rossumc0125471996-06-28 18:55:32 +00006586
Guido van Rossumb6775db1994-08-01 11:34:53 +00006587#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006588/*[clinic input]
6589os.setuid
6590
6591 uid: uid_t
6592 /
6593
6594Set the current process's user id.
6595[clinic start generated code]*/
6596
Larry Hastings2f936352014-08-05 14:04:04 +10006597static PyObject *
6598os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006599/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006600{
Victor Stinner8c62be82010-05-06 00:08:46 +00006601 if (setuid(uid) < 0)
6602 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006603 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006604}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006605#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006606
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006607
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006608#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006609/*[clinic input]
6610os.seteuid
6611
6612 euid: uid_t
6613 /
6614
6615Set the current process's effective user id.
6616[clinic start generated code]*/
6617
Larry Hastings2f936352014-08-05 14:04:04 +10006618static PyObject *
6619os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006620/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006621{
6622 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006623 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006624 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006625}
6626#endif /* HAVE_SETEUID */
6627
Larry Hastings2f936352014-08-05 14:04:04 +10006628
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006629#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006630/*[clinic input]
6631os.setegid
6632
6633 egid: gid_t
6634 /
6635
6636Set the current process's effective group id.
6637[clinic start generated code]*/
6638
Larry Hastings2f936352014-08-05 14:04:04 +10006639static PyObject *
6640os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006641/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006642{
6643 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006644 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006645 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006646}
6647#endif /* HAVE_SETEGID */
6648
Larry Hastings2f936352014-08-05 14:04:04 +10006649
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006650#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006651/*[clinic input]
6652os.setreuid
6653
6654 ruid: uid_t
6655 euid: uid_t
6656 /
6657
6658Set the current process's real and effective user ids.
6659[clinic start generated code]*/
6660
Larry Hastings2f936352014-08-05 14:04:04 +10006661static PyObject *
6662os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006663/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006664{
Victor Stinner8c62be82010-05-06 00:08:46 +00006665 if (setreuid(ruid, euid) < 0) {
6666 return posix_error();
6667 } else {
6668 Py_INCREF(Py_None);
6669 return Py_None;
6670 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006671}
6672#endif /* HAVE_SETREUID */
6673
Larry Hastings2f936352014-08-05 14:04:04 +10006674
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006675#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006676/*[clinic input]
6677os.setregid
6678
6679 rgid: gid_t
6680 egid: gid_t
6681 /
6682
6683Set the current process's real and effective group ids.
6684[clinic start generated code]*/
6685
Larry Hastings2f936352014-08-05 14:04:04 +10006686static PyObject *
6687os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006688/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006689{
6690 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006691 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006692 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006693}
6694#endif /* HAVE_SETREGID */
6695
Larry Hastings2f936352014-08-05 14:04:04 +10006696
Guido van Rossumb6775db1994-08-01 11:34:53 +00006697#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006698/*[clinic input]
6699os.setgid
6700 gid: gid_t
6701 /
6702
6703Set the current process's group id.
6704[clinic start generated code]*/
6705
Larry Hastings2f936352014-08-05 14:04:04 +10006706static PyObject *
6707os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006708/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006709{
Victor Stinner8c62be82010-05-06 00:08:46 +00006710 if (setgid(gid) < 0)
6711 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006712 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006713}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006714#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006715
Larry Hastings2f936352014-08-05 14:04:04 +10006716
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006717#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006718/*[clinic input]
6719os.setgroups
6720
6721 groups: object
6722 /
6723
6724Set the groups of the current process to list.
6725[clinic start generated code]*/
6726
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006727static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006728os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006729/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006730{
Victor Stinner8c62be82010-05-06 00:08:46 +00006731 int i, len;
6732 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006733
Victor Stinner8c62be82010-05-06 00:08:46 +00006734 if (!PySequence_Check(groups)) {
6735 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6736 return NULL;
6737 }
6738 len = PySequence_Size(groups);
6739 if (len > MAX_GROUPS) {
6740 PyErr_SetString(PyExc_ValueError, "too many groups");
6741 return NULL;
6742 }
6743 for(i = 0; i < len; i++) {
6744 PyObject *elem;
6745 elem = PySequence_GetItem(groups, i);
6746 if (!elem)
6747 return NULL;
6748 if (!PyLong_Check(elem)) {
6749 PyErr_SetString(PyExc_TypeError,
6750 "groups must be integers");
6751 Py_DECREF(elem);
6752 return NULL;
6753 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006754 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006755 Py_DECREF(elem);
6756 return NULL;
6757 }
6758 }
6759 Py_DECREF(elem);
6760 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006761
Victor Stinner8c62be82010-05-06 00:08:46 +00006762 if (setgroups(len, grouplist) < 0)
6763 return posix_error();
6764 Py_INCREF(Py_None);
6765 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006766}
6767#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006768
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006769#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6770static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006771wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006772{
Victor Stinner8c62be82010-05-06 00:08:46 +00006773 PyObject *result;
6774 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006775 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006776
Victor Stinner8c62be82010-05-06 00:08:46 +00006777 if (pid == -1)
6778 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006779
Victor Stinner8c62be82010-05-06 00:08:46 +00006780 if (struct_rusage == NULL) {
6781 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6782 if (m == NULL)
6783 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006784 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 Py_DECREF(m);
6786 if (struct_rusage == NULL)
6787 return NULL;
6788 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006789
Victor Stinner8c62be82010-05-06 00:08:46 +00006790 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6791 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6792 if (!result)
6793 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006794
6795#ifndef doubletime
6796#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6797#endif
6798
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006800 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006801 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006802 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006803#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006804 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6805 SET_INT(result, 2, ru->ru_maxrss);
6806 SET_INT(result, 3, ru->ru_ixrss);
6807 SET_INT(result, 4, ru->ru_idrss);
6808 SET_INT(result, 5, ru->ru_isrss);
6809 SET_INT(result, 6, ru->ru_minflt);
6810 SET_INT(result, 7, ru->ru_majflt);
6811 SET_INT(result, 8, ru->ru_nswap);
6812 SET_INT(result, 9, ru->ru_inblock);
6813 SET_INT(result, 10, ru->ru_oublock);
6814 SET_INT(result, 11, ru->ru_msgsnd);
6815 SET_INT(result, 12, ru->ru_msgrcv);
6816 SET_INT(result, 13, ru->ru_nsignals);
6817 SET_INT(result, 14, ru->ru_nvcsw);
6818 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006819#undef SET_INT
6820
Victor Stinner8c62be82010-05-06 00:08:46 +00006821 if (PyErr_Occurred()) {
6822 Py_DECREF(result);
6823 return NULL;
6824 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825
Victor Stinner8c62be82010-05-06 00:08:46 +00006826 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006827}
6828#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6829
Larry Hastings2f936352014-08-05 14:04:04 +10006830
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006831#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006832/*[clinic input]
6833os.wait3
6834
6835 options: int
6836Wait for completion of a child process.
6837
6838Returns a tuple of information about the child process:
6839 (pid, status, rusage)
6840[clinic start generated code]*/
6841
Larry Hastings2f936352014-08-05 14:04:04 +10006842static PyObject *
6843os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006844/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006845{
Victor Stinner8c62be82010-05-06 00:08:46 +00006846 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006848 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006849 WAIT_TYPE status;
6850 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006851
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006852 do {
6853 Py_BEGIN_ALLOW_THREADS
6854 pid = wait3(&status, options, &ru);
6855 Py_END_ALLOW_THREADS
6856 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6857 if (pid < 0)
6858 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006859
Victor Stinner4195b5c2012-02-08 23:03:19 +01006860 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006861}
6862#endif /* HAVE_WAIT3 */
6863
Larry Hastings2f936352014-08-05 14:04:04 +10006864
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006865#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006866/*[clinic input]
6867
6868os.wait4
6869
6870 pid: pid_t
6871 options: int
6872
6873Wait for completion of a specific child process.
6874
6875Returns a tuple of information about the child process:
6876 (pid, status, rusage)
6877[clinic start generated code]*/
6878
Larry Hastings2f936352014-08-05 14:04:04 +10006879static PyObject *
6880os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006881/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006882{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006883 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006885 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006886 WAIT_TYPE status;
6887 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006888
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006889 do {
6890 Py_BEGIN_ALLOW_THREADS
6891 res = wait4(pid, &status, options, &ru);
6892 Py_END_ALLOW_THREADS
6893 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6894 if (res < 0)
6895 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006897 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006898}
6899#endif /* HAVE_WAIT4 */
6900
Larry Hastings2f936352014-08-05 14:04:04 +10006901
Ross Lagerwall7807c352011-03-17 20:20:30 +02006902#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006903/*[clinic input]
6904os.waitid
6905
6906 idtype: idtype_t
6907 Must be one of be P_PID, P_PGID or P_ALL.
6908 id: id_t
6909 The id to wait on.
6910 options: int
6911 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6912 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6913 /
6914
6915Returns the result of waiting for a process or processes.
6916
6917Returns either waitid_result or None if WNOHANG is specified and there are
6918no children in a waitable state.
6919[clinic start generated code]*/
6920
Larry Hastings2f936352014-08-05 14:04:04 +10006921static PyObject *
6922os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006923/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006924{
6925 PyObject *result;
6926 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006927 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006928 siginfo_t si;
6929 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006930
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006931 do {
6932 Py_BEGIN_ALLOW_THREADS
6933 res = waitid(idtype, id, &si, options);
6934 Py_END_ALLOW_THREADS
6935 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6936 if (res < 0)
6937 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006938
6939 if (si.si_pid == 0)
6940 Py_RETURN_NONE;
6941
6942 result = PyStructSequence_New(&WaitidResultType);
6943 if (!result)
6944 return NULL;
6945
6946 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006947 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006948 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6949 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6950 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6951 if (PyErr_Occurred()) {
6952 Py_DECREF(result);
6953 return NULL;
6954 }
6955
6956 return result;
6957}
Larry Hastings2f936352014-08-05 14:04:04 +10006958#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006959
Larry Hastings2f936352014-08-05 14:04:04 +10006960
6961#if defined(HAVE_WAITPID)
6962/*[clinic input]
6963os.waitpid
6964 pid: pid_t
6965 options: int
6966 /
6967
6968Wait for completion of a given child process.
6969
6970Returns a tuple of information regarding the child process:
6971 (pid, status)
6972
6973The options argument is ignored on Windows.
6974[clinic start generated code]*/
6975
Larry Hastings2f936352014-08-05 14:04:04 +10006976static PyObject *
6977os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006978/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006979{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006980 pid_t res;
6981 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006982 WAIT_TYPE status;
6983 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006984
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006985 do {
6986 Py_BEGIN_ALLOW_THREADS
6987 res = waitpid(pid, &status, options);
6988 Py_END_ALLOW_THREADS
6989 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6990 if (res < 0)
6991 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006992
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006993 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006994}
Tim Petersab034fa2002-02-01 11:27:43 +00006995#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006996/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006997/*[clinic input]
6998os.waitpid
6999 pid: Py_intptr_t
7000 options: int
7001 /
7002
7003Wait for completion of a given process.
7004
7005Returns a tuple of information regarding the process:
7006 (pid, status << 8)
7007
7008The options argument is ignored on Windows.
7009[clinic start generated code]*/
7010
Larry Hastings2f936352014-08-05 14:04:04 +10007011static PyObject *
7012os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007013/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007014{
7015 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007016 Py_intptr_t res;
7017 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007018
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007019 do {
7020 Py_BEGIN_ALLOW_THREADS
7021 res = _cwait(&status, pid, options);
7022 Py_END_ALLOW_THREADS
7023 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007024 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007025 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007026
Victor Stinner8c62be82010-05-06 00:08:46 +00007027 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007028 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007029}
Larry Hastings2f936352014-08-05 14:04:04 +10007030#endif
7031
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007032
Guido van Rossumad0ee831995-03-01 10:34:45 +00007033#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007034/*[clinic input]
7035os.wait
7036
7037Wait for completion of a child process.
7038
7039Returns a tuple of information about the child process:
7040 (pid, status)
7041[clinic start generated code]*/
7042
Larry Hastings2f936352014-08-05 14:04:04 +10007043static PyObject *
7044os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007045/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007046{
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007048 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007049 WAIT_TYPE status;
7050 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007051
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007052 do {
7053 Py_BEGIN_ALLOW_THREADS
7054 pid = wait(&status);
7055 Py_END_ALLOW_THREADS
7056 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7057 if (pid < 0)
7058 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007059
Victor Stinner8c62be82010-05-06 00:08:46 +00007060 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007061}
Larry Hastings2f936352014-08-05 14:04:04 +10007062#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007063
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007064
Larry Hastings9cf065c2012-06-22 16:30:09 -07007065#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7066PyDoc_STRVAR(readlink__doc__,
7067"readlink(path, *, dir_fd=None) -> path\n\n\
7068Return a string representing the path to which the symbolic link points.\n\
7069\n\
7070If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7071 and path should be relative; path will then be relative to that directory.\n\
7072dir_fd may not be implemented on your platform.\n\
7073 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007074#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Guido van Rossumb6775db1994-08-01 11:34:53 +00007076#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007077
Larry Hastings2f936352014-08-05 14:04:04 +10007078/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007079static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007080posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007081{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007082 path_t path;
7083 int dir_fd = DEFAULT_DIR_FD;
7084 char buffer[MAXPATHLEN];
7085 ssize_t length;
7086 PyObject *return_value = NULL;
7087 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007088
Larry Hastings9cf065c2012-06-22 16:30:09 -07007089 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007090 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007091 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7092 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007093 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007095
Victor Stinner8c62be82010-05-06 00:08:46 +00007096 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007097#ifdef HAVE_READLINKAT
7098 if (dir_fd != DEFAULT_DIR_FD)
7099 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007100 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007101#endif
7102 length = readlink(path.narrow, buffer, sizeof(buffer));
7103 Py_END_ALLOW_THREADS
7104
7105 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007106 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007107 goto exit;
7108 }
7109
7110 if (PyUnicode_Check(path.object))
7111 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7112 else
7113 return_value = PyBytes_FromStringAndSize(buffer, length);
7114exit:
7115 path_cleanup(&path);
7116 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007117}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007118
Guido van Rossumb6775db1994-08-01 11:34:53 +00007119#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007120
Larry Hastings2f936352014-08-05 14:04:04 +10007121#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7122
7123static PyObject *
7124win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7125{
7126 wchar_t *path;
7127 DWORD n_bytes_returned;
7128 DWORD io_result;
7129 PyObject *po, *result;
7130 int dir_fd;
7131 HANDLE reparse_point_handle;
7132
7133 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7134 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7135 wchar_t *print_name;
7136
7137 static char *keywords[] = {"path", "dir_fd", NULL};
7138
7139 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7140 &po,
7141 dir_fd_unavailable, &dir_fd
7142 ))
7143 return NULL;
7144
7145 path = PyUnicode_AsUnicode(po);
7146 if (path == NULL)
7147 return NULL;
7148
7149 /* First get a handle to the reparse point */
7150 Py_BEGIN_ALLOW_THREADS
7151 reparse_point_handle = CreateFileW(
7152 path,
7153 0,
7154 0,
7155 0,
7156 OPEN_EXISTING,
7157 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7158 0);
7159 Py_END_ALLOW_THREADS
7160
7161 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7162 return win32_error_object("readlink", po);
7163
7164 Py_BEGIN_ALLOW_THREADS
7165 /* New call DeviceIoControl to read the reparse point */
7166 io_result = DeviceIoControl(
7167 reparse_point_handle,
7168 FSCTL_GET_REPARSE_POINT,
7169 0, 0, /* in buffer */
7170 target_buffer, sizeof(target_buffer),
7171 &n_bytes_returned,
7172 0 /* we're not using OVERLAPPED_IO */
7173 );
7174 CloseHandle(reparse_point_handle);
7175 Py_END_ALLOW_THREADS
7176
7177 if (io_result==0)
7178 return win32_error_object("readlink", po);
7179
7180 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7181 {
7182 PyErr_SetString(PyExc_ValueError,
7183 "not a symbolic link");
7184 return NULL;
7185 }
7186 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7187 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7188
7189 result = PyUnicode_FromWideChar(print_name,
7190 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7191 return result;
7192}
7193
7194#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7195
7196
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007197
Larry Hastings9cf065c2012-06-22 16:30:09 -07007198#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007199
7200#if defined(MS_WINDOWS)
7201
7202/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7203static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7204static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007205
Larry Hastings9cf065c2012-06-22 16:30:09 -07007206static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007207check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007208{
7209 HINSTANCE hKernel32;
7210 /* only recheck */
7211 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7212 return 1;
7213 hKernel32 = GetModuleHandleW(L"KERNEL32");
7214 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7215 "CreateSymbolicLinkW");
7216 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7217 "CreateSymbolicLinkA");
7218 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7219}
7220
Victor Stinner31b3b922013-06-05 01:49:17 +02007221/* Remove the last portion of the path */
7222static void
7223_dirnameW(WCHAR *path)
7224{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007225 WCHAR *ptr;
7226
7227 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007228 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007229 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007230 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007231 }
7232 *ptr = 0;
7233}
7234
Victor Stinner31b3b922013-06-05 01:49:17 +02007235/* Remove the last portion of the path */
7236static void
7237_dirnameA(char *path)
7238{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007239 char *ptr;
7240
7241 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007242 for(ptr = path + strlen(path); ptr != path; ptr--) {
7243 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007244 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007245 }
7246 *ptr = 0;
7247}
7248
Victor Stinner31b3b922013-06-05 01:49:17 +02007249/* Is this path absolute? */
7250static int
7251_is_absW(const WCHAR *path)
7252{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007253 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7254
7255}
7256
Victor Stinner31b3b922013-06-05 01:49:17 +02007257/* Is this path absolute? */
7258static int
7259_is_absA(const char *path)
7260{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007261 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7262
7263}
7264
Victor Stinner31b3b922013-06-05 01:49:17 +02007265/* join root and rest with a backslash */
7266static void
7267_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7268{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007269 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007270
Victor Stinner31b3b922013-06-05 01:49:17 +02007271 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007272 wcscpy(dest_path, rest);
7273 return;
7274 }
7275
7276 root_len = wcslen(root);
7277
7278 wcscpy(dest_path, root);
7279 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007280 dest_path[root_len] = L'\\';
7281 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007282 }
7283 wcscpy(dest_path+root_len, rest);
7284}
7285
Victor Stinner31b3b922013-06-05 01:49:17 +02007286/* join root and rest with a backslash */
7287static void
7288_joinA(char *dest_path, const char *root, const char *rest)
7289{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007290 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291
Victor Stinner31b3b922013-06-05 01:49:17 +02007292 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007293 strcpy(dest_path, rest);
7294 return;
7295 }
7296
7297 root_len = strlen(root);
7298
7299 strcpy(dest_path, root);
7300 if(root_len) {
7301 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007302 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007303 }
7304 strcpy(dest_path+root_len, rest);
7305}
7306
Victor Stinner31b3b922013-06-05 01:49:17 +02007307/* Return True if the path at src relative to dest is a directory */
7308static int
7309_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007310{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007311 WIN32_FILE_ATTRIBUTE_DATA src_info;
7312 WCHAR dest_parent[MAX_PATH];
7313 WCHAR src_resolved[MAX_PATH] = L"";
7314
7315 /* dest_parent = os.path.dirname(dest) */
7316 wcscpy(dest_parent, dest);
7317 _dirnameW(dest_parent);
7318 /* src_resolved = os.path.join(dest_parent, src) */
7319 _joinW(src_resolved, dest_parent, src);
7320 return (
7321 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7322 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7323 );
7324}
7325
Victor Stinner31b3b922013-06-05 01:49:17 +02007326/* Return True if the path at src relative to dest is a directory */
7327static int
7328_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007329{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007330 WIN32_FILE_ATTRIBUTE_DATA src_info;
7331 char dest_parent[MAX_PATH];
7332 char src_resolved[MAX_PATH] = "";
7333
7334 /* dest_parent = os.path.dirname(dest) */
7335 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007336 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007338 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007339 return (
7340 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7341 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7342 );
7343}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007344#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007345
Larry Hastings2f936352014-08-05 14:04:04 +10007346
7347/*[clinic input]
7348os.symlink
7349 src: path_t
7350 dst: path_t
7351 target_is_directory: bool = False
7352 *
7353 dir_fd: dir_fd(requires='symlinkat')=None
7354
7355# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7356
7357Create a symbolic link pointing to src named dst.
7358
7359target_is_directory is required on Windows if the target is to be
7360 interpreted as a directory. (On Windows, symlink requires
7361 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7362 target_is_directory is ignored on non-Windows platforms.
7363
7364If dir_fd is not None, it should be a file descriptor open to a directory,
7365 and path should be relative; path will then be relative to that directory.
7366dir_fd may not be implemented on your platform.
7367 If it is unavailable, using it will raise a NotImplementedError.
7368
7369[clinic start generated code]*/
7370
Larry Hastings2f936352014-08-05 14:04:04 +10007371static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04007372os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst,
7373 int target_is_directory, int dir_fd)
7374/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007375{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007376#ifdef MS_WINDOWS
7377 DWORD result;
7378#else
7379 int result;
7380#endif
7381
Larry Hastings9cf065c2012-06-22 16:30:09 -07007382#ifdef MS_WINDOWS
7383 if (!check_CreateSymbolicLink()) {
7384 PyErr_SetString(PyExc_NotImplementedError,
7385 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007386 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007387 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007388 if (!win32_can_symlink) {
7389 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007390 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007391 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007392#endif
7393
Larry Hastings2f936352014-08-05 14:04:04 +10007394 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007395 PyErr_SetString(PyExc_ValueError,
7396 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007397 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007398 }
7399
7400#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007401
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007403 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007404 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007405 target_is_directory |= _check_dirW(src->wide, dst->wide);
7406 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007407 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007408 }
7409 else {
7410 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007411 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7412 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007413 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007414 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007415 Py_END_ALLOW_THREADS
7416
Larry Hastings2f936352014-08-05 14:04:04 +10007417 if (!result)
7418 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007419
7420#else
7421
7422 Py_BEGIN_ALLOW_THREADS
7423#if HAVE_SYMLINKAT
7424 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007425 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007426 else
7427#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007428 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007429 Py_END_ALLOW_THREADS
7430
Larry Hastings2f936352014-08-05 14:04:04 +10007431 if (result)
7432 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007433#endif
7434
Larry Hastings2f936352014-08-05 14:04:04 +10007435 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007436}
7437#endif /* HAVE_SYMLINK */
7438
Larry Hastings9cf065c2012-06-22 16:30:09 -07007439
Brian Curtind40e6f72010-07-08 21:39:08 +00007440
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007441
Larry Hastings605a62d2012-06-24 04:33:36 -07007442static PyStructSequence_Field times_result_fields[] = {
7443 {"user", "user time"},
7444 {"system", "system time"},
7445 {"children_user", "user time of children"},
7446 {"children_system", "system time of children"},
7447 {"elapsed", "elapsed time since an arbitrary point in the past"},
7448 {NULL}
7449};
7450
7451PyDoc_STRVAR(times_result__doc__,
7452"times_result: Result from os.times().\n\n\
7453This object may be accessed either as a tuple of\n\
7454 (user, system, children_user, children_system, elapsed),\n\
7455or via the attributes user, system, children_user, children_system,\n\
7456and elapsed.\n\
7457\n\
7458See os.times for more information.");
7459
7460static PyStructSequence_Desc times_result_desc = {
7461 "times_result", /* name */
7462 times_result__doc__, /* doc */
7463 times_result_fields,
7464 5
7465};
7466
7467static PyTypeObject TimesResultType;
7468
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007469#ifdef MS_WINDOWS
7470#define HAVE_TIMES /* mandatory, for the method table */
7471#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007472
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007473#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007474
7475static PyObject *
7476build_times_result(double user, double system,
7477 double children_user, double children_system,
7478 double elapsed)
7479{
7480 PyObject *value = PyStructSequence_New(&TimesResultType);
7481 if (value == NULL)
7482 return NULL;
7483
7484#define SET(i, field) \
7485 { \
7486 PyObject *o = PyFloat_FromDouble(field); \
7487 if (!o) { \
7488 Py_DECREF(value); \
7489 return NULL; \
7490 } \
7491 PyStructSequence_SET_ITEM(value, i, o); \
7492 } \
7493
7494 SET(0, user);
7495 SET(1, system);
7496 SET(2, children_user);
7497 SET(3, children_system);
7498 SET(4, elapsed);
7499
7500#undef SET
7501
7502 return value;
7503}
7504
Larry Hastings605a62d2012-06-24 04:33:36 -07007505
Larry Hastings2f936352014-08-05 14:04:04 +10007506#ifndef MS_WINDOWS
7507#define NEED_TICKS_PER_SECOND
7508static long ticks_per_second = -1;
7509#endif /* MS_WINDOWS */
7510
7511/*[clinic input]
7512os.times
7513
7514Return a collection containing process timing information.
7515
7516The object returned behaves like a named tuple with these fields:
7517 (utime, stime, cutime, cstime, elapsed_time)
7518All fields are floating point numbers.
7519[clinic start generated code]*/
7520
Larry Hastings2f936352014-08-05 14:04:04 +10007521static PyObject *
7522os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007523/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007524#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007525{
Victor Stinner8c62be82010-05-06 00:08:46 +00007526 FILETIME create, exit, kernel, user;
7527 HANDLE hProc;
7528 hProc = GetCurrentProcess();
7529 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7530 /* The fields of a FILETIME structure are the hi and lo part
7531 of a 64-bit value expressed in 100 nanosecond units.
7532 1e7 is one second in such units; 1e-7 the inverse.
7533 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7534 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007535 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007536 (double)(user.dwHighDateTime*429.4967296 +
7537 user.dwLowDateTime*1e-7),
7538 (double)(kernel.dwHighDateTime*429.4967296 +
7539 kernel.dwLowDateTime*1e-7),
7540 (double)0,
7541 (double)0,
7542 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007543}
Larry Hastings2f936352014-08-05 14:04:04 +10007544#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007545{
Larry Hastings2f936352014-08-05 14:04:04 +10007546
7547
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007548 struct tms t;
7549 clock_t c;
7550 errno = 0;
7551 c = times(&t);
7552 if (c == (clock_t) -1)
7553 return posix_error();
7554 return build_times_result(
7555 (double)t.tms_utime / ticks_per_second,
7556 (double)t.tms_stime / ticks_per_second,
7557 (double)t.tms_cutime / ticks_per_second,
7558 (double)t.tms_cstime / ticks_per_second,
7559 (double)c / ticks_per_second);
7560}
Larry Hastings2f936352014-08-05 14:04:04 +10007561#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007562#endif /* HAVE_TIMES */
7563
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007564
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007565#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007566/*[clinic input]
7567os.getsid
7568
7569 pid: pid_t
7570 /
7571
7572Call the system call getsid(pid) and return the result.
7573[clinic start generated code]*/
7574
Larry Hastings2f936352014-08-05 14:04:04 +10007575static PyObject *
7576os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007577/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007578{
Victor Stinner8c62be82010-05-06 00:08:46 +00007579 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007580 sid = getsid(pid);
7581 if (sid < 0)
7582 return posix_error();
7583 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007584}
7585#endif /* HAVE_GETSID */
7586
7587
Guido van Rossumb6775db1994-08-01 11:34:53 +00007588#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007589/*[clinic input]
7590os.setsid
7591
7592Call the system call setsid().
7593[clinic start generated code]*/
7594
Larry Hastings2f936352014-08-05 14:04:04 +10007595static PyObject *
7596os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007597/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007598{
Victor Stinner8c62be82010-05-06 00:08:46 +00007599 if (setsid() < 0)
7600 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007601 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007602}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007603#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007604
Larry Hastings2f936352014-08-05 14:04:04 +10007605
Guido van Rossumb6775db1994-08-01 11:34:53 +00007606#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007607/*[clinic input]
7608os.setpgid
7609
7610 pid: pid_t
7611 pgrp: pid_t
7612 /
7613
7614Call the system call setpgid(pid, pgrp).
7615[clinic start generated code]*/
7616
Larry Hastings2f936352014-08-05 14:04:04 +10007617static PyObject *
7618os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007619/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007620{
Victor Stinner8c62be82010-05-06 00:08:46 +00007621 if (setpgid(pid, pgrp) < 0)
7622 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007623 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007624}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007625#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007626
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007627
Guido van Rossumb6775db1994-08-01 11:34:53 +00007628#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007629/*[clinic input]
7630os.tcgetpgrp
7631
7632 fd: int
7633 /
7634
7635Return the process group associated with the terminal specified by fd.
7636[clinic start generated code]*/
7637
Larry Hastings2f936352014-08-05 14:04:04 +10007638static PyObject *
7639os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007640/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007641{
7642 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007643 if (pgid < 0)
7644 return posix_error();
7645 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007646}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007647#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007648
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007649
Guido van Rossumb6775db1994-08-01 11:34:53 +00007650#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007651/*[clinic input]
7652os.tcsetpgrp
7653
7654 fd: int
7655 pgid: pid_t
7656 /
7657
7658Set the process group associated with the terminal specified by fd.
7659[clinic start generated code]*/
7660
Larry Hastings2f936352014-08-05 14:04:04 +10007661static PyObject *
7662os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007663/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007664{
Victor Stinner8c62be82010-05-06 00:08:46 +00007665 if (tcsetpgrp(fd, pgid) < 0)
7666 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007667 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007668}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007669#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007670
Guido van Rossum687dd131993-05-17 08:34:16 +00007671/* Functions acting on file descriptors */
7672
Victor Stinnerdaf45552013-08-28 00:53:59 +02007673#ifdef O_CLOEXEC
7674extern int _Py_open_cloexec_works;
7675#endif
7676
Larry Hastings2f936352014-08-05 14:04:04 +10007677
7678/*[clinic input]
7679os.open -> int
7680 path: path_t
7681 flags: int
7682 mode: int = 0o777
7683 *
7684 dir_fd: dir_fd(requires='openat') = None
7685
7686# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7687
7688Open a file for low level IO. Returns a file descriptor (integer).
7689
7690If dir_fd is not None, it should be a file descriptor open to a directory,
7691 and path should be relative; path will then be relative to that directory.
7692dir_fd may not be implemented on your platform.
7693 If it is unavailable, using it will raise a NotImplementedError.
7694[clinic start generated code]*/
7695
Larry Hastings2f936352014-08-05 14:04:04 +10007696static int
Larry Hastings89964c42015-04-14 18:07:59 -04007697os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode,
7698 int dir_fd)
7699/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007700{
7701 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007703
Victor Stinnerdaf45552013-08-28 00:53:59 +02007704#ifdef O_CLOEXEC
7705 int *atomic_flag_works = &_Py_open_cloexec_works;
7706#elif !defined(MS_WINDOWS)
7707 int *atomic_flag_works = NULL;
7708#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007709
Victor Stinnerdaf45552013-08-28 00:53:59 +02007710#ifdef MS_WINDOWS
7711 flags |= O_NOINHERIT;
7712#elif defined(O_CLOEXEC)
7713 flags |= O_CLOEXEC;
7714#endif
7715
Steve Dower8fc89802015-04-12 00:26:27 -04007716 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007717 do {
7718 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007719#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007720 if (path->wide)
7721 fd = _wopen(path->wide, flags, mode);
7722 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007723#endif
7724#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007725 if (dir_fd != DEFAULT_DIR_FD)
7726 fd = openat(dir_fd, path->narrow, flags, mode);
7727 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007728#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007729 fd = open(path->narrow, flags, mode);
7730 Py_END_ALLOW_THREADS
7731 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007732 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007733
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007734 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007735 if (!async_err)
7736 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007737 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007738 }
7739
Victor Stinnerdaf45552013-08-28 00:53:59 +02007740#ifndef MS_WINDOWS
7741 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7742 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007743 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007744 }
7745#endif
7746
Larry Hastings2f936352014-08-05 14:04:04 +10007747 return fd;
7748}
7749
7750
7751/*[clinic input]
7752os.close
7753
7754 fd: int
7755
7756Close a file descriptor.
7757[clinic start generated code]*/
7758
Barry Warsaw53699e91996-12-10 23:23:01 +00007759static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007760os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007761/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007762{
Larry Hastings2f936352014-08-05 14:04:04 +10007763 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007764 if (!_PyVerify_fd(fd))
7765 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007766 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7767 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7768 * for more details.
7769 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007771 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007773 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007774 Py_END_ALLOW_THREADS
7775 if (res < 0)
7776 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007777 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007778}
7779
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007780
Larry Hastings2f936352014-08-05 14:04:04 +10007781/*[clinic input]
7782os.closerange
7783
7784 fd_low: int
7785 fd_high: int
7786 /
7787
7788Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7789[clinic start generated code]*/
7790
Larry Hastings2f936352014-08-05 14:04:04 +10007791static PyObject *
7792os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007793/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007794{
7795 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007796 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007797 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007798 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007799 if (_PyVerify_fd(i))
7800 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007801 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007802 Py_END_ALLOW_THREADS
7803 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007804}
7805
7806
Larry Hastings2f936352014-08-05 14:04:04 +10007807/*[clinic input]
7808os.dup -> int
7809
7810 fd: int
7811 /
7812
7813Return a duplicate of a file descriptor.
7814[clinic start generated code]*/
7815
Larry Hastings2f936352014-08-05 14:04:04 +10007816static int
7817os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007818/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007819{
7820 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007821}
7822
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007823
Larry Hastings2f936352014-08-05 14:04:04 +10007824/*[clinic input]
7825os.dup2
7826 fd: int
7827 fd2: int
7828 inheritable: bool=True
7829
7830Duplicate file descriptor.
7831[clinic start generated code]*/
7832
Larry Hastings2f936352014-08-05 14:04:04 +10007833static PyObject *
7834os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007835/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007836{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007837 int res;
7838#if defined(HAVE_DUP3) && \
7839 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7840 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7841 int dup3_works = -1;
7842#endif
7843
Victor Stinner8c62be82010-05-06 00:08:46 +00007844 if (!_PyVerify_fd_dup2(fd, fd2))
7845 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007846
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007847 /* dup2() can fail with EINTR if the target FD is already open, because it
7848 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7849 * upon close(), and therefore below.
7850 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007851#ifdef MS_WINDOWS
7852 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007853 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007854 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007855 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007856 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007857 if (res < 0)
7858 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007859
7860 /* Character files like console cannot be make non-inheritable */
7861 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7862 close(fd2);
7863 return NULL;
7864 }
7865
7866#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7867 Py_BEGIN_ALLOW_THREADS
7868 if (!inheritable)
7869 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7870 else
7871 res = dup2(fd, fd2);
7872 Py_END_ALLOW_THREADS
7873 if (res < 0)
7874 return posix_error();
7875
7876#else
7877
7878#ifdef HAVE_DUP3
7879 if (!inheritable && dup3_works != 0) {
7880 Py_BEGIN_ALLOW_THREADS
7881 res = dup3(fd, fd2, O_CLOEXEC);
7882 Py_END_ALLOW_THREADS
7883 if (res < 0) {
7884 if (dup3_works == -1)
7885 dup3_works = (errno != ENOSYS);
7886 if (dup3_works)
7887 return posix_error();
7888 }
7889 }
7890
7891 if (inheritable || dup3_works == 0)
7892 {
7893#endif
7894 Py_BEGIN_ALLOW_THREADS
7895 res = dup2(fd, fd2);
7896 Py_END_ALLOW_THREADS
7897 if (res < 0)
7898 return posix_error();
7899
7900 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7901 close(fd2);
7902 return NULL;
7903 }
7904#ifdef HAVE_DUP3
7905 }
7906#endif
7907
7908#endif
7909
Larry Hastings2f936352014-08-05 14:04:04 +10007910 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007911}
7912
Larry Hastings2f936352014-08-05 14:04:04 +10007913
Ross Lagerwall7807c352011-03-17 20:20:30 +02007914#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007915/*[clinic input]
7916os.lockf
7917
7918 fd: int
7919 An open file descriptor.
7920 command: int
7921 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7922 length: Py_off_t
7923 The number of bytes to lock, starting at the current position.
7924 /
7925
7926Apply, test or remove a POSIX lock on an open file descriptor.
7927
7928[clinic start generated code]*/
7929
Larry Hastings2f936352014-08-05 14:04:04 +10007930static PyObject *
7931os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007932/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007933{
7934 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007935
7936 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007937 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007938 Py_END_ALLOW_THREADS
7939
7940 if (res < 0)
7941 return posix_error();
7942
7943 Py_RETURN_NONE;
7944}
Larry Hastings2f936352014-08-05 14:04:04 +10007945#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007946
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007947
Larry Hastings2f936352014-08-05 14:04:04 +10007948/*[clinic input]
7949os.lseek -> Py_off_t
7950
7951 fd: int
7952 position: Py_off_t
7953 how: int
7954 /
7955
7956Set the position of a file descriptor. Return the new position.
7957
7958Return the new cursor position in number of bytes
7959relative to the beginning of the file.
7960[clinic start generated code]*/
7961
Larry Hastings2f936352014-08-05 14:04:04 +10007962static Py_off_t
7963os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007964/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007965{
7966 Py_off_t result;
7967
7968 if (!_PyVerify_fd(fd)) {
7969 posix_error();
7970 return -1;
7971 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007972#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007973 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7974 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007975 case 0: how = SEEK_SET; break;
7976 case 1: how = SEEK_CUR; break;
7977 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007979#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007980
Victor Stinner8c62be82010-05-06 00:08:46 +00007981 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007982 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007983
Larry Hastings2f936352014-08-05 14:04:04 +10007984 if (!_PyVerify_fd(fd)) {
7985 posix_error();
7986 return -1;
7987 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007988 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007989 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007990#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007991 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007992#else
Larry Hastings2f936352014-08-05 14:04:04 +10007993 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007994#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007995 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007996 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007997 if (result < 0)
7998 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007999
Larry Hastings2f936352014-08-05 14:04:04 +10008000 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00008001}
8002
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008003
Larry Hastings2f936352014-08-05 14:04:04 +10008004/*[clinic input]
8005os.read
8006 fd: int
8007 length: Py_ssize_t
8008 /
8009
8010Read from a file descriptor. Returns a bytes object.
8011[clinic start generated code]*/
8012
Larry Hastings2f936352014-08-05 14:04:04 +10008013static PyObject *
8014os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008015/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008016{
Victor Stinner8c62be82010-05-06 00:08:46 +00008017 Py_ssize_t n;
8018 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008019
8020 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 errno = EINVAL;
8022 return posix_error();
8023 }
Larry Hastings2f936352014-08-05 14:04:04 +10008024
8025#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008026 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008027 if (length > INT_MAX)
8028 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008029#endif
8030
8031 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008032 if (buffer == NULL)
8033 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008034
Victor Stinner66aab0c2015-03-19 22:53:20 +01008035 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8036 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008038 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008039 }
Larry Hastings2f936352014-08-05 14:04:04 +10008040
8041 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008043
Victor Stinner8c62be82010-05-06 00:08:46 +00008044 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008045}
8046
Ross Lagerwall7807c352011-03-17 20:20:30 +02008047#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8048 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008049static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008050iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8051{
8052 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008053 Py_ssize_t blen, total = 0;
8054
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008055 *iov = PyMem_New(struct iovec, cnt);
8056 if (*iov == NULL) {
8057 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008058 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008060
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008061 *buf = PyMem_New(Py_buffer, cnt);
8062 if (*buf == NULL) {
8063 PyMem_Del(*iov);
8064 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008065 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008066 }
8067
8068 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008069 PyObject *item = PySequence_GetItem(seq, i);
8070 if (item == NULL)
8071 goto fail;
8072 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8073 Py_DECREF(item);
8074 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008076 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008077 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008078 blen = (*buf)[i].len;
8079 (*iov)[i].iov_len = blen;
8080 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008081 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008082 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008083
8084fail:
8085 PyMem_Del(*iov);
8086 for (j = 0; j < i; j++) {
8087 PyBuffer_Release(&(*buf)[j]);
8088 }
8089 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008090 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008091}
8092
8093static void
8094iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8095{
8096 int i;
8097 PyMem_Del(iov);
8098 for (i = 0; i < cnt; i++) {
8099 PyBuffer_Release(&buf[i]);
8100 }
8101 PyMem_Del(buf);
8102}
8103#endif
8104
Larry Hastings2f936352014-08-05 14:04:04 +10008105
Ross Lagerwall7807c352011-03-17 20:20:30 +02008106#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008107/*[clinic input]
8108os.readv -> Py_ssize_t
8109
8110 fd: int
8111 buffers: object
8112 /
8113
8114Read from a file descriptor fd into an iterable of buffers.
8115
8116The buffers should be mutable buffers accepting bytes.
8117readv will transfer data into each buffer until it is full
8118and then move on to the next buffer in the sequence to hold
8119the rest of the data.
8120
8121readv returns the total number of bytes read,
8122which may be less than the total capacity of all the buffers.
8123[clinic start generated code]*/
8124
Larry Hastings2f936352014-08-05 14:04:04 +10008125static Py_ssize_t
8126os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008127/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008128{
8129 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008130 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008131 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008132 struct iovec *iov;
8133 Py_buffer *buf;
8134
Larry Hastings2f936352014-08-05 14:04:04 +10008135 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008136 PyErr_SetString(PyExc_TypeError,
8137 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008138 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008139 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008140
Larry Hastings2f936352014-08-05 14:04:04 +10008141 cnt = PySequence_Size(buffers);
8142
8143 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8144 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008146 do {
8147 Py_BEGIN_ALLOW_THREADS
8148 n = readv(fd, iov, cnt);
8149 Py_END_ALLOW_THREADS
8150 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008151
8152 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008153 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008154 if (!async_err)
8155 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008156 return -1;
8157 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008158
Larry Hastings2f936352014-08-05 14:04:04 +10008159 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008160}
Larry Hastings2f936352014-08-05 14:04:04 +10008161#endif /* HAVE_READV */
8162
Ross Lagerwall7807c352011-03-17 20:20:30 +02008163
8164#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008165/*[clinic input]
8166# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8167os.pread
8168
8169 fd: int
8170 length: int
8171 offset: Py_off_t
8172 /
8173
8174Read a number of bytes from a file descriptor starting at a particular offset.
8175
8176Read length bytes from file descriptor fd, starting at offset bytes from
8177the beginning of the file. The file offset remains unchanged.
8178[clinic start generated code]*/
8179
Larry Hastings2f936352014-08-05 14:04:04 +10008180static PyObject *
8181os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008182/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008183{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008184 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008185 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008186 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008187
Larry Hastings2f936352014-08-05 14:04:04 +10008188 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008189 errno = EINVAL;
8190 return posix_error();
8191 }
Larry Hastings2f936352014-08-05 14:04:04 +10008192 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008193 if (buffer == NULL)
8194 return NULL;
8195 if (!_PyVerify_fd(fd)) {
8196 Py_DECREF(buffer);
8197 return posix_error();
8198 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008199
8200 do {
8201 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008202 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008203 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008204 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008205 Py_END_ALLOW_THREADS
8206 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8207
Ross Lagerwall7807c352011-03-17 20:20:30 +02008208 if (n < 0) {
8209 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008210 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008211 }
Larry Hastings2f936352014-08-05 14:04:04 +10008212 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008213 _PyBytes_Resize(&buffer, n);
8214 return buffer;
8215}
Larry Hastings2f936352014-08-05 14:04:04 +10008216#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008217
Larry Hastings2f936352014-08-05 14:04:04 +10008218
8219/*[clinic input]
8220os.write -> Py_ssize_t
8221
8222 fd: int
8223 data: Py_buffer
8224 /
8225
8226Write a bytes object to a file descriptor.
8227[clinic start generated code]*/
8228
Larry Hastings2f936352014-08-05 14:04:04 +10008229static Py_ssize_t
8230os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008231/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008232{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008233 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008234}
8235
8236#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008237PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008238"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008239sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008240 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008241Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242
Larry Hastings2f936352014-08-05 14:04:04 +10008243/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008244static PyObject *
8245posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8246{
8247 int in, out;
8248 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008249 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008250 off_t offset;
8251
8252#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8253#ifndef __APPLE__
8254 Py_ssize_t len;
8255#endif
8256 PyObject *headers = NULL, *trailers = NULL;
8257 Py_buffer *hbuf, *tbuf;
8258 off_t sbytes;
8259 struct sf_hdtr sf;
8260 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008261 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008262 static char *keywords[] = {"out", "in",
8263 "offset", "count",
8264 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008265
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008266 sf.headers = NULL;
8267 sf.trailers = NULL;
8268
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008269#ifdef __APPLE__
8270 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008271 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008272#else
8273 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008274 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008275#endif
8276 &headers, &trailers, &flags))
8277 return NULL;
8278 if (headers != NULL) {
8279 if (!PySequence_Check(headers)) {
8280 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008281 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008282 return NULL;
8283 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008284 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008285 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008286 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008287 (i = iov_setup(&(sf.headers), &hbuf,
8288 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008289 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008290#ifdef __APPLE__
8291 sbytes += i;
8292#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008293 }
8294 }
8295 if (trailers != NULL) {
8296 if (!PySequence_Check(trailers)) {
8297 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008298 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008299 return NULL;
8300 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008301 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008302 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008303 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008304 (i = iov_setup(&(sf.trailers), &tbuf,
8305 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008306 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008307#ifdef __APPLE__
8308 sbytes += i;
8309#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008310 }
8311 }
8312
Steve Dower8fc89802015-04-12 00:26:27 -04008313 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008314 do {
8315 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008317 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008320#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008321 Py_END_ALLOW_THREADS
8322 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008323 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008324
8325 if (sf.headers != NULL)
8326 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8327 if (sf.trailers != NULL)
8328 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8329
8330 if (ret < 0) {
8331 if ((errno == EAGAIN) || (errno == EBUSY)) {
8332 if (sbytes != 0) {
8333 // some data has been sent
8334 goto done;
8335 }
8336 else {
8337 // no data has been sent; upper application is supposed
8338 // to retry on EAGAIN or EBUSY
8339 return posix_error();
8340 }
8341 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008342 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008343 }
8344 goto done;
8345
8346done:
8347 #if !defined(HAVE_LARGEFILE_SUPPORT)
8348 return Py_BuildValue("l", sbytes);
8349 #else
8350 return Py_BuildValue("L", sbytes);
8351 #endif
8352
8353#else
8354 Py_ssize_t count;
8355 PyObject *offobj;
8356 static char *keywords[] = {"out", "in",
8357 "offset", "count", NULL};
8358 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8359 keywords, &out, &in, &offobj, &count))
8360 return NULL;
8361#ifdef linux
8362 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008363 do {
8364 Py_BEGIN_ALLOW_THREADS
8365 ret = sendfile(out, in, NULL, count);
8366 Py_END_ALLOW_THREADS
8367 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008368 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008369 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008370 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008371 }
8372#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008373 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008374 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008375
8376 do {
8377 Py_BEGIN_ALLOW_THREADS
8378 ret = sendfile(out, in, &offset, count);
8379 Py_END_ALLOW_THREADS
8380 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008381 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008382 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008383 return Py_BuildValue("n", ret);
8384#endif
8385}
Larry Hastings2f936352014-08-05 14:04:04 +10008386#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008387
Larry Hastings2f936352014-08-05 14:04:04 +10008388
8389/*[clinic input]
8390os.fstat
8391
8392 fd : int
8393
8394Perform a stat system call on the given file descriptor.
8395
8396Like stat(), but for an open file descriptor.
8397Equivalent to os.stat(fd).
8398[clinic start generated code]*/
8399
Larry Hastings2f936352014-08-05 14:04:04 +10008400static PyObject *
8401os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008402/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008403{
Victor Stinner8c62be82010-05-06 00:08:46 +00008404 STRUCT_STAT st;
8405 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008406 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008407
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008408 do {
8409 Py_BEGIN_ALLOW_THREADS
8410 res = FSTAT(fd, &st);
8411 Py_END_ALLOW_THREADS
8412 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008413 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008414#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008415 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008416#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008417 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008418#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008419 }
Tim Peters5aa91602002-01-30 05:46:57 +00008420
Victor Stinner4195b5c2012-02-08 23:03:19 +01008421 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008422}
8423
Larry Hastings2f936352014-08-05 14:04:04 +10008424
8425/*[clinic input]
8426os.isatty -> bool
8427 fd: int
8428 /
8429
8430Return True if the fd is connected to a terminal.
8431
8432Return True if the file descriptor is an open file descriptor
8433connected to the slave end of a terminal.
8434[clinic start generated code]*/
8435
Larry Hastings2f936352014-08-05 14:04:04 +10008436static int
8437os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008438/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008439{
Steve Dower8fc89802015-04-12 00:26:27 -04008440 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008441 if (!_PyVerify_fd(fd))
8442 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008443 _Py_BEGIN_SUPPRESS_IPH
8444 return_value = isatty(fd);
8445 _Py_END_SUPPRESS_IPH
8446 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008447}
8448
8449
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008450#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008451/*[clinic input]
8452os.pipe
8453
8454Create a pipe.
8455
8456Returns a tuple of two file descriptors:
8457 (read_fd, write_fd)
8458[clinic start generated code]*/
8459
Larry Hastings2f936352014-08-05 14:04:04 +10008460static PyObject *
8461os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008462/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008463{
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008465#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008467 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008468 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008469#else
8470 int res;
8471#endif
8472
8473#ifdef MS_WINDOWS
8474 attr.nLength = sizeof(attr);
8475 attr.lpSecurityDescriptor = NULL;
8476 attr.bInheritHandle = FALSE;
8477
8478 Py_BEGIN_ALLOW_THREADS
8479 ok = CreatePipe(&read, &write, &attr, 0);
8480 if (ok) {
8481 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8482 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8483 if (fds[0] == -1 || fds[1] == -1) {
8484 CloseHandle(read);
8485 CloseHandle(write);
8486 ok = 0;
8487 }
8488 }
8489 Py_END_ALLOW_THREADS
8490
Victor Stinner8c62be82010-05-06 00:08:46 +00008491 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008492 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008493#else
8494
8495#ifdef HAVE_PIPE2
8496 Py_BEGIN_ALLOW_THREADS
8497 res = pipe2(fds, O_CLOEXEC);
8498 Py_END_ALLOW_THREADS
8499
8500 if (res != 0 && errno == ENOSYS)
8501 {
8502#endif
8503 Py_BEGIN_ALLOW_THREADS
8504 res = pipe(fds);
8505 Py_END_ALLOW_THREADS
8506
8507 if (res == 0) {
8508 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8509 close(fds[0]);
8510 close(fds[1]);
8511 return NULL;
8512 }
8513 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8514 close(fds[0]);
8515 close(fds[1]);
8516 return NULL;
8517 }
8518 }
8519#ifdef HAVE_PIPE2
8520 }
8521#endif
8522
8523 if (res != 0)
8524 return PyErr_SetFromErrno(PyExc_OSError);
8525#endif /* !MS_WINDOWS */
8526 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008527}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008528#endif /* HAVE_PIPE */
8529
Larry Hastings2f936352014-08-05 14:04:04 +10008530
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008531#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008532/*[clinic input]
8533os.pipe2
8534
8535 flags: int
8536 /
8537
8538Create a pipe with flags set atomically.
8539
8540Returns a tuple of two file descriptors:
8541 (read_fd, write_fd)
8542
8543flags can be constructed by ORing together one or more of these values:
8544O_NONBLOCK, O_CLOEXEC.
8545[clinic start generated code]*/
8546
Larry Hastings2f936352014-08-05 14:04:04 +10008547static PyObject *
8548os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008549/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008550{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008551 int fds[2];
8552 int res;
8553
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008554 res = pipe2(fds, flags);
8555 if (res != 0)
8556 return posix_error();
8557 return Py_BuildValue("(ii)", fds[0], fds[1]);
8558}
8559#endif /* HAVE_PIPE2 */
8560
Larry Hastings2f936352014-08-05 14:04:04 +10008561
Ross Lagerwall7807c352011-03-17 20:20:30 +02008562#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008563/*[clinic input]
8564os.writev -> Py_ssize_t
8565 fd: int
8566 buffers: object
8567 /
8568
8569Iterate over buffers, and write the contents of each to a file descriptor.
8570
8571Returns the total number of bytes written.
8572buffers must be a sequence of bytes-like objects.
8573[clinic start generated code]*/
8574
Larry Hastings2f936352014-08-05 14:04:04 +10008575static Py_ssize_t
8576os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008577/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008578{
8579 int cnt;
8580 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008581 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008582 struct iovec *iov;
8583 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008584
8585 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008586 PyErr_SetString(PyExc_TypeError,
8587 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008588 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008589 }
Larry Hastings2f936352014-08-05 14:04:04 +10008590 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008591
Larry Hastings2f936352014-08-05 14:04:04 +10008592 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8593 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008594 }
8595
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008596 do {
8597 Py_BEGIN_ALLOW_THREADS
8598 result = writev(fd, iov, cnt);
8599 Py_END_ALLOW_THREADS
8600 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008601
8602 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008603 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008604 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008605
Georg Brandl306336b2012-06-24 12:55:33 +02008606 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008607}
Larry Hastings2f936352014-08-05 14:04:04 +10008608#endif /* HAVE_WRITEV */
8609
8610
8611#ifdef HAVE_PWRITE
8612/*[clinic input]
8613os.pwrite -> Py_ssize_t
8614
8615 fd: int
8616 buffer: Py_buffer
8617 offset: Py_off_t
8618 /
8619
8620Write bytes to a file descriptor starting at a particular offset.
8621
8622Write buffer to fd, starting at offset bytes from the beginning of
8623the file. Returns the number of bytes writte. Does not change the
8624current file offset.
8625[clinic start generated code]*/
8626
Larry Hastings2f936352014-08-05 14:04:04 +10008627static Py_ssize_t
Larry Hastings89964c42015-04-14 18:07:59 -04008628os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
8629 Py_off_t offset)
8630/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008631{
8632 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008633 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008634
8635 if (!_PyVerify_fd(fd)) {
8636 posix_error();
8637 return -1;
8638 }
8639
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008640 do {
8641 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008642 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008643 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008644 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008645 Py_END_ALLOW_THREADS
8646 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008647
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008648 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008649 posix_error();
8650 return size;
8651}
8652#endif /* HAVE_PWRITE */
8653
8654
8655#ifdef HAVE_MKFIFO
8656/*[clinic input]
8657os.mkfifo
8658
8659 path: path_t
8660 mode: int=0o666
8661 *
8662 dir_fd: dir_fd(requires='mkfifoat')=None
8663
8664Create a "fifo" (a POSIX named pipe).
8665
8666If dir_fd is not None, it should be a file descriptor open to a directory,
8667 and path should be relative; path will then be relative to that directory.
8668dir_fd may not be implemented on your platform.
8669 If it is unavailable, using it will raise a NotImplementedError.
8670[clinic start generated code]*/
8671
Larry Hastings2f936352014-08-05 14:04:04 +10008672static PyObject *
8673os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008674/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008675{
8676 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008677 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008678
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008679 do {
8680 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008681#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008682 if (dir_fd != DEFAULT_DIR_FD)
8683 result = mkfifoat(dir_fd, path->narrow, mode);
8684 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008685#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008686 result = mkfifo(path->narrow, mode);
8687 Py_END_ALLOW_THREADS
8688 } while (result != 0 && errno == EINTR &&
8689 !(async_err = PyErr_CheckSignals()));
8690 if (result != 0)
8691 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008692
8693 Py_RETURN_NONE;
8694}
8695#endif /* HAVE_MKFIFO */
8696
8697
8698#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8699/*[clinic input]
8700os.mknod
8701
8702 path: path_t
8703 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008704 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008705 *
8706 dir_fd: dir_fd(requires='mknodat')=None
8707
8708Create a node in the file system.
8709
8710Create a node in the file system (file, device special file or named pipe)
8711at path. mode specifies both the permissions to use and the
8712type of node to be created, being combined (bitwise OR) with one of
8713S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8714device defines the newly created device special file (probably using
8715os.makedev()). Otherwise device is ignored.
8716
8717If dir_fd is not None, it should be a file descriptor open to a directory,
8718 and path should be relative; path will then be relative to that directory.
8719dir_fd may not be implemented on your platform.
8720 If it is unavailable, using it will raise a NotImplementedError.
8721[clinic start generated code]*/
8722
Larry Hastings2f936352014-08-05 14:04:04 +10008723static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008724os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
8725 int dir_fd)
8726/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008727{
8728 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008729 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008730
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008731 do {
8732 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008733#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008734 if (dir_fd != DEFAULT_DIR_FD)
8735 result = mknodat(dir_fd, path->narrow, mode, device);
8736 else
Larry Hastings2f936352014-08-05 14:04:04 +10008737#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008738 result = mknod(path->narrow, mode, device);
8739 Py_END_ALLOW_THREADS
8740 } while (result != 0 && errno == EINTR &&
8741 !(async_err = PyErr_CheckSignals()));
8742 if (result != 0)
8743 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008744
8745 Py_RETURN_NONE;
8746}
8747#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8748
8749
8750#ifdef HAVE_DEVICE_MACROS
8751/*[clinic input]
8752os.major -> unsigned_int
8753
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008754 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008755 /
8756
8757Extracts a device major number from a raw device number.
8758[clinic start generated code]*/
8759
Larry Hastings2f936352014-08-05 14:04:04 +10008760static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008761os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008762/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008763{
8764 return major(device);
8765}
8766
8767
8768/*[clinic input]
8769os.minor -> unsigned_int
8770
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008771 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008772 /
8773
8774Extracts a device minor number from a raw device number.
8775[clinic start generated code]*/
8776
Larry Hastings2f936352014-08-05 14:04:04 +10008777static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008778os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008779/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008780{
8781 return minor(device);
8782}
8783
8784
8785/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008786os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008787
8788 major: int
8789 minor: int
8790 /
8791
8792Composes a raw device number from the major and minor device numbers.
8793[clinic start generated code]*/
8794
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008795static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008796os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008797/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008798{
8799 return makedev(major, minor);
8800}
8801#endif /* HAVE_DEVICE_MACROS */
8802
8803
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008804#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008805/*[clinic input]
8806os.ftruncate
8807
8808 fd: int
8809 length: Py_off_t
8810 /
8811
8812Truncate a file, specified by file descriptor, to a specific length.
8813[clinic start generated code]*/
8814
Larry Hastings2f936352014-08-05 14:04:04 +10008815static PyObject *
8816os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008817/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008818{
8819 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008820 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008821
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008822 if (!_PyVerify_fd(fd))
8823 return posix_error();
8824
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008825 do {
8826 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008827 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008828#ifdef MS_WINDOWS
8829 result = _chsize_s(fd, length);
8830#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008831 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008832#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008833 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008834 Py_END_ALLOW_THREADS
8835 } while (result != 0 && errno == EINTR &&
8836 !(async_err = PyErr_CheckSignals()));
8837 if (result != 0)
8838 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008839 Py_RETURN_NONE;
8840}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008841#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008842
8843
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008844#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008845/*[clinic input]
8846os.truncate
8847 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8848 length: Py_off_t
8849
8850Truncate a file, specified by path, to a specific length.
8851
8852On some platforms, path may also be specified as an open file descriptor.
8853 If this functionality is unavailable, using it raises an exception.
8854[clinic start generated code]*/
8855
Larry Hastings2f936352014-08-05 14:04:04 +10008856static PyObject *
8857os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008858/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008859{
8860 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008861#ifdef MS_WINDOWS
8862 int fd;
8863#endif
8864
8865 if (path->fd != -1)
8866 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008867
8868 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008869 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008870#ifdef MS_WINDOWS
8871 if (path->wide)
8872 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008873 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008874 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008875 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008876 result = -1;
8877 else {
8878 result = _chsize_s(fd, length);
8879 close(fd);
8880 if (result < 0)
8881 errno = result;
8882 }
8883#else
8884 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008885#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008886 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008887 Py_END_ALLOW_THREADS
8888 if (result < 0)
8889 return path_error(path);
8890
8891 Py_RETURN_NONE;
8892}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008893#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008894
Ross Lagerwall7807c352011-03-17 20:20:30 +02008895
Victor Stinnerd6b17692014-09-30 12:20:05 +02008896/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8897 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8898 defined, which is the case in Python on AIX. AIX bug report:
8899 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8900#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8901# define POSIX_FADVISE_AIX_BUG
8902#endif
8903
Victor Stinnerec39e262014-09-30 12:35:58 +02008904
Victor Stinnerd6b17692014-09-30 12:20:05 +02008905#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008906/*[clinic input]
8907os.posix_fallocate
8908
8909 fd: int
8910 offset: Py_off_t
8911 length: Py_off_t
8912 /
8913
8914Ensure a file has allocated at least a particular number of bytes on disk.
8915
8916Ensure that the file specified by fd encompasses a range of bytes
8917starting at offset bytes from the beginning and continuing for length bytes.
8918[clinic start generated code]*/
8919
Larry Hastings2f936352014-08-05 14:04:04 +10008920static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008921os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset,
8922 Py_off_t length)
8923/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008924{
8925 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008926 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008927
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008928 do {
8929 Py_BEGIN_ALLOW_THREADS
8930 result = posix_fallocate(fd, offset, length);
8931 Py_END_ALLOW_THREADS
8932 } while (result != 0 && errno == EINTR &&
8933 !(async_err = PyErr_CheckSignals()));
8934 if (result != 0)
8935 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008936 Py_RETURN_NONE;
8937}
Victor Stinnerec39e262014-09-30 12:35:58 +02008938#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008939
Ross Lagerwall7807c352011-03-17 20:20:30 +02008940
Victor Stinnerd6b17692014-09-30 12:20:05 +02008941#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008942/*[clinic input]
8943os.posix_fadvise
8944
8945 fd: int
8946 offset: Py_off_t
8947 length: Py_off_t
8948 advice: int
8949 /
8950
8951Announce an intention to access data in a specific pattern.
8952
8953Announce an intention to access data in a specific pattern, thus allowing
8954the kernel to make optimizations.
8955The advice applies to the region of the file specified by fd starting at
8956offset and continuing for length bytes.
8957advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8958POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8959POSIX_FADV_DONTNEED.
8960[clinic start generated code]*/
8961
Larry Hastings2f936352014-08-05 14:04:04 +10008962static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008963os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset,
8964 Py_off_t length, int advice)
8965/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008966{
8967 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008968 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008969
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008970 do {
8971 Py_BEGIN_ALLOW_THREADS
8972 result = posix_fadvise(fd, offset, length, advice);
8973 Py_END_ALLOW_THREADS
8974 } while (result != 0 && errno == EINTR &&
8975 !(async_err = PyErr_CheckSignals()));
8976 if (result != 0)
8977 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008978 Py_RETURN_NONE;
8979}
Victor Stinnerec39e262014-09-30 12:35:58 +02008980#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008981
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008982#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008983
Fred Drake762e2061999-08-26 17:23:54 +00008984/* Save putenv() parameters as values here, so we can collect them when they
8985 * get re-set with another call for the same key. */
8986static PyObject *posix_putenv_garbage;
8987
Larry Hastings2f936352014-08-05 14:04:04 +10008988static void
8989posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008990{
Larry Hastings2f936352014-08-05 14:04:04 +10008991 /* Install the first arg and newstr in posix_putenv_garbage;
8992 * this will cause previous value to be collected. This has to
8993 * happen after the real putenv() call because the old value
8994 * was still accessible until then. */
8995 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8996 /* really not much we can do; just leak */
8997 PyErr_Clear();
8998 else
8999 Py_DECREF(value);
9000}
9001
9002
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009003#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009004/*[clinic input]
9005os.putenv
9006
9007 name: unicode
9008 value: unicode
9009 /
9010
9011Change or add an environment variable.
9012[clinic start generated code]*/
9013
Larry Hastings2f936352014-08-05 14:04:04 +10009014static PyObject *
9015os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009016/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009017{
9018 wchar_t *env;
9019
9020 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9021 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009022 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009023 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009024 }
Larry Hastings2f936352014-08-05 14:04:04 +10009025 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009026 PyErr_Format(PyExc_ValueError,
9027 "the environment variable is longer than %u characters",
9028 _MAX_ENV);
9029 goto error;
9030 }
9031
Larry Hastings2f936352014-08-05 14:04:04 +10009032 env = PyUnicode_AsUnicode(unicode);
9033 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009034 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009035 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009037 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009038 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009039
Larry Hastings2f936352014-08-05 14:04:04 +10009040 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009041 Py_RETURN_NONE;
9042
9043error:
Larry Hastings2f936352014-08-05 14:04:04 +10009044 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009045 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009046}
Larry Hastings2f936352014-08-05 14:04:04 +10009047#else /* MS_WINDOWS */
9048/*[clinic input]
9049os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009050
Larry Hastings2f936352014-08-05 14:04:04 +10009051 name: FSConverter
9052 value: FSConverter
9053 /
9054
9055Change or add an environment variable.
9056[clinic start generated code]*/
9057
Larry Hastings2f936352014-08-05 14:04:04 +10009058static PyObject *
9059os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009060/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009061{
9062 PyObject *bytes = NULL;
9063 char *env;
9064 char *name_string = PyBytes_AsString(name);
9065 char *value_string = PyBytes_AsString(value);
9066
9067 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9068 if (bytes == NULL) {
9069 PyErr_NoMemory();
9070 return NULL;
9071 }
9072
9073 env = PyBytes_AS_STRING(bytes);
9074 if (putenv(env)) {
9075 Py_DECREF(bytes);
9076 return posix_error();
9077 }
9078
9079 posix_putenv_garbage_setitem(name, bytes);
9080 Py_RETURN_NONE;
9081}
9082#endif /* MS_WINDOWS */
9083#endif /* HAVE_PUTENV */
9084
9085
9086#ifdef HAVE_UNSETENV
9087/*[clinic input]
9088os.unsetenv
9089 name: FSConverter
9090 /
9091
9092Delete an environment variable.
9093[clinic start generated code]*/
9094
Larry Hastings2f936352014-08-05 14:04:04 +10009095static PyObject *
9096os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009097/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009098{
Victor Stinner984890f2011-11-24 13:53:38 +01009099#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009100 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009101#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009102
Victor Stinner984890f2011-11-24 13:53:38 +01009103#ifdef HAVE_BROKEN_UNSETENV
9104 unsetenv(PyBytes_AS_STRING(name));
9105#else
Victor Stinner65170952011-11-22 22:16:17 +01009106 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009107 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009108 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009109#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009110
Victor Stinner8c62be82010-05-06 00:08:46 +00009111 /* Remove the key from posix_putenv_garbage;
9112 * this will cause it to be collected. This has to
9113 * happen after the real unsetenv() call because the
9114 * old value was still accessible until then.
9115 */
Victor Stinner65170952011-11-22 22:16:17 +01009116 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009117 /* really not much we can do; just leak */
9118 PyErr_Clear();
9119 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009120 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009121}
Larry Hastings2f936352014-08-05 14:04:04 +10009122#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009123
Larry Hastings2f936352014-08-05 14:04:04 +10009124
9125/*[clinic input]
9126os.strerror
9127
9128 code: int
9129 /
9130
9131Translate an error code to a message string.
9132[clinic start generated code]*/
9133
Larry Hastings2f936352014-08-05 14:04:04 +10009134static PyObject *
9135os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009136/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009137{
9138 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009139 if (message == NULL) {
9140 PyErr_SetString(PyExc_ValueError,
9141 "strerror() argument out of range");
9142 return NULL;
9143 }
Victor Stinner1b579672011-12-17 05:47:23 +01009144 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009145}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009146
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009147
Guido van Rossumc9641791998-08-04 15:26:23 +00009148#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009149#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009150/*[clinic input]
9151os.WCOREDUMP -> bool
9152
9153 status: int
9154 /
9155
9156Return True if the process returning status was dumped to a core file.
9157[clinic start generated code]*/
9158
Larry Hastings2f936352014-08-05 14:04:04 +10009159static int
9160os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009161/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009162{
9163 WAIT_TYPE wait_status;
9164 WAIT_STATUS_INT(wait_status) = status;
9165 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009166}
9167#endif /* WCOREDUMP */
9168
Larry Hastings2f936352014-08-05 14:04:04 +10009169
Fred Drake106c1a02002-04-23 15:58:02 +00009170#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009171/*[clinic input]
9172os.WIFCONTINUED -> bool
9173
9174 status: int
9175
9176Return True if a particular process was continued from a job control stop.
9177
9178Return True if the process returning status was continued from a
9179job control stop.
9180[clinic start generated code]*/
9181
Larry Hastings2f936352014-08-05 14:04:04 +10009182static int
9183os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009184/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009185{
9186 WAIT_TYPE wait_status;
9187 WAIT_STATUS_INT(wait_status) = status;
9188 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009189}
9190#endif /* WIFCONTINUED */
9191
Larry Hastings2f936352014-08-05 14:04:04 +10009192
Guido van Rossumc9641791998-08-04 15:26:23 +00009193#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009194/*[clinic input]
9195os.WIFSTOPPED -> bool
9196
9197 status: int
9198
9199Return True if the process returning status was stopped.
9200[clinic start generated code]*/
9201
Larry Hastings2f936352014-08-05 14:04:04 +10009202static int
9203os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009204/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009205{
9206 WAIT_TYPE wait_status;
9207 WAIT_STATUS_INT(wait_status) = status;
9208 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009209}
9210#endif /* WIFSTOPPED */
9211
Larry Hastings2f936352014-08-05 14:04:04 +10009212
Guido van Rossumc9641791998-08-04 15:26:23 +00009213#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009214/*[clinic input]
9215os.WIFSIGNALED -> bool
9216
9217 status: int
9218
9219Return True if the process returning status was terminated by a signal.
9220[clinic start generated code]*/
9221
Larry Hastings2f936352014-08-05 14:04:04 +10009222static int
9223os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009224/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009225{
9226 WAIT_TYPE wait_status;
9227 WAIT_STATUS_INT(wait_status) = status;
9228 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009229}
9230#endif /* WIFSIGNALED */
9231
Larry Hastings2f936352014-08-05 14:04:04 +10009232
Guido van Rossumc9641791998-08-04 15:26:23 +00009233#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009234/*[clinic input]
9235os.WIFEXITED -> bool
9236
9237 status: int
9238
9239Return True if the process returning status exited via the exit() system call.
9240[clinic start generated code]*/
9241
Larry Hastings2f936352014-08-05 14:04:04 +10009242static int
9243os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009244/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009245{
9246 WAIT_TYPE wait_status;
9247 WAIT_STATUS_INT(wait_status) = status;
9248 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009249}
9250#endif /* WIFEXITED */
9251
Larry Hastings2f936352014-08-05 14:04:04 +10009252
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009253#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009254/*[clinic input]
9255os.WEXITSTATUS -> int
9256
9257 status: int
9258
9259Return the process return code from status.
9260[clinic start generated code]*/
9261
Larry Hastings2f936352014-08-05 14:04:04 +10009262static int
9263os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009264/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009265{
9266 WAIT_TYPE wait_status;
9267 WAIT_STATUS_INT(wait_status) = status;
9268 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009269}
9270#endif /* WEXITSTATUS */
9271
Larry Hastings2f936352014-08-05 14:04:04 +10009272
Guido van Rossumc9641791998-08-04 15:26:23 +00009273#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009274/*[clinic input]
9275os.WTERMSIG -> int
9276
9277 status: int
9278
9279Return the signal that terminated the process that provided the status value.
9280[clinic start generated code]*/
9281
Larry Hastings2f936352014-08-05 14:04:04 +10009282static int
9283os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009284/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009285{
9286 WAIT_TYPE wait_status;
9287 WAIT_STATUS_INT(wait_status) = status;
9288 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009289}
9290#endif /* WTERMSIG */
9291
Larry Hastings2f936352014-08-05 14:04:04 +10009292
Guido van Rossumc9641791998-08-04 15:26:23 +00009293#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009294/*[clinic input]
9295os.WSTOPSIG -> int
9296
9297 status: int
9298
9299Return the signal that stopped the process that provided the status value.
9300[clinic start generated code]*/
9301
Larry Hastings2f936352014-08-05 14:04:04 +10009302static int
9303os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009304/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009305{
9306 WAIT_TYPE wait_status;
9307 WAIT_STATUS_INT(wait_status) = status;
9308 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009309}
9310#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009311#endif /* HAVE_SYS_WAIT_H */
9312
9313
Thomas Wouters477c8d52006-05-27 19:21:47 +00009314#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009315#ifdef _SCO_DS
9316/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9317 needed definitions in sys/statvfs.h */
9318#define _SVID3
9319#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009320#include <sys/statvfs.h>
9321
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009322static PyObject*
9323_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009324 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9325 if (v == NULL)
9326 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009327
9328#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009329 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9330 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9331 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9332 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9333 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9334 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9335 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9336 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9337 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9338 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009339#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009340 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9341 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9342 PyStructSequence_SET_ITEM(v, 2,
9343 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9344 PyStructSequence_SET_ITEM(v, 3,
9345 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9346 PyStructSequence_SET_ITEM(v, 4,
9347 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9348 PyStructSequence_SET_ITEM(v, 5,
9349 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9350 PyStructSequence_SET_ITEM(v, 6,
9351 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9352 PyStructSequence_SET_ITEM(v, 7,
9353 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9354 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9355 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009356#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009357 if (PyErr_Occurred()) {
9358 Py_DECREF(v);
9359 return NULL;
9360 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009361
Victor Stinner8c62be82010-05-06 00:08:46 +00009362 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009363}
9364
Larry Hastings2f936352014-08-05 14:04:04 +10009365
9366/*[clinic input]
9367os.fstatvfs
9368 fd: int
9369 /
9370
9371Perform an fstatvfs system call on the given fd.
9372
9373Equivalent to statvfs(fd).
9374[clinic start generated code]*/
9375
Larry Hastings2f936352014-08-05 14:04:04 +10009376static PyObject *
9377os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009378/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009379{
9380 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009381 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009382 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009383
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009384 do {
9385 Py_BEGIN_ALLOW_THREADS
9386 result = fstatvfs(fd, &st);
9387 Py_END_ALLOW_THREADS
9388 } while (result != 0 && errno == EINTR &&
9389 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009390 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009391 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009392
Victor Stinner8c62be82010-05-06 00:08:46 +00009393 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009394}
Larry Hastings2f936352014-08-05 14:04:04 +10009395#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009396
9397
Thomas Wouters477c8d52006-05-27 19:21:47 +00009398#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009399#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009400/*[clinic input]
9401os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009402
Larry Hastings2f936352014-08-05 14:04:04 +10009403 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9404
9405Perform a statvfs system call on the given path.
9406
9407path may always be specified as a string.
9408On some platforms, path may also be specified as an open file descriptor.
9409 If this functionality is unavailable, using it raises an exception.
9410[clinic start generated code]*/
9411
Larry Hastings2f936352014-08-05 14:04:04 +10009412static PyObject *
9413os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009414/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009415{
9416 int result;
9417 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009418
9419 Py_BEGIN_ALLOW_THREADS
9420#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009421 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009422#ifdef __APPLE__
9423 /* handle weak-linking on Mac OS X 10.3 */
9424 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009425 fd_specified("statvfs", path->fd);
9426 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009427 }
9428#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009429 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009430 }
9431 else
9432#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009433 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009434 Py_END_ALLOW_THREADS
9435
9436 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009437 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009438 }
9439
Larry Hastings2f936352014-08-05 14:04:04 +10009440 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009441}
Larry Hastings2f936352014-08-05 14:04:04 +10009442#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9443
Guido van Rossum94f6f721999-01-06 18:42:14 +00009444
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009445#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009446/*[clinic input]
9447os._getdiskusage
9448
9449 path: Py_UNICODE
9450
9451Return disk usage statistics about the given path as a (total, free) tuple.
9452[clinic start generated code]*/
9453
Larry Hastings2f936352014-08-05 14:04:04 +10009454static PyObject *
9455os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009456/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009457{
9458 BOOL retval;
9459 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009460
9461 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009462 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009463 Py_END_ALLOW_THREADS
9464 if (retval == 0)
9465 return PyErr_SetFromWindowsErr(0);
9466
9467 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9468}
Larry Hastings2f936352014-08-05 14:04:04 +10009469#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009470
9471
Fred Drakec9680921999-12-13 16:37:25 +00009472/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9473 * It maps strings representing configuration variable names to
9474 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009475 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009476 * rarely-used constants. There are three separate tables that use
9477 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009478 *
9479 * This code is always included, even if none of the interfaces that
9480 * need it are included. The #if hackery needed to avoid it would be
9481 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009482 */
9483struct constdef {
9484 char *name;
9485 long value;
9486};
9487
Fred Drake12c6e2d1999-12-14 21:25:03 +00009488static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009489conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009490 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009491{
Christian Heimes217cfd12007-12-02 14:31:20 +00009492 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009493 *valuep = PyLong_AS_LONG(arg);
9494 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009495 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009496 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009497 /* look up the value in the table using a binary search */
9498 size_t lo = 0;
9499 size_t mid;
9500 size_t hi = tablesize;
9501 int cmp;
9502 const char *confname;
9503 if (!PyUnicode_Check(arg)) {
9504 PyErr_SetString(PyExc_TypeError,
9505 "configuration names must be strings or integers");
9506 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009507 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009508 confname = _PyUnicode_AsString(arg);
9509 if (confname == NULL)
9510 return 0;
9511 while (lo < hi) {
9512 mid = (lo + hi) / 2;
9513 cmp = strcmp(confname, table[mid].name);
9514 if (cmp < 0)
9515 hi = mid;
9516 else if (cmp > 0)
9517 lo = mid + 1;
9518 else {
9519 *valuep = table[mid].value;
9520 return 1;
9521 }
9522 }
9523 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9524 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009525 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009526}
9527
9528
9529#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9530static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009531#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009532 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009533#endif
9534#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009535 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009536#endif
Fred Drakec9680921999-12-13 16:37:25 +00009537#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009538 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009539#endif
9540#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009541 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009542#endif
9543#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009544 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009545#endif
9546#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009547 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009548#endif
9549#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009550 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009551#endif
9552#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009553 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009554#endif
9555#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009556 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009557#endif
9558#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009559 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009560#endif
9561#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009562 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009563#endif
9564#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009565 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009566#endif
9567#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009568 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009569#endif
9570#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009571 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009572#endif
9573#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009574 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009575#endif
9576#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009577 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009578#endif
9579#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009580 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009581#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009582#ifdef _PC_ACL_ENABLED
9583 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9584#endif
9585#ifdef _PC_MIN_HOLE_SIZE
9586 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9587#endif
9588#ifdef _PC_ALLOC_SIZE_MIN
9589 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9590#endif
9591#ifdef _PC_REC_INCR_XFER_SIZE
9592 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9593#endif
9594#ifdef _PC_REC_MAX_XFER_SIZE
9595 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9596#endif
9597#ifdef _PC_REC_MIN_XFER_SIZE
9598 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9599#endif
9600#ifdef _PC_REC_XFER_ALIGN
9601 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9602#endif
9603#ifdef _PC_SYMLINK_MAX
9604 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9605#endif
9606#ifdef _PC_XATTR_ENABLED
9607 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9608#endif
9609#ifdef _PC_XATTR_EXISTS
9610 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9611#endif
9612#ifdef _PC_TIMESTAMP_RESOLUTION
9613 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9614#endif
Fred Drakec9680921999-12-13 16:37:25 +00009615};
9616
Fred Drakec9680921999-12-13 16:37:25 +00009617static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009618conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009619{
9620 return conv_confname(arg, valuep, posix_constants_pathconf,
9621 sizeof(posix_constants_pathconf)
9622 / sizeof(struct constdef));
9623}
9624#endif
9625
Larry Hastings2f936352014-08-05 14:04:04 +10009626
Fred Drakec9680921999-12-13 16:37:25 +00009627#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009628/*[clinic input]
9629os.fpathconf -> long
9630
9631 fd: int
9632 name: path_confname
9633 /
9634
9635Return the configuration limit name for the file descriptor fd.
9636
9637If there is no limit, return -1.
9638[clinic start generated code]*/
9639
Larry Hastings2f936352014-08-05 14:04:04 +10009640static long
9641os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009642/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009643{
9644 long limit;
9645
9646 errno = 0;
9647 limit = fpathconf(fd, name);
9648 if (limit == -1 && errno != 0)
9649 posix_error();
9650
9651 return limit;
9652}
9653#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009654
9655
9656#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009657/*[clinic input]
9658os.pathconf -> long
9659 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9660 name: path_confname
9661
9662Return the configuration limit name for the file or directory path.
9663
9664If there is no limit, return -1.
9665On some platforms, path may also be specified as an open file descriptor.
9666 If this functionality is unavailable, using it raises an exception.
9667[clinic start generated code]*/
9668
Larry Hastings2f936352014-08-05 14:04:04 +10009669static long
9670os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009671/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009672{
Victor Stinner8c62be82010-05-06 00:08:46 +00009673 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009674
Victor Stinner8c62be82010-05-06 00:08:46 +00009675 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009676#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009677 if (path->fd != -1)
9678 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009679 else
9680#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009681 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009682 if (limit == -1 && errno != 0) {
9683 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009684 /* could be a path or name problem */
9685 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009686 else
Larry Hastings2f936352014-08-05 14:04:04 +10009687 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009688 }
Larry Hastings2f936352014-08-05 14:04:04 +10009689
9690 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009691}
Larry Hastings2f936352014-08-05 14:04:04 +10009692#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009693
9694#ifdef HAVE_CONFSTR
9695static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009696#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009697 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009698#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009699#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009700 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009701#endif
9702#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009703 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009704#endif
Fred Draked86ed291999-12-15 15:34:33 +00009705#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009706 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009707#endif
9708#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009709 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009710#endif
9711#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009712 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009713#endif
9714#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009715 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009716#endif
Fred Drakec9680921999-12-13 16:37:25 +00009717#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009718 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009719#endif
9720#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009721 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009722#endif
9723#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009724 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009725#endif
9726#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009727 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009728#endif
9729#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009730 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009731#endif
9732#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009733 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009734#endif
9735#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009736 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009737#endif
9738#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009739 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009740#endif
Fred Draked86ed291999-12-15 15:34:33 +00009741#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009742 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009743#endif
Fred Drakec9680921999-12-13 16:37:25 +00009744#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009745 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009746#endif
Fred Draked86ed291999-12-15 15:34:33 +00009747#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009748 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009749#endif
9750#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009751 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009752#endif
9753#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009754 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009755#endif
9756#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009757 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009758#endif
Fred Drakec9680921999-12-13 16:37:25 +00009759#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009760 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009761#endif
9762#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009763 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009764#endif
9765#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009766 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009767#endif
9768#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009769 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009770#endif
9771#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009772 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009773#endif
9774#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009775 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009776#endif
9777#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009778 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009779#endif
9780#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009781 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009782#endif
9783#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009784 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009785#endif
9786#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009787 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009788#endif
9789#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009790 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009791#endif
9792#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009793 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009794#endif
9795#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009796 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009797#endif
9798#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009799 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009800#endif
9801#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009802 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009803#endif
9804#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009805 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009806#endif
Fred Draked86ed291999-12-15 15:34:33 +00009807#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009808 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009809#endif
9810#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009811 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009812#endif
9813#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009814 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009815#endif
9816#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009817 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009818#endif
9819#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009820 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009821#endif
9822#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009823 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009824#endif
9825#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009826 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009827#endif
9828#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009829 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009830#endif
9831#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009832 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009833#endif
9834#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009835 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009836#endif
9837#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009838 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009839#endif
9840#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009841 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009842#endif
9843#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009844 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009845#endif
Fred Drakec9680921999-12-13 16:37:25 +00009846};
9847
9848static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009849conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009850{
9851 return conv_confname(arg, valuep, posix_constants_confstr,
9852 sizeof(posix_constants_confstr)
9853 / sizeof(struct constdef));
9854}
9855
Larry Hastings2f936352014-08-05 14:04:04 +10009856
9857/*[clinic input]
9858os.confstr
9859
9860 name: confstr_confname
9861 /
9862
9863Return a string-valued system configuration variable.
9864[clinic start generated code]*/
9865
Larry Hastings2f936352014-08-05 14:04:04 +10009866static PyObject *
9867os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009868/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009869{
9870 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009871 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009872 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009873
Victor Stinnercb043522010-09-10 23:49:04 +00009874 errno = 0;
9875 len = confstr(name, buffer, sizeof(buffer));
9876 if (len == 0) {
9877 if (errno) {
9878 posix_error();
9879 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009880 }
9881 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009882 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009883 }
9884 }
Victor Stinnercb043522010-09-10 23:49:04 +00009885
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009886 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009887 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009888 char *buf = PyMem_Malloc(len);
9889 if (buf == NULL)
9890 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009891 len2 = confstr(name, buf, len);
9892 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009893 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009894 PyMem_Free(buf);
9895 }
9896 else
9897 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009898 return result;
9899}
Larry Hastings2f936352014-08-05 14:04:04 +10009900#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009901
9902
9903#ifdef HAVE_SYSCONF
9904static struct constdef posix_constants_sysconf[] = {
9905#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009906 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009907#endif
9908#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009909 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009910#endif
9911#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009912 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009913#endif
9914#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009915 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009916#endif
9917#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009918 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009919#endif
9920#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009921 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009922#endif
9923#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009924 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009925#endif
9926#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009927 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009928#endif
9929#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009930 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009931#endif
9932#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009933 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009934#endif
Fred Draked86ed291999-12-15 15:34:33 +00009935#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009936 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009937#endif
9938#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009939 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009940#endif
Fred Drakec9680921999-12-13 16:37:25 +00009941#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009942 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009943#endif
Fred Drakec9680921999-12-13 16:37:25 +00009944#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009945 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009946#endif
9947#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009948 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009949#endif
9950#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009951 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009952#endif
9953#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009954 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009955#endif
9956#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009957 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009958#endif
Fred Draked86ed291999-12-15 15:34:33 +00009959#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009960 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009961#endif
Fred Drakec9680921999-12-13 16:37:25 +00009962#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009963 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009964#endif
9965#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009966 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009967#endif
9968#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009969 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009970#endif
9971#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009972 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009973#endif
9974#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009975 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009976#endif
Fred Draked86ed291999-12-15 15:34:33 +00009977#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009978 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009979#endif
Fred Drakec9680921999-12-13 16:37:25 +00009980#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009981 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009982#endif
9983#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009984 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009985#endif
9986#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009987 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009988#endif
9989#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009990 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009991#endif
9992#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009993 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009994#endif
9995#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009996 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009997#endif
9998#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009999 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010000#endif
10001#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010002 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010003#endif
10004#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010005 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010006#endif
10007#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010008 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010009#endif
10010#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010011 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010012#endif
10013#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010014 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010015#endif
10016#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010017 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010018#endif
10019#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010020 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010021#endif
10022#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010023 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010024#endif
10025#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010026 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010027#endif
10028#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010029 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010030#endif
10031#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010032 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010033#endif
10034#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010035 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010036#endif
10037#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010038 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010039#endif
10040#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010041 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010042#endif
10043#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010044 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010045#endif
10046#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010047 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010048#endif
Fred Draked86ed291999-12-15 15:34:33 +000010049#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010050 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010051#endif
Fred Drakec9680921999-12-13 16:37:25 +000010052#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010053 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010054#endif
10055#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010056 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010057#endif
10058#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010059 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010060#endif
Fred Draked86ed291999-12-15 15:34:33 +000010061#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010062 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010063#endif
Fred Drakec9680921999-12-13 16:37:25 +000010064#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010065 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010066#endif
Fred Draked86ed291999-12-15 15:34:33 +000010067#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010068 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010069#endif
10070#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010071 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010072#endif
Fred Drakec9680921999-12-13 16:37:25 +000010073#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010074 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010075#endif
10076#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010077 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010078#endif
10079#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010080 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010081#endif
10082#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010083 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010084#endif
Fred Draked86ed291999-12-15 15:34:33 +000010085#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010086 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010087#endif
Fred Drakec9680921999-12-13 16:37:25 +000010088#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010089 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010090#endif
10091#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010092 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010093#endif
10094#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010095 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010096#endif
10097#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010098 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010099#endif
10100#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010101 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010102#endif
10103#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010104 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010105#endif
10106#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010107 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010108#endif
Fred Draked86ed291999-12-15 15:34:33 +000010109#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010110 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010111#endif
Fred Drakec9680921999-12-13 16:37:25 +000010112#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010113 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010114#endif
10115#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010116 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010117#endif
Fred Draked86ed291999-12-15 15:34:33 +000010118#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010119 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010120#endif
Fred Drakec9680921999-12-13 16:37:25 +000010121#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010122 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010123#endif
10124#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010125 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010126#endif
10127#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010128 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010129#endif
10130#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010131 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010132#endif
10133#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010134 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010135#endif
10136#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010137 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010138#endif
10139#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010140 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010141#endif
10142#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010143 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010144#endif
10145#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010146 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010147#endif
Fred Draked86ed291999-12-15 15:34:33 +000010148#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010149 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010150#endif
10151#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010152 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010153#endif
Fred Drakec9680921999-12-13 16:37:25 +000010154#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010155 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010156#endif
10157#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010158 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010159#endif
10160#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010161 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010162#endif
10163#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010164 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010165#endif
10166#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010167 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010168#endif
10169#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010170 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010171#endif
10172#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010173 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010174#endif
10175#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010176 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010177#endif
10178#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010179 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010180#endif
10181#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010182 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010183#endif
10184#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010185 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010186#endif
10187#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010188 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010189#endif
10190#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010191 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010192#endif
10193#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010194 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010195#endif
10196#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010197 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010198#endif
10199#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010200 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010201#endif
10202#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010203 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010204#endif
10205#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010206 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010207#endif
10208#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010209 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010210#endif
10211#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010212 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010213#endif
10214#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010215 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010216#endif
10217#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010218 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010219#endif
10220#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010221 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010222#endif
10223#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010224 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010225#endif
10226#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010227 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010228#endif
10229#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010230 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010231#endif
10232#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010233 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010234#endif
10235#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010236 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010237#endif
10238#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010239 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010240#endif
10241#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010242 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010243#endif
10244#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010245 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010246#endif
10247#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010248 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010249#endif
10250#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010251 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010252#endif
10253#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010254 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010255#endif
10256#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010257 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010258#endif
Fred Draked86ed291999-12-15 15:34:33 +000010259#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010260 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010261#endif
Fred Drakec9680921999-12-13 16:37:25 +000010262#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010263 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010264#endif
10265#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010266 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010267#endif
10268#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010269 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010270#endif
10271#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010272 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010273#endif
10274#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010275 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010276#endif
10277#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010278 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010279#endif
10280#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010281 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010282#endif
10283#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010284 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010285#endif
10286#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010287 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010288#endif
10289#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010290 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010291#endif
10292#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010293 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010294#endif
10295#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010296 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010297#endif
10298#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010299 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010300#endif
10301#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010302 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010303#endif
10304#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010305 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010306#endif
10307#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010308 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010309#endif
10310#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010311 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010312#endif
10313#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010314 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010315#endif
10316#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010317 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010318#endif
10319#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010320 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010321#endif
10322#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010323 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010324#endif
10325#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010326 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010327#endif
10328#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010329 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010330#endif
10331#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010332 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010333#endif
10334#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010335 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010336#endif
10337#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010338 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010339#endif
10340#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010341 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010342#endif
10343#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010344 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010345#endif
10346#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010347 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010348#endif
10349#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010350 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010351#endif
10352#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010353 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010354#endif
10355#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010356 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010357#endif
10358#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010359 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010360#endif
10361#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010362 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010363#endif
10364#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010365 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010366#endif
10367#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010368 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010369#endif
10370#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010371 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010372#endif
10373#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010374 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010375#endif
10376#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010377 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010378#endif
10379#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010380 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010381#endif
10382#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010383 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010384#endif
10385#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010386 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010387#endif
10388#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010389 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010390#endif
10391#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010392 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010393#endif
10394#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010395 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010396#endif
10397};
10398
10399static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010400conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010401{
10402 return conv_confname(arg, valuep, posix_constants_sysconf,
10403 sizeof(posix_constants_sysconf)
10404 / sizeof(struct constdef));
10405}
10406
Larry Hastings2f936352014-08-05 14:04:04 +100010407
10408/*[clinic input]
10409os.sysconf -> long
10410 name: sysconf_confname
10411 /
10412
10413Return an integer-valued system configuration variable.
10414[clinic start generated code]*/
10415
Larry Hastings2f936352014-08-05 14:04:04 +100010416static long
10417os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010418/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010419{
10420 long value;
10421
10422 errno = 0;
10423 value = sysconf(name);
10424 if (value == -1 && errno != 0)
10425 posix_error();
10426 return value;
10427}
10428#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010429
10430
Fred Drakebec628d1999-12-15 18:31:10 +000010431/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010432 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010433 * the exported dictionaries that are used to publish information about the
10434 * names available on the host platform.
10435 *
10436 * Sorting the table at runtime ensures that the table is properly ordered
10437 * when used, even for platforms we're not able to test on. It also makes
10438 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010439 */
Fred Drakebec628d1999-12-15 18:31:10 +000010440
10441static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010442cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010443{
10444 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010445 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010446 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010447 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010448
10449 return strcmp(c1->name, c2->name);
10450}
10451
10452static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010453setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010454 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010455{
Fred Drakebec628d1999-12-15 18:31:10 +000010456 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010457 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010458
10459 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10460 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010461 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010462 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010463
Barry Warsaw3155db32000-04-13 15:20:40 +000010464 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010465 PyObject *o = PyLong_FromLong(table[i].value);
10466 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10467 Py_XDECREF(o);
10468 Py_DECREF(d);
10469 return -1;
10470 }
10471 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010472 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010473 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010474}
10475
Fred Drakebec628d1999-12-15 18:31:10 +000010476/* Return -1 on failure, 0 on success. */
10477static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010478setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010479{
10480#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010481 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010482 sizeof(posix_constants_pathconf)
10483 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010484 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010485 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010486#endif
10487#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010488 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010489 sizeof(posix_constants_confstr)
10490 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010491 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010492 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010493#endif
10494#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010495 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010496 sizeof(posix_constants_sysconf)
10497 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010498 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010499 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010500#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010501 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010502}
Fred Draked86ed291999-12-15 15:34:33 +000010503
10504
Larry Hastings2f936352014-08-05 14:04:04 +100010505/*[clinic input]
10506os.abort
10507
10508Abort the interpreter immediately.
10509
10510This function 'dumps core' or otherwise fails in the hardest way possible
10511on the hosting operating system. This function never returns.
10512[clinic start generated code]*/
10513
Larry Hastings2f936352014-08-05 14:04:04 +100010514static PyObject *
10515os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010516/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010517{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010518 abort();
10519 /*NOTREACHED*/
10520 Py_FatalError("abort() called from Python code didn't abort!");
10521 return NULL;
10522}
Fred Drakebec628d1999-12-15 18:31:10 +000010523
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010524#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010525/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010526PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010527"startfile(filepath [, operation])\n\
10528\n\
10529Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010530\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010531When \"operation\" is not specified or \"open\", this acts like\n\
10532double-clicking the file in Explorer, or giving the file name as an\n\
10533argument to the DOS \"start\" command: the file is opened with whatever\n\
10534application (if any) its extension is associated.\n\
10535When another \"operation\" is given, it specifies what should be done with\n\
10536the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010537\n\
10538startfile returns as soon as the associated application is launched.\n\
10539There is no option to wait for the application to close, and no way\n\
10540to retrieve the application's exit status.\n\
10541\n\
10542The filepath is relative to the current directory. If you want to use\n\
10543an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010544the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010545
Steve Dower7d0e0c92015-01-24 08:18:24 -080010546/* Grab ShellExecute dynamically from shell32 */
10547static int has_ShellExecute = -1;
10548static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10549 LPCSTR, INT);
10550static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10551 LPCWSTR, INT);
10552static int
10553check_ShellExecute()
10554{
10555 HINSTANCE hShell32;
10556
10557 /* only recheck */
10558 if (-1 == has_ShellExecute) {
10559 Py_BEGIN_ALLOW_THREADS
10560 hShell32 = LoadLibraryW(L"SHELL32");
10561 Py_END_ALLOW_THREADS
10562 if (hShell32) {
10563 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10564 "ShellExecuteA");
10565 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10566 "ShellExecuteW");
10567 has_ShellExecute = Py_ShellExecuteA &&
10568 Py_ShellExecuteW;
10569 } else {
10570 has_ShellExecute = 0;
10571 }
10572 }
10573 return has_ShellExecute;
10574}
10575
10576
Tim Petersf58a7aa2000-09-22 10:05:54 +000010577static PyObject *
10578win32_startfile(PyObject *self, PyObject *args)
10579{
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 PyObject *ofilepath;
10581 char *filepath;
10582 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010583 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010584 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010585
Victor Stinnereb5657a2011-09-30 01:44:27 +020010586 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010587
10588 if(!check_ShellExecute()) {
10589 /* If the OS doesn't have ShellExecute, return a
10590 NotImplementedError. */
10591 return PyErr_Format(PyExc_NotImplementedError,
10592 "startfile not available on this platform");
10593 }
10594
Victor Stinner8c62be82010-05-06 00:08:46 +000010595 if (!PyArg_ParseTuple(args, "U|s:startfile",
10596 &unipath, &operation)) {
10597 PyErr_Clear();
10598 goto normal;
10599 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010600
Victor Stinner8c62be82010-05-06 00:08:46 +000010601 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010602 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010603 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010604 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 PyErr_Clear();
10606 operation = NULL;
10607 goto normal;
10608 }
10609 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010610
Victor Stinnereb5657a2011-09-30 01:44:27 +020010611 wpath = PyUnicode_AsUnicode(unipath);
10612 if (wpath == NULL)
10613 goto normal;
10614 if (uoperation) {
10615 woperation = PyUnicode_AsUnicode(uoperation);
10616 if (woperation == NULL)
10617 goto normal;
10618 }
10619 else
10620 woperation = NULL;
10621
Victor Stinner8c62be82010-05-06 00:08:46 +000010622 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010623 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10624 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 Py_END_ALLOW_THREADS
10626
Victor Stinnereb5657a2011-09-30 01:44:27 +020010627 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010628 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010629 win32_error_object("startfile", unipath);
10630 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010631 }
10632 Py_INCREF(Py_None);
10633 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010634
10635normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010636 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10637 PyUnicode_FSConverter, &ofilepath,
10638 &operation))
10639 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010640 if (win32_warn_bytes_api()) {
10641 Py_DECREF(ofilepath);
10642 return NULL;
10643 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010644 filepath = PyBytes_AsString(ofilepath);
10645 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010646 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10647 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010648 Py_END_ALLOW_THREADS
10649 if (rc <= (HINSTANCE)32) {
10650 PyObject *errval = win32_error("startfile", filepath);
10651 Py_DECREF(ofilepath);
10652 return errval;
10653 }
10654 Py_DECREF(ofilepath);
10655 Py_INCREF(Py_None);
10656 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010657}
Larry Hastings2f936352014-08-05 14:04:04 +100010658#endif /* MS_WINDOWS */
10659
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010660
Martin v. Löwis438b5342002-12-27 10:16:42 +000010661#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010662/*[clinic input]
10663os.getloadavg
10664
10665Return average recent system load information.
10666
10667Return the number of processes in the system run queue averaged over
10668the last 1, 5, and 15 minutes as a tuple of three floats.
10669Raises OSError if the load average was unobtainable.
10670[clinic start generated code]*/
10671
Larry Hastings2f936352014-08-05 14:04:04 +100010672static PyObject *
10673os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010674/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010675{
10676 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010677 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010678 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10679 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010680 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010681 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010682}
Larry Hastings2f936352014-08-05 14:04:04 +100010683#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010684
Larry Hastings2f936352014-08-05 14:04:04 +100010685
10686/*[clinic input]
10687os.device_encoding
10688 fd: int
10689
10690Return a string describing the encoding of a terminal's file descriptor.
10691
10692The file descriptor must be attached to a terminal.
10693If the device is not a terminal, return None.
10694[clinic start generated code]*/
10695
Larry Hastings2f936352014-08-05 14:04:04 +100010696static PyObject *
10697os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010698/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010699{
Brett Cannonefb00c02012-02-29 18:31:31 -050010700 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010701}
10702
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010703
Larry Hastings2f936352014-08-05 14:04:04 +100010704#ifdef HAVE_SETRESUID
10705/*[clinic input]
10706os.setresuid
10707
10708 ruid: uid_t
10709 euid: uid_t
10710 suid: uid_t
10711 /
10712
10713Set the current process's real, effective, and saved user ids.
10714[clinic start generated code]*/
10715
Larry Hastings2f936352014-08-05 14:04:04 +100010716static PyObject *
10717os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010718/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010719{
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 if (setresuid(ruid, euid, suid) < 0)
10721 return posix_error();
10722 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010723}
Larry Hastings2f936352014-08-05 14:04:04 +100010724#endif /* HAVE_SETRESUID */
10725
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010726
10727#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010728/*[clinic input]
10729os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010730
Larry Hastings2f936352014-08-05 14:04:04 +100010731 rgid: gid_t
10732 egid: gid_t
10733 sgid: gid_t
10734 /
10735
10736Set the current process's real, effective, and saved group ids.
10737[clinic start generated code]*/
10738
Larry Hastings2f936352014-08-05 14:04:04 +100010739static PyObject *
10740os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010741/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010742{
Victor Stinner8c62be82010-05-06 00:08:46 +000010743 if (setresgid(rgid, egid, sgid) < 0)
10744 return posix_error();
10745 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010746}
Larry Hastings2f936352014-08-05 14:04:04 +100010747#endif /* HAVE_SETRESGID */
10748
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010749
10750#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010751/*[clinic input]
10752os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010753
Larry Hastings2f936352014-08-05 14:04:04 +100010754Return a tuple of the current process's real, effective, and saved user ids.
10755[clinic start generated code]*/
10756
Larry Hastings2f936352014-08-05 14:04:04 +100010757static PyObject *
10758os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010759/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010760{
Victor Stinner8c62be82010-05-06 00:08:46 +000010761 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 if (getresuid(&ruid, &euid, &suid) < 0)
10763 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010764 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10765 _PyLong_FromUid(euid),
10766 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010767}
Larry Hastings2f936352014-08-05 14:04:04 +100010768#endif /* HAVE_GETRESUID */
10769
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010770
10771#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010772/*[clinic input]
10773os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010774
Larry Hastings2f936352014-08-05 14:04:04 +100010775Return a tuple of the current process's real, effective, and saved group ids.
10776[clinic start generated code]*/
10777
Larry Hastings2f936352014-08-05 14:04:04 +100010778static PyObject *
10779os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010780/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010781{
10782 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010783 if (getresgid(&rgid, &egid, &sgid) < 0)
10784 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010785 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10786 _PyLong_FromGid(egid),
10787 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010788}
Larry Hastings2f936352014-08-05 14:04:04 +100010789#endif /* HAVE_GETRESGID */
10790
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010791
Benjamin Peterson9428d532011-09-14 11:45:52 -040010792#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010793/*[clinic input]
10794os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010795
Larry Hastings2f936352014-08-05 14:04:04 +100010796 path: path_t(allow_fd=True)
10797 attribute: path_t
10798 *
10799 follow_symlinks: bool = True
10800
10801Return the value of extended attribute attribute on path.
10802
10803path may be either a string or an open file descriptor.
10804If follow_symlinks is False, and the last element of the path is a symbolic
10805 link, getxattr will examine the symbolic link itself instead of the file
10806 the link points to.
10807
10808[clinic start generated code]*/
10809
Larry Hastings2f936352014-08-05 14:04:04 +100010810static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010811os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10812 int follow_symlinks)
10813/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010814{
10815 Py_ssize_t i;
10816 PyObject *buffer = NULL;
10817
10818 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10819 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010820
Larry Hastings9cf065c2012-06-22 16:30:09 -070010821 for (i = 0; ; i++) {
10822 void *ptr;
10823 ssize_t result;
10824 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10825 Py_ssize_t buffer_size = buffer_sizes[i];
10826 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010827 path_error(path);
10828 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010829 }
10830 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10831 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010832 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010833 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010834
Larry Hastings9cf065c2012-06-22 16:30:09 -070010835 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010836 if (path->fd >= 0)
10837 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010838 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010839 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010840 else
Larry Hastings2f936352014-08-05 14:04:04 +100010841 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010842 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010843
Larry Hastings9cf065c2012-06-22 16:30:09 -070010844 if (result < 0) {
10845 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010846 if (errno == ERANGE)
10847 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010848 path_error(path);
10849 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010850 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010851
Larry Hastings9cf065c2012-06-22 16:30:09 -070010852 if (result != buffer_size) {
10853 /* Can only shrink. */
10854 _PyBytes_Resize(&buffer, result);
10855 }
10856 break;
10857 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010858
Larry Hastings9cf065c2012-06-22 16:30:09 -070010859 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010860}
10861
Larry Hastings2f936352014-08-05 14:04:04 +100010862
10863/*[clinic input]
10864os.setxattr
10865
10866 path: path_t(allow_fd=True)
10867 attribute: path_t
10868 value: Py_buffer
10869 flags: int = 0
10870 *
10871 follow_symlinks: bool = True
10872
10873Set extended attribute attribute on path to value.
10874
10875path may be either a string or an open file descriptor.
10876If follow_symlinks is False, and the last element of the path is a symbolic
10877 link, setxattr will modify the symbolic link itself instead of the file
10878 the link points to.
10879
10880[clinic start generated code]*/
10881
Benjamin Peterson799bd802011-08-31 22:15:17 -040010882static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010883os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10884 Py_buffer *value, int flags, int follow_symlinks)
10885/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010886{
Larry Hastings2f936352014-08-05 14:04:04 +100010887 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010888
Larry Hastings2f936352014-08-05 14:04:04 +100010889 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010890 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010891
Benjamin Peterson799bd802011-08-31 22:15:17 -040010892 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010893 if (path->fd > -1)
10894 result = fsetxattr(path->fd, attribute->narrow,
10895 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010896 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010897 result = setxattr(path->narrow, attribute->narrow,
10898 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010899 else
Larry Hastings2f936352014-08-05 14:04:04 +100010900 result = lsetxattr(path->narrow, attribute->narrow,
10901 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010902 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010903
Larry Hastings9cf065c2012-06-22 16:30:09 -070010904 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010905 path_error(path);
10906 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010907 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908
Larry Hastings2f936352014-08-05 14:04:04 +100010909 Py_RETURN_NONE;
10910}
10911
10912
10913/*[clinic input]
10914os.removexattr
10915
10916 path: path_t(allow_fd=True)
10917 attribute: path_t
10918 *
10919 follow_symlinks: bool = True
10920
10921Remove extended attribute attribute on path.
10922
10923path may be either a string or an open file descriptor.
10924If follow_symlinks is False, and the last element of the path is a symbolic
10925 link, removexattr will modify the symbolic link itself instead of the file
10926 the link points to.
10927
10928[clinic start generated code]*/
10929
Larry Hastings2f936352014-08-05 14:04:04 +100010930static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010931os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10932 int follow_symlinks)
10933/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010934{
10935 ssize_t result;
10936
10937 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10938 return NULL;
10939
10940 Py_BEGIN_ALLOW_THREADS;
10941 if (path->fd > -1)
10942 result = fremovexattr(path->fd, attribute->narrow);
10943 else if (follow_symlinks)
10944 result = removexattr(path->narrow, attribute->narrow);
10945 else
10946 result = lremovexattr(path->narrow, attribute->narrow);
10947 Py_END_ALLOW_THREADS;
10948
10949 if (result) {
10950 return path_error(path);
10951 }
10952
10953 Py_RETURN_NONE;
10954}
10955
10956
10957/*[clinic input]
10958os.listxattr
10959
10960 path: path_t(allow_fd=True, nullable=True) = None
10961 *
10962 follow_symlinks: bool = True
10963
10964Return a list of extended attributes on path.
10965
10966path may be either None, a string, or an open file descriptor.
10967if path is None, listxattr will examine the current directory.
10968If follow_symlinks is False, and the last element of the path is a symbolic
10969 link, listxattr will examine the symbolic link itself instead of the file
10970 the link points to.
10971[clinic start generated code]*/
10972
Larry Hastings2f936352014-08-05 14:04:04 +100010973static PyObject *
10974os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010975/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010976{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010977 Py_ssize_t i;
10978 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010979 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010980 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010981
Larry Hastings2f936352014-08-05 14:04:04 +100010982 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010983 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010984
Larry Hastings2f936352014-08-05 14:04:04 +100010985 name = path->narrow ? path->narrow : ".";
10986
Larry Hastings9cf065c2012-06-22 16:30:09 -070010987 for (i = 0; ; i++) {
10988 char *start, *trace, *end;
10989 ssize_t length;
10990 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10991 Py_ssize_t buffer_size = buffer_sizes[i];
10992 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010993 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010994 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010995 break;
10996 }
10997 buffer = PyMem_MALLOC(buffer_size);
10998 if (!buffer) {
10999 PyErr_NoMemory();
11000 break;
11001 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011002
Larry Hastings9cf065c2012-06-22 16:30:09 -070011003 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011004 if (path->fd > -1)
11005 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011006 else if (follow_symlinks)
11007 length = listxattr(name, buffer, buffer_size);
11008 else
11009 length = llistxattr(name, buffer, buffer_size);
11010 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011011
Larry Hastings9cf065c2012-06-22 16:30:09 -070011012 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011013 if (errno == ERANGE) {
11014 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011015 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011016 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011017 }
Larry Hastings2f936352014-08-05 14:04:04 +100011018 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011019 break;
11020 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011021
Larry Hastings9cf065c2012-06-22 16:30:09 -070011022 result = PyList_New(0);
11023 if (!result) {
11024 goto exit;
11025 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011026
Larry Hastings9cf065c2012-06-22 16:30:09 -070011027 end = buffer + length;
11028 for (trace = start = buffer; trace != end; trace++) {
11029 if (!*trace) {
11030 int error;
11031 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11032 trace - start);
11033 if (!attribute) {
11034 Py_DECREF(result);
11035 result = NULL;
11036 goto exit;
11037 }
11038 error = PyList_Append(result, attribute);
11039 Py_DECREF(attribute);
11040 if (error) {
11041 Py_DECREF(result);
11042 result = NULL;
11043 goto exit;
11044 }
11045 start = trace + 1;
11046 }
11047 }
11048 break;
11049 }
11050exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011051 if (buffer)
11052 PyMem_FREE(buffer);
11053 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011054}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011055#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011056
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011057
Larry Hastings2f936352014-08-05 14:04:04 +100011058/*[clinic input]
11059os.urandom
11060
11061 size: Py_ssize_t
11062 /
11063
11064Return a bytes object containing random bytes suitable for cryptographic use.
11065[clinic start generated code]*/
11066
Larry Hastings2f936352014-08-05 14:04:04 +100011067static PyObject *
11068os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011069/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011070{
11071 PyObject *bytes;
11072 int result;
11073
Georg Brandl2fb477c2012-02-21 00:33:36 +010011074 if (size < 0)
11075 return PyErr_Format(PyExc_ValueError,
11076 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011077 bytes = PyBytes_FromStringAndSize(NULL, size);
11078 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011079 return NULL;
11080
Larry Hastings2f936352014-08-05 14:04:04 +100011081 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11082 PyBytes_GET_SIZE(bytes));
11083 if (result == -1) {
11084 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011085 return NULL;
11086 }
Larry Hastings2f936352014-08-05 14:04:04 +100011087 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011088}
11089
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011090/* Terminal size querying */
11091
11092static PyTypeObject TerminalSizeType;
11093
11094PyDoc_STRVAR(TerminalSize_docstring,
11095 "A tuple of (columns, lines) for holding terminal window size");
11096
11097static PyStructSequence_Field TerminalSize_fields[] = {
11098 {"columns", "width of the terminal window in characters"},
11099 {"lines", "height of the terminal window in characters"},
11100 {NULL, NULL}
11101};
11102
11103static PyStructSequence_Desc TerminalSize_desc = {
11104 "os.terminal_size",
11105 TerminalSize_docstring,
11106 TerminalSize_fields,
11107 2,
11108};
11109
11110#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011111/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011112PyDoc_STRVAR(termsize__doc__,
11113 "Return the size of the terminal window as (columns, lines).\n" \
11114 "\n" \
11115 "The optional argument fd (default standard output) specifies\n" \
11116 "which file descriptor should be queried.\n" \
11117 "\n" \
11118 "If the file descriptor is not connected to a terminal, an OSError\n" \
11119 "is thrown.\n" \
11120 "\n" \
11121 "This function will only be defined if an implementation is\n" \
11122 "available for this system.\n" \
11123 "\n" \
11124 "shutil.get_terminal_size is the high-level function which should \n" \
11125 "normally be used, os.get_terminal_size is the low-level implementation.");
11126
11127static PyObject*
11128get_terminal_size(PyObject *self, PyObject *args)
11129{
11130 int columns, lines;
11131 PyObject *termsize;
11132
11133 int fd = fileno(stdout);
11134 /* Under some conditions stdout may not be connected and
11135 * fileno(stdout) may point to an invalid file descriptor. For example
11136 * GUI apps don't have valid standard streams by default.
11137 *
11138 * If this happens, and the optional fd argument is not present,
11139 * the ioctl below will fail returning EBADF. This is what we want.
11140 */
11141
11142 if (!PyArg_ParseTuple(args, "|i", &fd))
11143 return NULL;
11144
11145#ifdef TERMSIZE_USE_IOCTL
11146 {
11147 struct winsize w;
11148 if (ioctl(fd, TIOCGWINSZ, &w))
11149 return PyErr_SetFromErrno(PyExc_OSError);
11150 columns = w.ws_col;
11151 lines = w.ws_row;
11152 }
11153#endif /* TERMSIZE_USE_IOCTL */
11154
11155#ifdef TERMSIZE_USE_CONIO
11156 {
11157 DWORD nhandle;
11158 HANDLE handle;
11159 CONSOLE_SCREEN_BUFFER_INFO csbi;
11160 switch (fd) {
11161 case 0: nhandle = STD_INPUT_HANDLE;
11162 break;
11163 case 1: nhandle = STD_OUTPUT_HANDLE;
11164 break;
11165 case 2: nhandle = STD_ERROR_HANDLE;
11166 break;
11167 default:
11168 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11169 }
11170 handle = GetStdHandle(nhandle);
11171 if (handle == NULL)
11172 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11173 if (handle == INVALID_HANDLE_VALUE)
11174 return PyErr_SetFromWindowsErr(0);
11175
11176 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11177 return PyErr_SetFromWindowsErr(0);
11178
11179 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11180 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11181 }
11182#endif /* TERMSIZE_USE_CONIO */
11183
11184 termsize = PyStructSequence_New(&TerminalSizeType);
11185 if (termsize == NULL)
11186 return NULL;
11187 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11188 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11189 if (PyErr_Occurred()) {
11190 Py_DECREF(termsize);
11191 return NULL;
11192 }
11193 return termsize;
11194}
11195#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11196
Larry Hastings2f936352014-08-05 14:04:04 +100011197
11198/*[clinic input]
11199os.cpu_count
11200
11201Return the number of CPUs in the system; return None if indeterminable.
11202[clinic start generated code]*/
11203
Larry Hastings2f936352014-08-05 14:04:04 +100011204static PyObject *
11205os_cpu_count_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011206/*[clinic end generated code: output=c59ee7f6bce832b8 input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011207{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011208 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011209#ifdef MS_WINDOWS
11210 SYSTEM_INFO sysinfo;
11211 GetSystemInfo(&sysinfo);
11212 ncpu = sysinfo.dwNumberOfProcessors;
11213#elif defined(__hpux)
11214 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11215#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11216 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011217#elif defined(__DragonFly__) || \
11218 defined(__OpenBSD__) || \
11219 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011220 defined(__NetBSD__) || \
11221 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011222 int mib[2];
11223 size_t len = sizeof(ncpu);
11224 mib[0] = CTL_HW;
11225 mib[1] = HW_NCPU;
11226 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11227 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011228#endif
11229 if (ncpu >= 1)
11230 return PyLong_FromLong(ncpu);
11231 else
11232 Py_RETURN_NONE;
11233}
11234
Victor Stinnerdaf45552013-08-28 00:53:59 +020011235
Larry Hastings2f936352014-08-05 14:04:04 +100011236/*[clinic input]
11237os.get_inheritable -> bool
11238
11239 fd: int
11240 /
11241
11242Get the close-on-exe flag of the specified file descriptor.
11243[clinic start generated code]*/
11244
Larry Hastings2f936352014-08-05 14:04:04 +100011245static int
11246os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011247/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011248{
Steve Dower8fc89802015-04-12 00:26:27 -040011249 int return_value;
11250 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011251 posix_error();
11252 return -1;
11253 }
11254
Steve Dower8fc89802015-04-12 00:26:27 -040011255 _Py_BEGIN_SUPPRESS_IPH
11256 return_value = _Py_get_inheritable(fd);
11257 _Py_END_SUPPRESS_IPH
11258 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011259}
11260
11261
11262/*[clinic input]
11263os.set_inheritable
11264 fd: int
11265 inheritable: int
11266 /
11267
11268Set the inheritable flag of the specified file descriptor.
11269[clinic start generated code]*/
11270
Larry Hastings2f936352014-08-05 14:04:04 +100011271static PyObject *
11272os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011273/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011274{
Steve Dower8fc89802015-04-12 00:26:27 -040011275 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011276 if (!_PyVerify_fd(fd))
11277 return posix_error();
11278
Steve Dower8fc89802015-04-12 00:26:27 -040011279 _Py_BEGIN_SUPPRESS_IPH
11280 result = _Py_set_inheritable(fd, inheritable, NULL);
11281 _Py_END_SUPPRESS_IPH
11282 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011283 return NULL;
11284 Py_RETURN_NONE;
11285}
11286
11287
11288#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011289/*[clinic input]
11290os.get_handle_inheritable -> bool
11291 handle: Py_intptr_t
11292 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011293
Larry Hastings2f936352014-08-05 14:04:04 +100011294Get the close-on-exe flag of the specified file descriptor.
11295[clinic start generated code]*/
11296
Larry Hastings2f936352014-08-05 14:04:04 +100011297static int
11298os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011299/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011300{
11301 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011302
11303 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11304 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011305 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011306 }
11307
Larry Hastings2f936352014-08-05 14:04:04 +100011308 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011309}
11310
Victor Stinnerdaf45552013-08-28 00:53:59 +020011311
Larry Hastings2f936352014-08-05 14:04:04 +100011312/*[clinic input]
11313os.set_handle_inheritable
11314 handle: Py_intptr_t
11315 inheritable: bool
11316 /
11317
11318Set the inheritable flag of the specified handle.
11319[clinic start generated code]*/
11320
Larry Hastings2f936352014-08-05 14:04:04 +100011321static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040011322os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle,
11323 int inheritable)
11324/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011325{
11326 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011327 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11328 PyErr_SetFromWindowsErr(0);
11329 return NULL;
11330 }
11331 Py_RETURN_NONE;
11332}
Larry Hastings2f936352014-08-05 14:04:04 +100011333#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011334
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011335#ifndef MS_WINDOWS
11336PyDoc_STRVAR(get_blocking__doc__,
11337 "get_blocking(fd) -> bool\n" \
11338 "\n" \
11339 "Get the blocking mode of the file descriptor:\n" \
11340 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11341
11342static PyObject*
11343posix_get_blocking(PyObject *self, PyObject *args)
11344{
11345 int fd;
11346 int blocking;
11347
11348 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11349 return NULL;
11350
11351 if (!_PyVerify_fd(fd))
11352 return posix_error();
11353
Steve Dower8fc89802015-04-12 00:26:27 -040011354 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011355 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011356 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011357 if (blocking < 0)
11358 return NULL;
11359 return PyBool_FromLong(blocking);
11360}
11361
11362PyDoc_STRVAR(set_blocking__doc__,
11363 "set_blocking(fd, blocking)\n" \
11364 "\n" \
11365 "Set the blocking mode of the specified file descriptor.\n" \
11366 "Set the O_NONBLOCK flag if blocking is False,\n" \
11367 "clear the O_NONBLOCK flag otherwise.");
11368
11369static PyObject*
11370posix_set_blocking(PyObject *self, PyObject *args)
11371{
Steve Dower8fc89802015-04-12 00:26:27 -040011372 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011373
11374 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11375 return NULL;
11376
11377 if (!_PyVerify_fd(fd))
11378 return posix_error();
11379
Steve Dower8fc89802015-04-12 00:26:27 -040011380 _Py_BEGIN_SUPPRESS_IPH
11381 result = _Py_set_blocking(fd, blocking);
11382 _Py_END_SUPPRESS_IPH
11383 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011384 return NULL;
11385 Py_RETURN_NONE;
11386}
11387#endif /* !MS_WINDOWS */
11388
11389
Victor Stinner6036e442015-03-08 01:58:04 +010011390PyDoc_STRVAR(posix_scandir__doc__,
11391"scandir(path='.') -> iterator of DirEntry objects for given path");
11392
11393static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11394
11395typedef struct {
11396 PyObject_HEAD
11397 PyObject *name;
11398 PyObject *path;
11399 PyObject *stat;
11400 PyObject *lstat;
11401#ifdef MS_WINDOWS
11402 struct _Py_stat_struct win32_lstat;
11403 __int64 win32_file_index;
11404 int got_file_index;
11405#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011406#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011407 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011408#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011409 ino_t d_ino;
11410#endif
11411} DirEntry;
11412
11413static void
11414DirEntry_dealloc(DirEntry *entry)
11415{
11416 Py_XDECREF(entry->name);
11417 Py_XDECREF(entry->path);
11418 Py_XDECREF(entry->stat);
11419 Py_XDECREF(entry->lstat);
11420 Py_TYPE(entry)->tp_free((PyObject *)entry);
11421}
11422
11423/* Forward reference */
11424static int
11425DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11426
11427/* Set exception and return -1 on error, 0 for False, 1 for True */
11428static int
11429DirEntry_is_symlink(DirEntry *self)
11430{
11431#ifdef MS_WINDOWS
11432 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011433#elif defined(HAVE_DIRENT_D_TYPE)
11434 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011435 if (self->d_type != DT_UNKNOWN)
11436 return self->d_type == DT_LNK;
11437 else
11438 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011439#else
11440 /* POSIX without d_type */
11441 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011442#endif
11443}
11444
11445static PyObject *
11446DirEntry_py_is_symlink(DirEntry *self)
11447{
11448 int result;
11449
11450 result = DirEntry_is_symlink(self);
11451 if (result == -1)
11452 return NULL;
11453 return PyBool_FromLong(result);
11454}
11455
11456static PyObject *
11457DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11458{
11459 int result;
11460 struct _Py_stat_struct st;
11461
11462#ifdef MS_WINDOWS
11463 wchar_t *path;
11464
11465 path = PyUnicode_AsUnicode(self->path);
11466 if (!path)
11467 return NULL;
11468
11469 if (follow_symlinks)
11470 result = win32_stat_w(path, &st);
11471 else
11472 result = win32_lstat_w(path, &st);
11473
11474 if (result != 0) {
11475 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11476 0, self->path);
11477 }
11478#else /* POSIX */
11479 PyObject *bytes;
11480 char *path;
11481
11482 if (!PyUnicode_FSConverter(self->path, &bytes))
11483 return NULL;
11484 path = PyBytes_AS_STRING(bytes);
11485
11486 if (follow_symlinks)
11487 result = STAT(path, &st);
11488 else
11489 result = LSTAT(path, &st);
11490 Py_DECREF(bytes);
11491
11492 if (result != 0)
11493 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11494#endif
11495
11496 return _pystat_fromstructstat(&st);
11497}
11498
11499static PyObject *
11500DirEntry_get_lstat(DirEntry *self)
11501{
11502 if (!self->lstat) {
11503#ifdef MS_WINDOWS
11504 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11505#else /* POSIX */
11506 self->lstat = DirEntry_fetch_stat(self, 0);
11507#endif
11508 }
11509 Py_XINCREF(self->lstat);
11510 return self->lstat;
11511}
11512
11513static PyObject *
11514DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11515{
11516 if (!follow_symlinks)
11517 return DirEntry_get_lstat(self);
11518
11519 if (!self->stat) {
11520 int result = DirEntry_is_symlink(self);
11521 if (result == -1)
11522 return NULL;
11523 else if (result)
11524 self->stat = DirEntry_fetch_stat(self, 1);
11525 else
11526 self->stat = DirEntry_get_lstat(self);
11527 }
11528
11529 Py_XINCREF(self->stat);
11530 return self->stat;
11531}
11532
11533static PyObject *
11534DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11535{
11536 int follow_symlinks = 1;
11537
11538 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11539 follow_symlinks_keywords, &follow_symlinks))
11540 return NULL;
11541
11542 return DirEntry_get_stat(self, follow_symlinks);
11543}
11544
11545/* Set exception and return -1 on error, 0 for False, 1 for True */
11546static int
11547DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11548{
11549 PyObject *stat = NULL;
11550 PyObject *st_mode = NULL;
11551 long mode;
11552 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011553#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011554 int is_symlink;
11555 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011556#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011557#ifdef MS_WINDOWS
11558 unsigned long dir_bits;
11559#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011560 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011561
11562#ifdef MS_WINDOWS
11563 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11564 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011565#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011566 is_symlink = self->d_type == DT_LNK;
11567 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11568#endif
11569
Victor Stinner35a97c02015-03-08 02:59:09 +010011570#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011571 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011572#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011573 stat = DirEntry_get_stat(self, follow_symlinks);
11574 if (!stat) {
11575 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11576 /* If file doesn't exist (anymore), then return False
11577 (i.e., say it's not a file/directory) */
11578 PyErr_Clear();
11579 return 0;
11580 }
11581 goto error;
11582 }
11583 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11584 if (!st_mode)
11585 goto error;
11586
11587 mode = PyLong_AsLong(st_mode);
11588 if (mode == -1 && PyErr_Occurred())
11589 goto error;
11590 Py_CLEAR(st_mode);
11591 Py_CLEAR(stat);
11592 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011593#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011594 }
11595 else if (is_symlink) {
11596 assert(mode_bits != S_IFLNK);
11597 result = 0;
11598 }
11599 else {
11600 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11601#ifdef MS_WINDOWS
11602 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11603 if (mode_bits == S_IFDIR)
11604 result = dir_bits != 0;
11605 else
11606 result = dir_bits == 0;
11607#else /* POSIX */
11608 if (mode_bits == S_IFDIR)
11609 result = self->d_type == DT_DIR;
11610 else
11611 result = self->d_type == DT_REG;
11612#endif
11613 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011614#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011615
11616 return result;
11617
11618error:
11619 Py_XDECREF(st_mode);
11620 Py_XDECREF(stat);
11621 return -1;
11622}
11623
11624static PyObject *
11625DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11626{
11627 int result;
11628
11629 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11630 if (result == -1)
11631 return NULL;
11632 return PyBool_FromLong(result);
11633}
11634
11635static PyObject *
11636DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11637{
11638 int follow_symlinks = 1;
11639
11640 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11641 follow_symlinks_keywords, &follow_symlinks))
11642 return NULL;
11643
11644 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11645}
11646
11647static PyObject *
11648DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11649{
11650 int follow_symlinks = 1;
11651
11652 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11653 follow_symlinks_keywords, &follow_symlinks))
11654 return NULL;
11655
11656 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11657}
11658
11659static PyObject *
11660DirEntry_inode(DirEntry *self)
11661{
11662#ifdef MS_WINDOWS
11663 if (!self->got_file_index) {
11664 wchar_t *path;
11665 struct _Py_stat_struct stat;
11666
11667 path = PyUnicode_AsUnicode(self->path);
11668 if (!path)
11669 return NULL;
11670
11671 if (win32_lstat_w(path, &stat) != 0) {
11672 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11673 0, self->path);
11674 }
11675
11676 self->win32_file_index = stat.st_ino;
11677 self->got_file_index = 1;
11678 }
11679 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11680#else /* POSIX */
11681#ifdef HAVE_LARGEFILE_SUPPORT
11682 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11683#else
11684 return PyLong_FromLong((long)self->d_ino);
11685#endif
11686#endif
11687}
11688
11689static PyObject *
11690DirEntry_repr(DirEntry *self)
11691{
11692 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11693}
11694
11695static PyMemberDef DirEntry_members[] = {
11696 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11697 "the entry's base filename, relative to scandir() \"path\" argument"},
11698 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11699 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11700 {NULL}
11701};
11702
11703static PyMethodDef DirEntry_methods[] = {
11704 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11705 "return True if the entry is a directory; cached per entry"
11706 },
11707 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11708 "return True if the entry is a file; cached per entry"
11709 },
11710 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11711 "return True if the entry is a symbolic link; cached per entry"
11712 },
11713 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11714 "return stat_result object for the entry; cached per entry"
11715 },
11716 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11717 "return inode of the entry; cached per entry",
11718 },
11719 {NULL}
11720};
11721
Benjamin Peterson5646de42015-04-12 17:56:34 -040011722static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011723 PyVarObject_HEAD_INIT(NULL, 0)
11724 MODNAME ".DirEntry", /* tp_name */
11725 sizeof(DirEntry), /* tp_basicsize */
11726 0, /* tp_itemsize */
11727 /* methods */
11728 (destructor)DirEntry_dealloc, /* tp_dealloc */
11729 0, /* tp_print */
11730 0, /* tp_getattr */
11731 0, /* tp_setattr */
11732 0, /* tp_compare */
11733 (reprfunc)DirEntry_repr, /* tp_repr */
11734 0, /* tp_as_number */
11735 0, /* tp_as_sequence */
11736 0, /* tp_as_mapping */
11737 0, /* tp_hash */
11738 0, /* tp_call */
11739 0, /* tp_str */
11740 0, /* tp_getattro */
11741 0, /* tp_setattro */
11742 0, /* tp_as_buffer */
11743 Py_TPFLAGS_DEFAULT, /* tp_flags */
11744 0, /* tp_doc */
11745 0, /* tp_traverse */
11746 0, /* tp_clear */
11747 0, /* tp_richcompare */
11748 0, /* tp_weaklistoffset */
11749 0, /* tp_iter */
11750 0, /* tp_iternext */
11751 DirEntry_methods, /* tp_methods */
11752 DirEntry_members, /* tp_members */
11753};
11754
11755#ifdef MS_WINDOWS
11756
11757static wchar_t *
11758join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11759{
11760 Py_ssize_t path_len;
11761 Py_ssize_t size;
11762 wchar_t *result;
11763 wchar_t ch;
11764
11765 if (!path_wide) { /* Default arg: "." */
11766 path_wide = L".";
11767 path_len = 1;
11768 }
11769 else {
11770 path_len = wcslen(path_wide);
11771 }
11772
11773 /* The +1's are for the path separator and the NUL */
11774 size = path_len + 1 + wcslen(filename) + 1;
11775 result = PyMem_New(wchar_t, size);
11776 if (!result) {
11777 PyErr_NoMemory();
11778 return NULL;
11779 }
11780 wcscpy(result, path_wide);
11781 if (path_len > 0) {
11782 ch = result[path_len - 1];
11783 if (ch != SEP && ch != ALTSEP && ch != L':')
11784 result[path_len++] = SEP;
11785 wcscpy(result + path_len, filename);
11786 }
11787 return result;
11788}
11789
11790static PyObject *
11791DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11792{
11793 DirEntry *entry;
11794 BY_HANDLE_FILE_INFORMATION file_info;
11795 ULONG reparse_tag;
11796 wchar_t *joined_path;
11797
11798 entry = PyObject_New(DirEntry, &DirEntryType);
11799 if (!entry)
11800 return NULL;
11801 entry->name = NULL;
11802 entry->path = NULL;
11803 entry->stat = NULL;
11804 entry->lstat = NULL;
11805 entry->got_file_index = 0;
11806
11807 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11808 if (!entry->name)
11809 goto error;
11810
11811 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11812 if (!joined_path)
11813 goto error;
11814
11815 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11816 PyMem_Free(joined_path);
11817 if (!entry->path)
11818 goto error;
11819
11820 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11821 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11822
11823 return (PyObject *)entry;
11824
11825error:
11826 Py_DECREF(entry);
11827 return NULL;
11828}
11829
11830#else /* POSIX */
11831
11832static char *
11833join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11834{
11835 Py_ssize_t path_len;
11836 Py_ssize_t size;
11837 char *result;
11838
11839 if (!path_narrow) { /* Default arg: "." */
11840 path_narrow = ".";
11841 path_len = 1;
11842 }
11843 else {
11844 path_len = strlen(path_narrow);
11845 }
11846
11847 if (filename_len == -1)
11848 filename_len = strlen(filename);
11849
11850 /* The +1's are for the path separator and the NUL */
11851 size = path_len + 1 + filename_len + 1;
11852 result = PyMem_New(char, size);
11853 if (!result) {
11854 PyErr_NoMemory();
11855 return NULL;
11856 }
11857 strcpy(result, path_narrow);
11858 if (path_len > 0 && result[path_len - 1] != '/')
11859 result[path_len++] = '/';
11860 strcpy(result + path_len, filename);
11861 return result;
11862}
11863
11864static PyObject *
11865DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011866 ino_t d_ino
11867#ifdef HAVE_DIRENT_D_TYPE
11868 , unsigned char d_type
11869#endif
11870 )
Victor Stinner6036e442015-03-08 01:58:04 +010011871{
11872 DirEntry *entry;
11873 char *joined_path;
11874
11875 entry = PyObject_New(DirEntry, &DirEntryType);
11876 if (!entry)
11877 return NULL;
11878 entry->name = NULL;
11879 entry->path = NULL;
11880 entry->stat = NULL;
11881 entry->lstat = NULL;
11882
11883 joined_path = join_path_filename(path->narrow, name, name_len);
11884 if (!joined_path)
11885 goto error;
11886
11887 if (!path->narrow || !PyBytes_Check(path->object)) {
11888 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11889 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11890 }
11891 else {
11892 entry->name = PyBytes_FromStringAndSize(name, name_len);
11893 entry->path = PyBytes_FromString(joined_path);
11894 }
11895 PyMem_Free(joined_path);
11896 if (!entry->name || !entry->path)
11897 goto error;
11898
Victor Stinner35a97c02015-03-08 02:59:09 +010011899#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011900 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011901#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011902 entry->d_ino = d_ino;
11903
11904 return (PyObject *)entry;
11905
11906error:
11907 Py_XDECREF(entry);
11908 return NULL;
11909}
11910
11911#endif
11912
11913
11914typedef struct {
11915 PyObject_HEAD
11916 path_t path;
11917#ifdef MS_WINDOWS
11918 HANDLE handle;
11919 WIN32_FIND_DATAW file_data;
11920 int first_time;
11921#else /* POSIX */
11922 DIR *dirp;
11923#endif
11924} ScandirIterator;
11925
11926#ifdef MS_WINDOWS
11927
11928static void
11929ScandirIterator_close(ScandirIterator *iterator)
11930{
11931 if (iterator->handle == INVALID_HANDLE_VALUE)
11932 return;
11933
11934 Py_BEGIN_ALLOW_THREADS
11935 FindClose(iterator->handle);
11936 Py_END_ALLOW_THREADS
11937 iterator->handle = INVALID_HANDLE_VALUE;
11938}
11939
11940static PyObject *
11941ScandirIterator_iternext(ScandirIterator *iterator)
11942{
11943 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11944 BOOL success;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011945 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010011946
11947 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011948 if (iterator->handle == INVALID_HANDLE_VALUE)
Victor Stinner6036e442015-03-08 01:58:04 +010011949 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010011950
11951 while (1) {
11952 if (!iterator->first_time) {
11953 Py_BEGIN_ALLOW_THREADS
11954 success = FindNextFileW(iterator->handle, file_data);
11955 Py_END_ALLOW_THREADS
11956 if (!success) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011957 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011958 if (GetLastError() != ERROR_NO_MORE_FILES)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011959 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010011960 break;
11961 }
11962 }
11963 iterator->first_time = 0;
11964
11965 /* Skip over . and .. */
11966 if (wcscmp(file_data->cFileName, L".") != 0 &&
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011967 wcscmp(file_data->cFileName, L"..") != 0) {
11968 entry = DirEntry_from_find_data(&iterator->path, file_data);
11969 if (!entry)
11970 break;
11971 return entry;
11972 }
Victor Stinner6036e442015-03-08 01:58:04 +010011973
11974 /* Loop till we get a non-dot directory or finish iterating */
11975 }
11976
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020011977 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010011978 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010011979 return NULL;
11980}
11981
11982#else /* POSIX */
11983
11984static void
11985ScandirIterator_close(ScandirIterator *iterator)
11986{
11987 if (!iterator->dirp)
11988 return;
11989
11990 Py_BEGIN_ALLOW_THREADS
11991 closedir(iterator->dirp);
11992 Py_END_ALLOW_THREADS
11993 iterator->dirp = NULL;
11994 return;
11995}
11996
11997static PyObject *
11998ScandirIterator_iternext(ScandirIterator *iterator)
11999{
12000 struct dirent *direntp;
12001 Py_ssize_t name_len;
12002 int is_dot;
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012003 PyObject *entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012004
12005 /* Happens if the iterator is iterated twice */
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012006 if (!iterator->dirp)
Victor Stinner6036e442015-03-08 01:58:04 +010012007 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010012008
12009 while (1) {
12010 errno = 0;
12011 Py_BEGIN_ALLOW_THREADS
12012 direntp = readdir(iterator->dirp);
12013 Py_END_ALLOW_THREADS
12014
12015 if (!direntp) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012016 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012017 if (errno != 0)
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012018 path_error(&iterator->path);
Victor Stinner6036e442015-03-08 01:58:04 +010012019 break;
12020 }
12021
12022 /* Skip over . and .. */
12023 name_len = NAMLEN(direntp);
12024 is_dot = direntp->d_name[0] == '.' &&
12025 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12026 if (!is_dot) {
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012027 entry = DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012028 name_len, direntp->d_ino
12029#ifdef HAVE_DIRENT_D_TYPE
12030 , direntp->d_type
12031#endif
12032 );
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012033 if (!entry)
12034 break;
12035 return entry;
Victor Stinner6036e442015-03-08 01:58:04 +010012036 }
12037
12038 /* Loop till we get a non-dot directory or finish iterating */
12039 }
12040
Serhiy Storchaka988b9bc2016-02-08 17:56:36 +020012041 /* Error or no more files */
Victor Stinner6036e442015-03-08 01:58:04 +010012042 ScandirIterator_close(iterator);
Victor Stinner6036e442015-03-08 01:58:04 +010012043 return NULL;
12044}
12045
12046#endif
12047
12048static void
12049ScandirIterator_dealloc(ScandirIterator *iterator)
12050{
12051 ScandirIterator_close(iterator);
12052 Py_XDECREF(iterator->path.object);
12053 path_cleanup(&iterator->path);
12054 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12055}
12056
Benjamin Peterson5646de42015-04-12 17:56:34 -040012057static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012058 PyVarObject_HEAD_INIT(NULL, 0)
12059 MODNAME ".ScandirIterator", /* tp_name */
12060 sizeof(ScandirIterator), /* tp_basicsize */
12061 0, /* tp_itemsize */
12062 /* methods */
12063 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12064 0, /* tp_print */
12065 0, /* tp_getattr */
12066 0, /* tp_setattr */
12067 0, /* tp_compare */
12068 0, /* tp_repr */
12069 0, /* tp_as_number */
12070 0, /* tp_as_sequence */
12071 0, /* tp_as_mapping */
12072 0, /* tp_hash */
12073 0, /* tp_call */
12074 0, /* tp_str */
12075 0, /* tp_getattro */
12076 0, /* tp_setattro */
12077 0, /* tp_as_buffer */
12078 Py_TPFLAGS_DEFAULT, /* tp_flags */
12079 0, /* tp_doc */
12080 0, /* tp_traverse */
12081 0, /* tp_clear */
12082 0, /* tp_richcompare */
12083 0, /* tp_weaklistoffset */
12084 PyObject_SelfIter, /* tp_iter */
12085 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12086};
12087
12088static PyObject *
12089posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12090{
12091 ScandirIterator *iterator;
12092 static char *keywords[] = {"path", NULL};
12093#ifdef MS_WINDOWS
12094 wchar_t *path_strW;
12095#else
12096 char *path;
12097#endif
12098
12099 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12100 if (!iterator)
12101 return NULL;
12102 memset(&iterator->path, 0, sizeof(path_t));
12103 iterator->path.function_name = "scandir";
12104 iterator->path.nullable = 1;
12105
12106#ifdef MS_WINDOWS
12107 iterator->handle = INVALID_HANDLE_VALUE;
12108#else
12109 iterator->dirp = NULL;
12110#endif
12111
12112 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12113 path_converter, &iterator->path))
12114 goto error;
12115
12116 /* path_converter doesn't keep path.object around, so do it
12117 manually for the lifetime of the iterator here (the refcount
12118 is decremented in ScandirIterator_dealloc)
12119 */
12120 Py_XINCREF(iterator->path.object);
12121
12122#ifdef MS_WINDOWS
12123 if (iterator->path.narrow) {
12124 PyErr_SetString(PyExc_TypeError,
12125 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12126 goto error;
12127 }
12128 iterator->first_time = 1;
12129
12130 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12131 if (!path_strW)
12132 goto error;
12133
12134 Py_BEGIN_ALLOW_THREADS
12135 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12136 Py_END_ALLOW_THREADS
12137
12138 PyMem_Free(path_strW);
12139
12140 if (iterator->handle == INVALID_HANDLE_VALUE) {
12141 path_error(&iterator->path);
12142 goto error;
12143 }
12144#else /* POSIX */
12145 if (iterator->path.narrow)
12146 path = iterator->path.narrow;
12147 else
12148 path = ".";
12149
12150 errno = 0;
12151 Py_BEGIN_ALLOW_THREADS
12152 iterator->dirp = opendir(path);
12153 Py_END_ALLOW_THREADS
12154
12155 if (!iterator->dirp) {
12156 path_error(&iterator->path);
12157 goto error;
12158 }
12159#endif
12160
12161 return (PyObject *)iterator;
12162
12163error:
12164 Py_DECREF(iterator);
12165 return NULL;
12166}
12167
12168
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012169#include "clinic/posixmodule.c.h"
12170
Larry Hastings7726ac92014-01-31 22:03:12 -080012171/*[clinic input]
12172dump buffer
12173[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012174/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012175
Larry Hastings31826802013-10-19 00:09:25 -070012176
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012177static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012178
12179 OS_STAT_METHODDEF
12180 OS_ACCESS_METHODDEF
12181 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012182 OS_CHDIR_METHODDEF
12183 OS_CHFLAGS_METHODDEF
12184 OS_CHMOD_METHODDEF
12185 OS_FCHMOD_METHODDEF
12186 OS_LCHMOD_METHODDEF
12187 OS_CHOWN_METHODDEF
12188 OS_FCHOWN_METHODDEF
12189 OS_LCHOWN_METHODDEF
12190 OS_LCHFLAGS_METHODDEF
12191 OS_CHROOT_METHODDEF
12192 OS_CTERMID_METHODDEF
12193 OS_GETCWD_METHODDEF
12194 OS_GETCWDB_METHODDEF
12195 OS_LINK_METHODDEF
12196 OS_LISTDIR_METHODDEF
12197 OS_LSTAT_METHODDEF
12198 OS_MKDIR_METHODDEF
12199 OS_NICE_METHODDEF
12200 OS_GETPRIORITY_METHODDEF
12201 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012202#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012203 {"readlink", (PyCFunction)posix_readlink,
12204 METH_VARARGS | METH_KEYWORDS,
12205 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012206#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012207#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012208 {"readlink", (PyCFunction)win_readlink,
12209 METH_VARARGS | METH_KEYWORDS,
12210 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012211#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012212 OS_RENAME_METHODDEF
12213 OS_REPLACE_METHODDEF
12214 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012215 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012216 OS_SYMLINK_METHODDEF
12217 OS_SYSTEM_METHODDEF
12218 OS_UMASK_METHODDEF
12219 OS_UNAME_METHODDEF
12220 OS_UNLINK_METHODDEF
12221 OS_REMOVE_METHODDEF
12222 OS_UTIME_METHODDEF
12223 OS_TIMES_METHODDEF
12224 OS__EXIT_METHODDEF
12225 OS_EXECV_METHODDEF
12226 OS_EXECVE_METHODDEF
12227 OS_SPAWNV_METHODDEF
12228 OS_SPAWNVE_METHODDEF
12229 OS_FORK1_METHODDEF
12230 OS_FORK_METHODDEF
12231 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12232 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12233 OS_SCHED_GETPARAM_METHODDEF
12234 OS_SCHED_GETSCHEDULER_METHODDEF
12235 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12236 OS_SCHED_SETPARAM_METHODDEF
12237 OS_SCHED_SETSCHEDULER_METHODDEF
12238 OS_SCHED_YIELD_METHODDEF
12239 OS_SCHED_SETAFFINITY_METHODDEF
12240 OS_SCHED_GETAFFINITY_METHODDEF
12241 OS_OPENPTY_METHODDEF
12242 OS_FORKPTY_METHODDEF
12243 OS_GETEGID_METHODDEF
12244 OS_GETEUID_METHODDEF
12245 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012246#ifdef HAVE_GETGROUPLIST
12247 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12248#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012249 OS_GETGROUPS_METHODDEF
12250 OS_GETPID_METHODDEF
12251 OS_GETPGRP_METHODDEF
12252 OS_GETPPID_METHODDEF
12253 OS_GETUID_METHODDEF
12254 OS_GETLOGIN_METHODDEF
12255 OS_KILL_METHODDEF
12256 OS_KILLPG_METHODDEF
12257 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012258#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012259 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012260#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012261 OS_SETUID_METHODDEF
12262 OS_SETEUID_METHODDEF
12263 OS_SETREUID_METHODDEF
12264 OS_SETGID_METHODDEF
12265 OS_SETEGID_METHODDEF
12266 OS_SETREGID_METHODDEF
12267 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012268#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012269 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012270#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012271 OS_GETPGID_METHODDEF
12272 OS_SETPGRP_METHODDEF
12273 OS_WAIT_METHODDEF
12274 OS_WAIT3_METHODDEF
12275 OS_WAIT4_METHODDEF
12276 OS_WAITID_METHODDEF
12277 OS_WAITPID_METHODDEF
12278 OS_GETSID_METHODDEF
12279 OS_SETSID_METHODDEF
12280 OS_SETPGID_METHODDEF
12281 OS_TCGETPGRP_METHODDEF
12282 OS_TCSETPGRP_METHODDEF
12283 OS_OPEN_METHODDEF
12284 OS_CLOSE_METHODDEF
12285 OS_CLOSERANGE_METHODDEF
12286 OS_DEVICE_ENCODING_METHODDEF
12287 OS_DUP_METHODDEF
12288 OS_DUP2_METHODDEF
12289 OS_LOCKF_METHODDEF
12290 OS_LSEEK_METHODDEF
12291 OS_READ_METHODDEF
12292 OS_READV_METHODDEF
12293 OS_PREAD_METHODDEF
12294 OS_WRITE_METHODDEF
12295 OS_WRITEV_METHODDEF
12296 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012297#ifdef HAVE_SENDFILE
12298 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12299 posix_sendfile__doc__},
12300#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012301 OS_FSTAT_METHODDEF
12302 OS_ISATTY_METHODDEF
12303 OS_PIPE_METHODDEF
12304 OS_PIPE2_METHODDEF
12305 OS_MKFIFO_METHODDEF
12306 OS_MKNOD_METHODDEF
12307 OS_MAJOR_METHODDEF
12308 OS_MINOR_METHODDEF
12309 OS_MAKEDEV_METHODDEF
12310 OS_FTRUNCATE_METHODDEF
12311 OS_TRUNCATE_METHODDEF
12312 OS_POSIX_FALLOCATE_METHODDEF
12313 OS_POSIX_FADVISE_METHODDEF
12314 OS_PUTENV_METHODDEF
12315 OS_UNSETENV_METHODDEF
12316 OS_STRERROR_METHODDEF
12317 OS_FCHDIR_METHODDEF
12318 OS_FSYNC_METHODDEF
12319 OS_SYNC_METHODDEF
12320 OS_FDATASYNC_METHODDEF
12321 OS_WCOREDUMP_METHODDEF
12322 OS_WIFCONTINUED_METHODDEF
12323 OS_WIFSTOPPED_METHODDEF
12324 OS_WIFSIGNALED_METHODDEF
12325 OS_WIFEXITED_METHODDEF
12326 OS_WEXITSTATUS_METHODDEF
12327 OS_WTERMSIG_METHODDEF
12328 OS_WSTOPSIG_METHODDEF
12329 OS_FSTATVFS_METHODDEF
12330 OS_STATVFS_METHODDEF
12331 OS_CONFSTR_METHODDEF
12332 OS_SYSCONF_METHODDEF
12333 OS_FPATHCONF_METHODDEF
12334 OS_PATHCONF_METHODDEF
12335 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012336 OS__GETFULLPATHNAME_METHODDEF
12337 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012338 OS__GETDISKUSAGE_METHODDEF
12339 OS__GETFINALPATHNAME_METHODDEF
12340 OS__GETVOLUMEPATHNAME_METHODDEF
12341 OS_GETLOADAVG_METHODDEF
12342 OS_URANDOM_METHODDEF
12343 OS_SETRESUID_METHODDEF
12344 OS_SETRESGID_METHODDEF
12345 OS_GETRESUID_METHODDEF
12346 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012347
Larry Hastings2f936352014-08-05 14:04:04 +100012348 OS_GETXATTR_METHODDEF
12349 OS_SETXATTR_METHODDEF
12350 OS_REMOVEXATTR_METHODDEF
12351 OS_LISTXATTR_METHODDEF
12352
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012353#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12354 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12355#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012356 OS_CPU_COUNT_METHODDEF
12357 OS_GET_INHERITABLE_METHODDEF
12358 OS_SET_INHERITABLE_METHODDEF
12359 OS_GET_HANDLE_INHERITABLE_METHODDEF
12360 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012361#ifndef MS_WINDOWS
12362 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12363 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12364#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012365 {"scandir", (PyCFunction)posix_scandir,
12366 METH_VARARGS | METH_KEYWORDS,
12367 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012368 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012369};
12370
12371
Brian Curtin52173d42010-12-02 18:29:18 +000012372#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012373static int
Brian Curtin52173d42010-12-02 18:29:18 +000012374enable_symlink()
12375{
12376 HANDLE tok;
12377 TOKEN_PRIVILEGES tok_priv;
12378 LUID luid;
12379 int meth_idx = 0;
12380
12381 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012382 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012383
12384 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012385 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012386
12387 tok_priv.PrivilegeCount = 1;
12388 tok_priv.Privileges[0].Luid = luid;
12389 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12390
12391 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12392 sizeof(TOKEN_PRIVILEGES),
12393 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012394 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012395
Brian Curtin3b4499c2010-12-28 14:31:47 +000012396 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12397 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012398}
12399#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12400
Barry Warsaw4a342091996-12-19 23:50:02 +000012401static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012402all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012403{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012404#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012405 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012406#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012407#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012408 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012409#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012410#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012411 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012412#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012413#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012414 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012415#endif
Fred Drakec9680921999-12-13 16:37:25 +000012416#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012417 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012418#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012419#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012420 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012421#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012422#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012423 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012424#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012425#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012426 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012427#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012428#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012429 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012430#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012431#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012432 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012433#endif
12434#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012435 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012436#endif
12437#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012438 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012439#endif
12440#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012441 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012442#endif
12443#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012444 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012445#endif
12446#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012447 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012448#endif
12449#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012450 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012451#endif
12452#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012453 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012454#endif
12455#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012456 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012457#endif
12458#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012459 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012460#endif
12461#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012462 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012463#endif
12464#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012465 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012466#endif
12467#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012468 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012469#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012470#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012471 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012472#endif
12473#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012474 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012475#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012476#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012477 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012478#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012479#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012480 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012481#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012482#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012483 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012484#endif
12485#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012486 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012487#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012488#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012489 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012490#endif
12491#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012492 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012493#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012494#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012495 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012496#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012497#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012498 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012499#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012500#ifdef O_TMPFILE
12501 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12502#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012503#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012504 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012505#endif
12506#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012507 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012508#endif
12509#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012510 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012511#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012512#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012513 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012514#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012515#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012516 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012517#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012518
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012519
Jesus Cea94363612012-06-22 18:32:07 +020012520#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012521 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012522#endif
12523#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012524 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012525#endif
12526
Tim Peters5aa91602002-01-30 05:46:57 +000012527/* MS Windows */
12528#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012529 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012531#endif
12532#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012533 /* Optimize for short life (keep in memory). */
12534 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012535 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012536#endif
12537#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012538 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012539 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012540#endif
12541#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012542 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012543 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012544#endif
12545#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012546 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012547 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012548#endif
12549
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012550/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012551#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012552 /* Send a SIGIO signal whenever input or output
12553 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012555#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012556#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012557 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012558 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012559#endif
12560#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012561 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012562 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012563#endif
12564#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012565 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012567#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012568#ifdef O_NOLINKS
12569 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012570 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012571#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012572#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012573 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012574 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012575#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012576
Victor Stinner8c62be82010-05-06 00:08:46 +000012577 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012578#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012579 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012580#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012581#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012582 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012583#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012584#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012585 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012586#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012587#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012588 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012589#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012590#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012591 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012592#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012593#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012594 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012595#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012596#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012597 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012598#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012599#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012600 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012601#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012602#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012603 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012604#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012605#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012606 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012607#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012608#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012609 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012610#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012611#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012612 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012613#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012614#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012615 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012616#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012617#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012618 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012619#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012620#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012621 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012622#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012623#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012624 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012625#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012626#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012627 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012628#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012629
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012630 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012631#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012632 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012633#endif /* ST_RDONLY */
12634#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012635 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012636#endif /* ST_NOSUID */
12637
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012638 /* GNU extensions */
12639#ifdef ST_NODEV
12640 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12641#endif /* ST_NODEV */
12642#ifdef ST_NOEXEC
12643 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12644#endif /* ST_NOEXEC */
12645#ifdef ST_SYNCHRONOUS
12646 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12647#endif /* ST_SYNCHRONOUS */
12648#ifdef ST_MANDLOCK
12649 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12650#endif /* ST_MANDLOCK */
12651#ifdef ST_WRITE
12652 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12653#endif /* ST_WRITE */
12654#ifdef ST_APPEND
12655 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12656#endif /* ST_APPEND */
12657#ifdef ST_NOATIME
12658 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12659#endif /* ST_NOATIME */
12660#ifdef ST_NODIRATIME
12661 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12662#endif /* ST_NODIRATIME */
12663#ifdef ST_RELATIME
12664 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12665#endif /* ST_RELATIME */
12666
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012667 /* FreeBSD sendfile() constants */
12668#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012669 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012670#endif
12671#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012673#endif
12674#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012675 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012676#endif
12677
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678 /* constants for posix_fadvise */
12679#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697
12698 /* constants for waitid */
12699#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12701 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12702 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012703#endif
12704#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012705 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012706#endif
12707#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012708 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012709#endif
12710#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012711 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012712#endif
12713#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012714 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012715#endif
12716#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012717 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012718#endif
12719#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012720 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012721#endif
12722#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012723 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012724#endif
12725
12726 /* constants for lockf */
12727#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012729#endif
12730#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012732#endif
12733#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012735#endif
12736#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012738#endif
12739
Guido van Rossum246bc171999-02-01 23:54:31 +000012740#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012741 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12742 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12743 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12744 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12745 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012746#endif
12747
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012748#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012749 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12750 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12751 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012752#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012753 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012754#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012755#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012756 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012757#endif
12758#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012759 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012760#endif
12761#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012762 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012763#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012764#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012765 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012766#endif
12767#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012768 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012769#endif
12770#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012771 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012772#endif
12773#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012774 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012775#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012776#endif
12777
Benjamin Peterson9428d532011-09-14 11:45:52 -040012778#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012779 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12780 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12781 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012782#endif
12783
Victor Stinner8b905bd2011-10-25 13:34:04 +020012784#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012785 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012786#endif
12787#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012788 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012789#endif
12790#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012791 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012792#endif
12793#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012794 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012795#endif
12796#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012797 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012798#endif
12799#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012800 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012801#endif
12802#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012803 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012804#endif
12805
Victor Stinner8c62be82010-05-06 00:08:46 +000012806 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012807}
12808
12809
Martin v. Löwis1a214512008-06-11 05:26:20 +000012810static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012811 PyModuleDef_HEAD_INIT,
12812 MODNAME,
12813 posix__doc__,
12814 -1,
12815 posix_methods,
12816 NULL,
12817 NULL,
12818 NULL,
12819 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012820};
12821
12822
Larry Hastings9cf065c2012-06-22 16:30:09 -070012823static char *have_functions[] = {
12824
12825#ifdef HAVE_FACCESSAT
12826 "HAVE_FACCESSAT",
12827#endif
12828
12829#ifdef HAVE_FCHDIR
12830 "HAVE_FCHDIR",
12831#endif
12832
12833#ifdef HAVE_FCHMOD
12834 "HAVE_FCHMOD",
12835#endif
12836
12837#ifdef HAVE_FCHMODAT
12838 "HAVE_FCHMODAT",
12839#endif
12840
12841#ifdef HAVE_FCHOWN
12842 "HAVE_FCHOWN",
12843#endif
12844
Larry Hastings00964ed2013-08-12 13:49:30 -040012845#ifdef HAVE_FCHOWNAT
12846 "HAVE_FCHOWNAT",
12847#endif
12848
Larry Hastings9cf065c2012-06-22 16:30:09 -070012849#ifdef HAVE_FEXECVE
12850 "HAVE_FEXECVE",
12851#endif
12852
12853#ifdef HAVE_FDOPENDIR
12854 "HAVE_FDOPENDIR",
12855#endif
12856
Georg Brandl306336b2012-06-24 12:55:33 +020012857#ifdef HAVE_FPATHCONF
12858 "HAVE_FPATHCONF",
12859#endif
12860
Larry Hastings9cf065c2012-06-22 16:30:09 -070012861#ifdef HAVE_FSTATAT
12862 "HAVE_FSTATAT",
12863#endif
12864
12865#ifdef HAVE_FSTATVFS
12866 "HAVE_FSTATVFS",
12867#endif
12868
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012869#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012870 "HAVE_FTRUNCATE",
12871#endif
12872
Larry Hastings9cf065c2012-06-22 16:30:09 -070012873#ifdef HAVE_FUTIMENS
12874 "HAVE_FUTIMENS",
12875#endif
12876
12877#ifdef HAVE_FUTIMES
12878 "HAVE_FUTIMES",
12879#endif
12880
12881#ifdef HAVE_FUTIMESAT
12882 "HAVE_FUTIMESAT",
12883#endif
12884
12885#ifdef HAVE_LINKAT
12886 "HAVE_LINKAT",
12887#endif
12888
12889#ifdef HAVE_LCHFLAGS
12890 "HAVE_LCHFLAGS",
12891#endif
12892
12893#ifdef HAVE_LCHMOD
12894 "HAVE_LCHMOD",
12895#endif
12896
12897#ifdef HAVE_LCHOWN
12898 "HAVE_LCHOWN",
12899#endif
12900
12901#ifdef HAVE_LSTAT
12902 "HAVE_LSTAT",
12903#endif
12904
12905#ifdef HAVE_LUTIMES
12906 "HAVE_LUTIMES",
12907#endif
12908
12909#ifdef HAVE_MKDIRAT
12910 "HAVE_MKDIRAT",
12911#endif
12912
12913#ifdef HAVE_MKFIFOAT
12914 "HAVE_MKFIFOAT",
12915#endif
12916
12917#ifdef HAVE_MKNODAT
12918 "HAVE_MKNODAT",
12919#endif
12920
12921#ifdef HAVE_OPENAT
12922 "HAVE_OPENAT",
12923#endif
12924
12925#ifdef HAVE_READLINKAT
12926 "HAVE_READLINKAT",
12927#endif
12928
12929#ifdef HAVE_RENAMEAT
12930 "HAVE_RENAMEAT",
12931#endif
12932
12933#ifdef HAVE_SYMLINKAT
12934 "HAVE_SYMLINKAT",
12935#endif
12936
12937#ifdef HAVE_UNLINKAT
12938 "HAVE_UNLINKAT",
12939#endif
12940
12941#ifdef HAVE_UTIMENSAT
12942 "HAVE_UTIMENSAT",
12943#endif
12944
12945#ifdef MS_WINDOWS
12946 "MS_WINDOWS",
12947#endif
12948
12949 NULL
12950};
12951
12952
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012953PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012954INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012955{
Victor Stinner8c62be82010-05-06 00:08:46 +000012956 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012957 PyObject *list;
12958 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012959
Brian Curtin52173d42010-12-02 18:29:18 +000012960#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012961 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012962#endif
12963
Victor Stinner8c62be82010-05-06 00:08:46 +000012964 m = PyModule_Create(&posixmodule);
12965 if (m == NULL)
12966 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012967
Victor Stinner8c62be82010-05-06 00:08:46 +000012968 /* Initialize environ dictionary */
12969 v = convertenviron();
12970 Py_XINCREF(v);
12971 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12972 return NULL;
12973 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012974
Victor Stinner8c62be82010-05-06 00:08:46 +000012975 if (all_ins(m))
12976 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012977
Victor Stinner8c62be82010-05-06 00:08:46 +000012978 if (setup_confname_tables(m))
12979 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012980
Victor Stinner8c62be82010-05-06 00:08:46 +000012981 Py_INCREF(PyExc_OSError);
12982 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012983
Guido van Rossumb3d39562000-01-31 18:41:26 +000012984#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012985 if (posix_putenv_garbage == NULL)
12986 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012987#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012988
Victor Stinner8c62be82010-05-06 00:08:46 +000012989 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012990#if defined(HAVE_WAITID) && !defined(__APPLE__)
12991 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012992 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12993 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012994#endif
12995
Christian Heimes25827622013-10-12 01:27:08 +020012996 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012997 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12998 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12999 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013000 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13001 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013002 structseq_new = StatResultType.tp_new;
13003 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013004
Christian Heimes25827622013-10-12 01:27:08 +020013005 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013006 if (PyStructSequence_InitType2(&StatVFSResultType,
13007 &statvfs_result_desc) < 0)
13008 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013009#ifdef NEED_TICKS_PER_SECOND
13010# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013011 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013012# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013014# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013015 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013016# endif
13017#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013018
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013019#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013020 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013021 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13022 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013023 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013024#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013025
13026 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013027 if (PyStructSequence_InitType2(&TerminalSizeType,
13028 &TerminalSize_desc) < 0)
13029 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013030
13031 /* initialize scandir types */
13032 if (PyType_Ready(&ScandirIteratorType) < 0)
13033 return NULL;
13034 if (PyType_Ready(&DirEntryType) < 0)
13035 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013036 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013037#if defined(HAVE_WAITID) && !defined(__APPLE__)
13038 Py_INCREF((PyObject*) &WaitidResultType);
13039 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13040#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013041 Py_INCREF((PyObject*) &StatResultType);
13042 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13043 Py_INCREF((PyObject*) &StatVFSResultType);
13044 PyModule_AddObject(m, "statvfs_result",
13045 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013046
13047#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013048 Py_INCREF(&SchedParamType);
13049 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013050#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013051
Larry Hastings605a62d2012-06-24 04:33:36 -070013052 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013053 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13054 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013055 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13056
13057 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013058 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13059 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013060 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13061
Thomas Wouters477c8d52006-05-27 19:21:47 +000013062#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013063 /*
13064 * Step 2 of weak-linking support on Mac OS X.
13065 *
13066 * The code below removes functions that are not available on the
13067 * currently active platform.
13068 *
13069 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013070 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013071 * OSX 10.4.
13072 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013073#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013074 if (fstatvfs == NULL) {
13075 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13076 return NULL;
13077 }
13078 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013079#endif /* HAVE_FSTATVFS */
13080
13081#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013082 if (statvfs == NULL) {
13083 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13084 return NULL;
13085 }
13086 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013087#endif /* HAVE_STATVFS */
13088
13089# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013090 if (lchown == NULL) {
13091 if (PyObject_DelAttrString(m, "lchown") == -1) {
13092 return NULL;
13093 }
13094 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013095#endif /* HAVE_LCHOWN */
13096
13097
13098#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013099
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013100 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013101 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13102
Larry Hastings6fe20b32012-04-19 15:07:49 -070013103 billion = PyLong_FromLong(1000000000);
13104 if (!billion)
13105 return NULL;
13106
Larry Hastings9cf065c2012-06-22 16:30:09 -070013107 /* suppress "function not used" warnings */
13108 {
13109 int ignored;
13110 fd_specified("", -1);
13111 follow_symlinks_specified("", 1);
13112 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13113 dir_fd_converter(Py_None, &ignored);
13114 dir_fd_unavailable(Py_None, &ignored);
13115 }
13116
13117 /*
13118 * provide list of locally available functions
13119 * so os.py can populate support_* lists
13120 */
13121 list = PyList_New(0);
13122 if (!list)
13123 return NULL;
13124 for (trace = have_functions; *trace; trace++) {
13125 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13126 if (!unicode)
13127 return NULL;
13128 if (PyList_Append(list, unicode))
13129 return NULL;
13130 Py_DECREF(unicode);
13131 }
13132 PyModule_AddObject(m, "_have_functions", list);
13133
13134 initialized = 1;
13135
Victor Stinner8c62be82010-05-06 00:08:46 +000013136 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013137}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013138
13139#ifdef __cplusplus
13140}
13141#endif