blob: 7a2b661e610b9555aea2c4e5e519fc58425817a6 [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 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003464 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003465 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003466
Gregory P. Smith40a21602013-03-20 20:52:50 -07003467 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003469 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003470
Gregory P. Smith40a21602013-03-20 20:52:50 -07003471 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003472 po_wchars = L".";
3473 len = 1;
3474 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003475 po_wchars = path->wide;
3476 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003477 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003478 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003479 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003480 if (!wnamebuf) {
3481 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003482 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003483 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003484 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003486 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003487 if (wch != SEP && wch != ALTSEP && wch != L':')
3488 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003489 wcscpy(wnamebuf + len, L"*.*");
3490 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003491 if ((list = PyList_New(0)) == NULL) {
3492 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003493 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003494 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003495 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003496 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003497 if (hFindFile == INVALID_HANDLE_VALUE) {
3498 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003499 if (error == ERROR_FILE_NOT_FOUND)
3500 goto exit;
3501 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003502 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003503 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003504 }
3505 do {
3506 /* Skip over . and .. */
3507 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3508 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003509 v = PyUnicode_FromWideChar(wFileData.cFileName,
3510 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003512 Py_DECREF(list);
3513 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003514 break;
3515 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003516 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003517 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 Py_DECREF(list);
3519 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003520 break;
3521 }
3522 Py_DECREF(v);
3523 }
3524 Py_BEGIN_ALLOW_THREADS
3525 result = FindNextFileW(hFindFile, &wFileData);
3526 Py_END_ALLOW_THREADS
3527 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3528 it got to the end of the directory. */
3529 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003531 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003532 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003533 }
3534 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003535
Larry Hastings9cf065c2012-06-22 16:30:09 -07003536 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003537 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003538 strcpy(namebuf, path->narrow);
3539 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 if (len > 0) {
3541 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003542 if (ch != '\\' && ch != '/' && ch != ':')
3543 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003544 strcpy(namebuf + len, "*.*");
3545 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003546
Larry Hastings9cf065c2012-06-22 16:30:09 -07003547 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003548 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003549
Antoine Pitroub73caab2010-08-09 23:39:31 +00003550 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003551 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003552 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003553 if (hFindFile == INVALID_HANDLE_VALUE) {
3554 int error = GetLastError();
3555 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 goto exit;
3557 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003558 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003559 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003560 }
3561 do {
3562 /* Skip over . and .. */
3563 if (strcmp(FileData.cFileName, ".") != 0 &&
3564 strcmp(FileData.cFileName, "..") != 0) {
3565 v = PyBytes_FromString(FileData.cFileName);
3566 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003567 Py_DECREF(list);
3568 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003569 break;
3570 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003571 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003572 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 Py_DECREF(list);
3574 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003575 break;
3576 }
3577 Py_DECREF(v);
3578 }
3579 Py_BEGIN_ALLOW_THREADS
3580 result = FindNextFile(hFindFile, &FileData);
3581 Py_END_ALLOW_THREADS
3582 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3583 it got to the end of the directory. */
3584 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003585 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003586 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003587 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003588 }
3589 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003590
Larry Hastings9cf065c2012-06-22 16:30:09 -07003591exit:
3592 if (hFindFile != INVALID_HANDLE_VALUE) {
3593 if (FindClose(hFindFile) == FALSE) {
3594 if (list != NULL) {
3595 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003596 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003597 }
3598 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003599 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003600 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003601
Larry Hastings9cf065c2012-06-22 16:30:09 -07003602 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003603} /* end of _listdir_windows_no_opendir */
3604
3605#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3606
3607static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003608_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003609{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003610 PyObject *v;
3611 DIR *dirp = NULL;
3612 struct dirent *ep;
3613 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003614#ifdef HAVE_FDOPENDIR
3615 int fd = -1;
3616#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003617
Victor Stinner8c62be82010-05-06 00:08:46 +00003618 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003619#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003620 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003621 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003622 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003623 if (fd == -1)
3624 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003625
Larry Hastingsfdaea062012-06-25 04:42:23 -07003626 return_str = 1;
3627
Larry Hastings9cf065c2012-06-22 16:30:09 -07003628 Py_BEGIN_ALLOW_THREADS
3629 dirp = fdopendir(fd);
3630 Py_END_ALLOW_THREADS
3631 }
3632 else
3633#endif
3634 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003635 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003636 if (path->narrow) {
3637 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003638 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003639 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003640 }
3641 else {
3642 name = ".";
3643 return_str = 1;
3644 }
3645
Larry Hastings9cf065c2012-06-22 16:30:09 -07003646 Py_BEGIN_ALLOW_THREADS
3647 dirp = opendir(name);
3648 Py_END_ALLOW_THREADS
3649 }
3650
3651 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003652 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003653#ifdef HAVE_FDOPENDIR
3654 if (fd != -1) {
3655 Py_BEGIN_ALLOW_THREADS
3656 close(fd);
3657 Py_END_ALLOW_THREADS
3658 }
3659#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003660 goto exit;
3661 }
3662 if ((list = PyList_New(0)) == NULL) {
3663 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003664 }
3665 for (;;) {
3666 errno = 0;
3667 Py_BEGIN_ALLOW_THREADS
3668 ep = readdir(dirp);
3669 Py_END_ALLOW_THREADS
3670 if (ep == NULL) {
3671 if (errno == 0) {
3672 break;
3673 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003675 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003676 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003677 }
3678 }
3679 if (ep->d_name[0] == '.' &&
3680 (NAMLEN(ep) == 1 ||
3681 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3682 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003683 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003684 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3685 else
3686 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003687 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003688 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003689 break;
3690 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003691 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003692 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003693 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003694 break;
3695 }
3696 Py_DECREF(v);
3697 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003698
Larry Hastings9cf065c2012-06-22 16:30:09 -07003699exit:
3700 if (dirp != NULL) {
3701 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003702#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003703 if (fd > -1)
3704 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003705#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003706 closedir(dirp);
3707 Py_END_ALLOW_THREADS
3708 }
3709
Larry Hastings9cf065c2012-06-22 16:30:09 -07003710 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003711} /* end of _posix_listdir */
3712#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003713
Larry Hastings2f936352014-08-05 14:04:04 +10003714
3715/*[clinic input]
3716os.listdir
3717
3718 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3719
3720Return a list containing the names of the files in the directory.
3721
3722path can be specified as either str or bytes. If path is bytes,
3723 the filenames returned will also be bytes; in all other circumstances
3724 the filenames returned will be str.
3725If path is None, uses the path='.'.
3726On some platforms, path may also be specified as an open file descriptor;\
3727 the file descriptor must refer to a directory.
3728 If this functionality is unavailable, using it raises NotImplementedError.
3729
3730The list is in arbitrary order. It does not include the special
3731entries '.' and '..' even if they are present in the directory.
3732
3733
3734[clinic start generated code]*/
3735
Larry Hastings2f936352014-08-05 14:04:04 +10003736static PyObject *
3737os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003738/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003739{
3740#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3741 return _listdir_windows_no_opendir(path, NULL);
3742#else
3743 return _posix_listdir(path, NULL);
3744#endif
3745}
3746
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003747#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003748/* A helper function for abspath on win32 */
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003749/*[clinic input]
3750os._getfullpathname
Victor Stinnereb5657a2011-09-30 01:44:27 +02003751
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003752 path: path_t
3753 /
3754
3755[clinic start generated code]*/
3756
3757static PyObject *
3758os__getfullpathname_impl(PyModuleDef *module, path_t *path)
3759/*[clinic end generated code: output=b90b1f103b08773f input=332ed537c29d0a3e]*/
3760{
3761 if (!path->narrow)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003762 {
Victor Stinner75875072013-11-24 19:23:25 +01003763 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003764 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003765 DWORD result;
3766 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003767
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003768 result = GetFullPathNameW(path->wide,
Victor Stinner63941882011-09-29 00:42:28 +02003769 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003770 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003771 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003772 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003773 if (!woutbufp)
3774 return PyErr_NoMemory();
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003775 result = GetFullPathNameW(path->wide, result, woutbufp, &wtemp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003776 }
3777 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003778 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003779 else
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003780 v = win32_error_object("GetFullPathNameW", path->object);
Victor Stinner8c62be82010-05-06 00:08:46 +00003781 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003782 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003783 return v;
3784 }
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003785 else {
3786 char outbuf[MAX_PATH];
3787 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003788
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003789 if (!GetFullPathName(path->narrow, Py_ARRAY_LENGTH(outbuf),
3790 outbuf, &temp)) {
3791 win32_error_object("GetFullPathName", path->object);
3792 return NULL;
3793 }
3794 return PyBytes_FromString(outbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003795 }
Larry Hastings2f936352014-08-05 14:04:04 +10003796}
Brian Curtind40e6f72010-07-08 21:39:08 +00003797
Brian Curtind25aef52011-06-13 15:16:04 -05003798
Larry Hastings2f936352014-08-05 14:04:04 +10003799/*[clinic input]
3800os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003801
Larry Hastings2f936352014-08-05 14:04:04 +10003802 path: unicode
3803 /
3804
3805A helper function for samepath on windows.
3806[clinic start generated code]*/
3807
Larry Hastings2f936352014-08-05 14:04:04 +10003808static PyObject *
3809os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003810/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003811{
3812 HANDLE hFile;
3813 int buf_size;
3814 wchar_t *target_path;
3815 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003816 PyObject *result;
3817 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003818
Larry Hastings2f936352014-08-05 14:04:04 +10003819 path_wchar = PyUnicode_AsUnicode(path);
3820 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003821 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003822
Brian Curtind40e6f72010-07-08 21:39:08 +00003823 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003824 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003825 0, /* desired access */
3826 0, /* share mode */
3827 NULL, /* security attributes */
3828 OPEN_EXISTING,
3829 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3830 FILE_FLAG_BACKUP_SEMANTICS,
3831 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003832
Victor Stinnereb5657a2011-09-30 01:44:27 +02003833 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003834 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003835
3836 /* We have a good handle to the target, use it to determine the
3837 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003838 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003839
3840 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003841 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003842
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003843 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003844 if(!target_path)
3845 return PyErr_NoMemory();
3846
Steve Dower2ea51c92015-03-20 21:49:12 -07003847 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3848 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003849 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003850 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003851
3852 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003853 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003854
3855 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003856 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003857 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003858 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003859}
Brian Curtin62857742010-09-06 17:07:27 +00003860
Brian Curtin95d028f2011-06-09 09:10:38 -05003861PyDoc_STRVAR(posix__isdir__doc__,
3862"Return true if the pathname refers to an existing directory.");
3863
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003864/*[clinic input]
3865os._isdir
3866
3867 path: path_t
3868 /
3869
3870[clinic start generated code]*/
3871
Brian Curtin9c669cc2011-06-08 18:17:18 -05003872static PyObject *
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003873os__isdir_impl(PyModuleDef *module, path_t *path)
3874/*[clinic end generated code: output=f17b2d4e1994b0ff input=e794f12faab62a2a]*/
Brian Curtin9c669cc2011-06-08 18:17:18 -05003875{
Brian Curtin9c669cc2011-06-08 18:17:18 -05003876 DWORD attributes;
3877
Serhiy Storchakaf0b50152015-05-13 00:52:39 +03003878 if (!path->narrow)
3879 attributes = GetFileAttributesW(path->wide);
3880 else
3881 attributes = GetFileAttributesA(path->narrow);
Brian Curtin9c669cc2011-06-08 18:17:18 -05003882
Brian Curtin9c669cc2011-06-08 18:17:18 -05003883 if (attributes == INVALID_FILE_ATTRIBUTES)
3884 Py_RETURN_FALSE;
3885
Brian Curtin9c669cc2011-06-08 18:17:18 -05003886 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3887 Py_RETURN_TRUE;
3888 else
3889 Py_RETURN_FALSE;
3890}
Tim Golden6b528062013-08-01 12:44:00 +01003891
Tim Golden6b528062013-08-01 12:44:00 +01003892
Larry Hastings2f936352014-08-05 14:04:04 +10003893/*[clinic input]
3894os._getvolumepathname
3895
3896 path: unicode
3897
3898A helper function for ismount on Win32.
3899[clinic start generated code]*/
3900
Larry Hastings2f936352014-08-05 14:04:04 +10003901static PyObject *
3902os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003903/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003904{
3905 PyObject *result;
3906 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003907 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003908 BOOL ret;
3909
Larry Hastings2f936352014-08-05 14:04:04 +10003910 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3911 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003912 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003913 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003914
3915 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003916 buflen = Py_MAX(buflen, MAX_PATH);
3917
3918 if (buflen > DWORD_MAX) {
3919 PyErr_SetString(PyExc_OverflowError, "path too long");
3920 return NULL;
3921 }
3922
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003923 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003924 if (mountpath == NULL)
3925 return PyErr_NoMemory();
3926
3927 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003928 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003929 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003930 Py_END_ALLOW_THREADS
3931
3932 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003933 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003934 goto exit;
3935 }
3936 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3937
3938exit:
3939 PyMem_Free(mountpath);
3940 return result;
3941}
Tim Golden6b528062013-08-01 12:44:00 +01003942
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003943#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003944
Larry Hastings2f936352014-08-05 14:04:04 +10003945
3946/*[clinic input]
3947os.mkdir
3948
3949 path : path_t
3950
3951 mode: int = 0o777
3952
3953 *
3954
3955 dir_fd : dir_fd(requires='mkdirat') = None
3956
3957# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3958
3959Create a directory.
3960
3961If dir_fd is not None, it should be a file descriptor open to a directory,
3962 and path should be relative; path will then be relative to that directory.
3963dir_fd may not be implemented on your platform.
3964 If it is unavailable, using it will raise a NotImplementedError.
3965
3966The mode argument is ignored on Windows.
3967[clinic start generated code]*/
3968
Larry Hastings2f936352014-08-05 14:04:04 +10003969static PyObject *
3970os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003971/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003972{
3973 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003974
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003975#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003976 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003977 if (path->wide)
3978 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 else
Larry Hastings2f936352014-08-05 14:04:04 +10003980 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003981 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003982
Larry Hastings2f936352014-08-05 14:04:04 +10003983 if (!result)
3984 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003985#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003986 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003987#if HAVE_MKDIRAT
3988 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003989 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003990 else
3991#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003992#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003993 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003994#else
Larry Hastings2f936352014-08-05 14:04:04 +10003995 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003996#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003997 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003998 if (result < 0)
3999 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00004000#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004001 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004002}
4003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004004
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004005/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
4006#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004007#include <sys/resource.h>
4008#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004009
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00004010
4011#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004012/*[clinic input]
4013os.nice
4014
4015 increment: int
4016 /
4017
4018Add increment to the priority of process and return the new priority.
4019[clinic start generated code]*/
4020
Larry Hastings2f936352014-08-05 14:04:04 +10004021static PyObject *
4022os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004023/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004024{
4025 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004026
Victor Stinner8c62be82010-05-06 00:08:46 +00004027 /* There are two flavours of 'nice': one that returns the new
4028 priority (as required by almost all standards out there) and the
4029 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4030 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004031
Victor Stinner8c62be82010-05-06 00:08:46 +00004032 If we are of the nice family that returns the new priority, we
4033 need to clear errno before the call, and check if errno is filled
4034 before calling posix_error() on a returnvalue of -1, because the
4035 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004036
Victor Stinner8c62be82010-05-06 00:08:46 +00004037 errno = 0;
4038 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004039#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004040 if (value == 0)
4041 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004042#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004043 if (value == -1 && errno != 0)
4044 /* either nice() or getpriority() returned an error */
4045 return posix_error();
4046 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004047}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004048#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004049
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004050
4051#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004052/*[clinic input]
4053os.getpriority
4054
4055 which: int
4056 who: int
4057
4058Return program scheduling priority.
4059[clinic start generated code]*/
4060
Larry Hastings2f936352014-08-05 14:04:04 +10004061static PyObject *
4062os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004063/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004064{
4065 int retval;
4066
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004067 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004068 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004069 if (errno != 0)
4070 return posix_error();
4071 return PyLong_FromLong((long)retval);
4072}
4073#endif /* HAVE_GETPRIORITY */
4074
4075
4076#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004077/*[clinic input]
4078os.setpriority
4079
4080 which: int
4081 who: int
4082 priority: int
4083
4084Set program scheduling priority.
4085[clinic start generated code]*/
4086
Larry Hastings2f936352014-08-05 14:04:04 +10004087static PyObject *
4088os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004089/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004090{
4091 int retval;
4092
4093 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004094 if (retval == -1)
4095 return posix_error();
4096 Py_RETURN_NONE;
4097}
4098#endif /* HAVE_SETPRIORITY */
4099
4100
Barry Warsaw53699e91996-12-10 23:23:01 +00004101static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004102internal_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 +00004103{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004104 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004105 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004106
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004107#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004108 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004109 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004110#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004111 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004112#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113
Larry Hastings9cf065c2012-06-22 16:30:09 -07004114 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4115 (dst_dir_fd != DEFAULT_DIR_FD);
4116#ifndef HAVE_RENAMEAT
4117 if (dir_fd_specified) {
4118 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004119 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004120 }
4121#endif
4122
Larry Hastings2f936352014-08-05 14:04:04 +10004123 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 PyErr_Format(PyExc_ValueError,
4125 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004126 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004127 }
4128
4129#ifdef MS_WINDOWS
4130 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004131 if (src->wide)
4132 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004133 else
Larry Hastings2f936352014-08-05 14:04:04 +10004134 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004135 Py_END_ALLOW_THREADS
4136
Larry Hastings2f936352014-08-05 14:04:04 +10004137 if (!result)
4138 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004139
4140#else
4141 Py_BEGIN_ALLOW_THREADS
4142#ifdef HAVE_RENAMEAT
4143 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004144 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004145 else
4146#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004147 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004148 Py_END_ALLOW_THREADS
4149
Larry Hastings2f936352014-08-05 14:04:04 +10004150 if (result)
4151 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004152#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004153 Py_RETURN_NONE;
4154}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004155
Larry Hastings2f936352014-08-05 14:04:04 +10004156
4157/*[clinic input]
4158os.rename
4159
4160 src : path_t
4161 dst : path_t
4162 *
4163 src_dir_fd : dir_fd = None
4164 dst_dir_fd : dir_fd = None
4165
4166Rename a file or directory.
4167
4168If either src_dir_fd or dst_dir_fd is not None, it should be a file
4169 descriptor open to a directory, and the respective path string (src or dst)
4170 should be relative; the path will then be relative to that directory.
4171src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4172 If they are unavailable, using them will raise a NotImplementedError.
4173[clinic start generated code]*/
4174
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004175static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004176os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd,
4177 int dst_dir_fd)
4178/*[clinic end generated code: output=08033bb2ec27fb5f input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004179{
Larry Hastings2f936352014-08-05 14:04:04 +10004180 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004181}
4182
Larry Hastings2f936352014-08-05 14:04:04 +10004183
4184/*[clinic input]
4185os.replace = os.rename
4186
4187Rename a file or directory, overwriting the destination.
4188
4189If either src_dir_fd or dst_dir_fd is not None, it should be a file
4190 descriptor open to a directory, and the respective path string (src or dst)
4191 should be relative; the path will then be relative to that directory.
4192src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4193 If they are unavailable, using them will raise a NotImplementedError."
4194[clinic start generated code]*/
4195
Larry Hastings2f936352014-08-05 14:04:04 +10004196static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004197os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst,
4198 int src_dir_fd, int dst_dir_fd)
4199/*[clinic end generated code: output=131d012eed8d3b8b input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004200{
4201 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4202}
4203
4204
4205/*[clinic input]
4206os.rmdir
4207
4208 path: path_t
4209 *
4210 dir_fd: dir_fd(requires='unlinkat') = None
4211
4212Remove a directory.
4213
4214If dir_fd is not None, it should be a file descriptor open to a directory,
4215 and path should be relative; path will then be relative to that directory.
4216dir_fd may not be implemented on your platform.
4217 If it is unavailable, using it will raise a NotImplementedError.
4218[clinic start generated code]*/
4219
Larry Hastings2f936352014-08-05 14:04:04 +10004220static PyObject *
4221os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004222/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004223{
4224 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004225
4226 Py_BEGIN_ALLOW_THREADS
4227#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004228 if (path->wide)
4229 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004230 else
Larry Hastings2f936352014-08-05 14:04:04 +10004231 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004232 result = !result; /* Windows, success=1, UNIX, success=0 */
4233#else
4234#ifdef HAVE_UNLINKAT
4235 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004236 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004237 else
4238#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004239 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004240#endif
4241 Py_END_ALLOW_THREADS
4242
Larry Hastings2f936352014-08-05 14:04:04 +10004243 if (result)
4244 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004245
Larry Hastings2f936352014-08-05 14:04:04 +10004246 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004247}
4248
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004249
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004250#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004251#ifdef MS_WINDOWS
4252/*[clinic input]
4253os.system -> long
4254
4255 command: Py_UNICODE
4256
4257Execute the command in a subshell.
4258[clinic start generated code]*/
4259
Larry Hastings2f936352014-08-05 14:04:04 +10004260static long
4261os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004262/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004263{
4264 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004265 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004266 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004267 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004268 return result;
4269}
4270#else /* MS_WINDOWS */
4271/*[clinic input]
4272os.system -> long
4273
4274 command: FSConverter
4275
4276Execute the command in a subshell.
4277[clinic start generated code]*/
4278
Larry Hastings2f936352014-08-05 14:04:04 +10004279static long
4280os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004281/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004282{
4283 long result;
4284 char *bytes = PyBytes_AsString(command);
4285 Py_BEGIN_ALLOW_THREADS
4286 result = system(bytes);
4287 Py_END_ALLOW_THREADS
4288 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004289}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004290#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004291#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004292
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004293
Larry Hastings2f936352014-08-05 14:04:04 +10004294/*[clinic input]
4295os.umask
4296
4297 mask: int
4298 /
4299
4300Set the current numeric umask and return the previous umask.
4301[clinic start generated code]*/
4302
Larry Hastings2f936352014-08-05 14:04:04 +10004303static PyObject *
4304os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004305/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004306{
4307 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004308 if (i < 0)
4309 return posix_error();
4310 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004311}
4312
Brian Curtind40e6f72010-07-08 21:39:08 +00004313#ifdef MS_WINDOWS
4314
4315/* override the default DeleteFileW behavior so that directory
4316symlinks can be removed with this function, the same as with
4317Unix symlinks */
4318BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4319{
4320 WIN32_FILE_ATTRIBUTE_DATA info;
4321 WIN32_FIND_DATAW find_data;
4322 HANDLE find_data_handle;
4323 int is_directory = 0;
4324 int is_link = 0;
4325
4326 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4327 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004328
Brian Curtind40e6f72010-07-08 21:39:08 +00004329 /* Get WIN32_FIND_DATA structure for the path to determine if
4330 it is a symlink */
4331 if(is_directory &&
4332 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4333 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4334
4335 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004336 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4337 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4338 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4339 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004340 FindClose(find_data_handle);
4341 }
4342 }
4343 }
4344
4345 if (is_directory && is_link)
4346 return RemoveDirectoryW(lpFileName);
4347
4348 return DeleteFileW(lpFileName);
4349}
4350#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004351
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004352
Larry Hastings2f936352014-08-05 14:04:04 +10004353/*[clinic input]
4354os.unlink
4355
4356 path: path_t
4357 *
4358 dir_fd: dir_fd(requires='unlinkat')=None
4359
4360Remove a file (same as remove()).
4361
4362If dir_fd is not None, it should be a file descriptor open to a directory,
4363 and path should be relative; path will then be relative to that directory.
4364dir_fd may not be implemented on your platform.
4365 If it is unavailable, using it will raise a NotImplementedError.
4366
4367[clinic start generated code]*/
4368
Larry Hastings2f936352014-08-05 14:04:04 +10004369static PyObject *
4370os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004371/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004372{
4373 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374
4375 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004376 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004378 if (path->wide)
4379 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004380 else
Larry Hastings2f936352014-08-05 14:04:04 +10004381 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004382 result = !result; /* Windows, success=1, UNIX, success=0 */
4383#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004384#ifdef HAVE_UNLINKAT
4385 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004386 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004387 else
4388#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004389 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004390#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004391 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004392 Py_END_ALLOW_THREADS
4393
Larry Hastings2f936352014-08-05 14:04:04 +10004394 if (result)
4395 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004396
Larry Hastings2f936352014-08-05 14:04:04 +10004397 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004398}
4399
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004400
Larry Hastings2f936352014-08-05 14:04:04 +10004401/*[clinic input]
4402os.remove = os.unlink
4403
4404Remove a file (same as unlink()).
4405
4406If dir_fd is not None, it should be a file descriptor open to a directory,
4407 and path should be relative; path will then be relative to that directory.
4408dir_fd may not be implemented on your platform.
4409 If it is unavailable, using it will raise a NotImplementedError.
4410[clinic start generated code]*/
4411
Larry Hastings2f936352014-08-05 14:04:04 +10004412static PyObject *
4413os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004414/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004415{
4416 return os_unlink_impl(module, path, dir_fd);
4417}
4418
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004419
Larry Hastings605a62d2012-06-24 04:33:36 -07004420static PyStructSequence_Field uname_result_fields[] = {
4421 {"sysname", "operating system name"},
4422 {"nodename", "name of machine on network (implementation-defined)"},
4423 {"release", "operating system release"},
4424 {"version", "operating system version"},
4425 {"machine", "hardware identifier"},
4426 {NULL}
4427};
4428
4429PyDoc_STRVAR(uname_result__doc__,
4430"uname_result: Result from os.uname().\n\n\
4431This object may be accessed either as a tuple of\n\
4432 (sysname, nodename, release, version, machine),\n\
4433or via the attributes sysname, nodename, release, version, and machine.\n\
4434\n\
4435See os.uname for more information.");
4436
4437static PyStructSequence_Desc uname_result_desc = {
4438 "uname_result", /* name */
4439 uname_result__doc__, /* doc */
4440 uname_result_fields,
4441 5
4442};
4443
4444static PyTypeObject UnameResultType;
4445
4446
4447#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004448/*[clinic input]
4449os.uname
4450
4451Return an object identifying the current operating system.
4452
4453The object behaves like a named tuple with the following fields:
4454 (sysname, nodename, release, version, machine)
4455
4456[clinic start generated code]*/
4457
Larry Hastings2f936352014-08-05 14:04:04 +10004458static PyObject *
4459os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004460/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004461{
Victor Stinner8c62be82010-05-06 00:08:46 +00004462 struct utsname u;
4463 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004464 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004465
Victor Stinner8c62be82010-05-06 00:08:46 +00004466 Py_BEGIN_ALLOW_THREADS
4467 res = uname(&u);
4468 Py_END_ALLOW_THREADS
4469 if (res < 0)
4470 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004471
4472 value = PyStructSequence_New(&UnameResultType);
4473 if (value == NULL)
4474 return NULL;
4475
4476#define SET(i, field) \
4477 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004478 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004479 if (!o) { \
4480 Py_DECREF(value); \
4481 return NULL; \
4482 } \
4483 PyStructSequence_SET_ITEM(value, i, o); \
4484 } \
4485
4486 SET(0, u.sysname);
4487 SET(1, u.nodename);
4488 SET(2, u.release);
4489 SET(3, u.version);
4490 SET(4, u.machine);
4491
4492#undef SET
4493
4494 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004495}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004496#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004497
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004498
Larry Hastings9cf065c2012-06-22 16:30:09 -07004499
4500typedef struct {
4501 int now;
4502 time_t atime_s;
4503 long atime_ns;
4504 time_t mtime_s;
4505 long mtime_ns;
4506} utime_t;
4507
4508/*
Victor Stinner484df002014-10-09 13:52:31 +02004509 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004510 * they also intentionally leak the declaration of a pointer named "time"
4511 */
4512#define UTIME_TO_TIMESPEC \
4513 struct timespec ts[2]; \
4514 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004515 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004516 time = NULL; \
4517 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004518 ts[0].tv_sec = ut->atime_s; \
4519 ts[0].tv_nsec = ut->atime_ns; \
4520 ts[1].tv_sec = ut->mtime_s; \
4521 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522 time = ts; \
4523 } \
4524
4525#define UTIME_TO_TIMEVAL \
4526 struct timeval tv[2]; \
4527 struct timeval *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004528 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 time = NULL; \
4530 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004531 tv[0].tv_sec = ut->atime_s; \
4532 tv[0].tv_usec = ut->atime_ns / 1000; \
4533 tv[1].tv_sec = ut->mtime_s; \
4534 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004535 time = tv; \
4536 } \
4537
4538#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004539 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004541 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004542 time = NULL; \
4543 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004544 u.actime = ut->atime_s; \
4545 u.modtime = ut->mtime_s; \
4546 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004547 }
4548
4549#define UTIME_TO_TIME_T \
4550 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004551 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004552 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004553 time = NULL; \
4554 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004555 timet[0] = ut->atime_s; \
4556 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004557 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004558 } \
4559
4560
Victor Stinner528a9ab2015-09-03 21:30:26 +02004561#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004562
4563static int
Victor Stinner484df002014-10-09 13:52:31 +02004564utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004565{
4566#ifdef HAVE_UTIMENSAT
4567 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4568 UTIME_TO_TIMESPEC;
4569 return utimensat(dir_fd, path, time, flags);
4570#elif defined(HAVE_FUTIMESAT)
4571 UTIME_TO_TIMEVAL;
4572 /*
4573 * follow_symlinks will never be false here;
4574 * we only allow !follow_symlinks and dir_fd together
4575 * if we have utimensat()
4576 */
4577 assert(follow_symlinks);
4578 return futimesat(dir_fd, path, time);
4579#endif
4580}
4581
Larry Hastings2f936352014-08-05 14:04:04 +10004582 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4583#else
4584 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004585#endif
4586
Victor Stinner528a9ab2015-09-03 21:30:26 +02004587#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004588
4589static int
Victor Stinner484df002014-10-09 13:52:31 +02004590utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004591{
4592#ifdef HAVE_FUTIMENS
4593 UTIME_TO_TIMESPEC;
4594 return futimens(fd, time);
4595#else
4596 UTIME_TO_TIMEVAL;
4597 return futimes(fd, time);
4598#endif
4599}
4600
Larry Hastings2f936352014-08-05 14:04:04 +10004601 #define PATH_UTIME_HAVE_FD 1
4602#else
4603 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004604#endif
4605
Victor Stinner5ebae872015-09-22 01:29:33 +02004606#if defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES)
4607# define UTIME_HAVE_NOFOLLOW_SYMLINKS
4608#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004609
Victor Stinner4552ced2015-09-21 22:37:15 +02004610#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004611
4612static int
Victor Stinner484df002014-10-09 13:52:31 +02004613utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004614{
4615#ifdef HAVE_UTIMENSAT
4616 UTIME_TO_TIMESPEC;
4617 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4618#else
4619 UTIME_TO_TIMEVAL;
4620 return lutimes(path, time);
4621#endif
4622}
4623
4624#endif
4625
4626#ifndef MS_WINDOWS
4627
4628static int
Victor Stinner484df002014-10-09 13:52:31 +02004629utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004630{
4631#ifdef HAVE_UTIMENSAT
4632 UTIME_TO_TIMESPEC;
4633 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4634#elif defined(HAVE_UTIMES)
4635 UTIME_TO_TIMEVAL;
4636 return utimes(path, time);
4637#elif defined(HAVE_UTIME_H)
4638 UTIME_TO_UTIMBUF;
4639 return utime(path, time);
4640#else
4641 UTIME_TO_TIME_T;
4642 return utime(path, time);
4643#endif
4644}
4645
4646#endif
4647
Larry Hastings76ad59b2012-05-03 00:30:07 -07004648static int
4649split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4650{
4651 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004652 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004653 divmod = PyNumber_Divmod(py_long, billion);
4654 if (!divmod)
4655 goto exit;
4656 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4657 if ((*s == -1) && PyErr_Occurred())
4658 goto exit;
4659 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004660 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004661 goto exit;
4662
4663 result = 1;
4664exit:
4665 Py_XDECREF(divmod);
4666 return result;
4667}
4668
Larry Hastings2f936352014-08-05 14:04:04 +10004669
4670/*[clinic input]
4671os.utime
4672
4673 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4674 times: object = NULL
4675 *
4676 ns: object = NULL
4677 dir_fd: dir_fd(requires='futimensat') = None
4678 follow_symlinks: bool=True
4679
Martin Panter0ff89092015-09-09 01:56:53 +00004680# "utime(path, times=None, *[, ns], dir_fd=None, follow_symlinks=True)\n\
Larry Hastings2f936352014-08-05 14:04:04 +10004681
4682Set the access and modified time of path.
4683
4684path may always be specified as a string.
4685On some platforms, path may also be specified as an open file descriptor.
4686 If this functionality is unavailable, using it raises an exception.
4687
4688If times is not None, it must be a tuple (atime, mtime);
4689 atime and mtime should be expressed as float seconds since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004690If ns is specified, it must be a tuple (atime_ns, mtime_ns);
Larry Hastings2f936352014-08-05 14:04:04 +10004691 atime_ns and mtime_ns should be expressed as integer nanoseconds
4692 since the epoch.
Martin Panter0ff89092015-09-09 01:56:53 +00004693If times is None and ns is unspecified, utime uses the current time.
Larry Hastings2f936352014-08-05 14:04:04 +10004694Specifying tuples for both times and ns is an error.
4695
4696If dir_fd is not None, it should be a file descriptor open to a directory,
4697 and path should be relative; path will then be relative to that directory.
4698If follow_symlinks is False, and the last element of the path is a symbolic
4699 link, utime will modify the symbolic link itself instead of the file the
4700 link points to.
4701It is an error to use dir_fd or follow_symlinks when specifying path
4702 as an open file descriptor.
4703dir_fd and follow_symlinks may not be available on your platform.
4704 If they are unavailable, using them will raise a NotImplementedError.
4705
4706[clinic start generated code]*/
4707
Larry Hastings2f936352014-08-05 14:04:04 +10004708static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04004709os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times,
4710 PyObject *ns, int dir_fd, int follow_symlinks)
Martin Panter0ff89092015-09-09 01:56:53 +00004711/*[clinic end generated code: output=31f3434e560ba2f0 input=081cdc54ca685385]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004712{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004713#ifdef MS_WINDOWS
4714 HANDLE hFile;
4715 FILETIME atime, mtime;
4716#else
4717 int result;
4718#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004719
Larry Hastings9cf065c2012-06-22 16:30:09 -07004720 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004721 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004722
Christian Heimesb3c87242013-08-01 00:08:16 +02004723 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004724
Larry Hastings9cf065c2012-06-22 16:30:09 -07004725 if (times && (times != Py_None) && ns) {
4726 PyErr_SetString(PyExc_ValueError,
4727 "utime: you may specify either 'times'"
4728 " or 'ns' but not both");
4729 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730 }
4731
4732 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004733 time_t a_sec, m_sec;
4734 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004735 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 PyErr_SetString(PyExc_TypeError,
4737 "utime: 'times' must be either"
4738 " a tuple of two ints or None");
4739 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004740 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004741 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004742 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004743 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004744 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004745 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004746 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004747 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004748 utime.atime_s = a_sec;
4749 utime.atime_ns = a_nsec;
4750 utime.mtime_s = m_sec;
4751 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004752 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004754 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004755 PyErr_SetString(PyExc_TypeError,
4756 "utime: 'ns' must be a tuple of two ints");
4757 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004758 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004759 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004760 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004761 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004762 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004763 &utime.mtime_s, &utime.mtime_ns)) {
4764 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004765 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004766 }
4767 else {
4768 /* times and ns are both None/unspecified. use "now". */
4769 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004770 }
4771
Victor Stinner4552ced2015-09-21 22:37:15 +02004772#if !defined(UTIME_HAVE_NOFOLLOW_SYMLINKS)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004773 if (follow_symlinks_specified("utime", follow_symlinks))
4774 goto exit;
4775#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004776
Larry Hastings2f936352014-08-05 14:04:04 +10004777 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4778 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4779 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004780 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004781
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782#if !defined(HAVE_UTIMENSAT)
4783 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004784 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004785 "utime: cannot use dir_fd and follow_symlinks "
4786 "together on this platform");
4787 goto exit;
4788 }
4789#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004790
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004791#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004792 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004793 if (path->wide)
4794 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004795 NULL, OPEN_EXISTING,
4796 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004797 else
Larry Hastings2f936352014-08-05 14:04:04 +10004798 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004799 NULL, OPEN_EXISTING,
4800 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004801 Py_END_ALLOW_THREADS
4802 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004803 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004804 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004805 }
4806
Larry Hastings9cf065c2012-06-22 16:30:09 -07004807 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004808 GetSystemTimeAsFileTime(&mtime);
4809 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004810 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004811 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004812 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4813 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004814 }
4815 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4816 /* Avoid putting the file name into the error here,
4817 as that may confuse the user into believing that
4818 something is wrong with the file, when it also
4819 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004820 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004822 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004823#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004824 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004825
Victor Stinner4552ced2015-09-21 22:37:15 +02004826#ifdef UTIME_HAVE_NOFOLLOW_SYMLINKS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004827 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004828 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004829 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004830#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831
Victor Stinner528a9ab2015-09-03 21:30:26 +02004832#if defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004833 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004834 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835 else
4836#endif
4837
Victor Stinner528a9ab2015-09-03 21:30:26 +02004838#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS)
Larry Hastings2f936352014-08-05 14:04:04 +10004839 if (path->fd != -1)
4840 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004841 else
4842#endif
4843
Larry Hastings2f936352014-08-05 14:04:04 +10004844 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845
4846 Py_END_ALLOW_THREADS
4847
4848 if (result < 0) {
4849 /* see previous comment about not putting filename in error here */
4850 return_value = posix_error();
4851 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004852 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004853
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004854#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004855
4856 Py_INCREF(Py_None);
4857 return_value = Py_None;
4858
4859exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004860#ifdef MS_WINDOWS
4861 if (hFile != INVALID_HANDLE_VALUE)
4862 CloseHandle(hFile);
4863#endif
4864 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004865}
4866
Guido van Rossum3b066191991-06-04 19:40:25 +00004867/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004868
Larry Hastings2f936352014-08-05 14:04:04 +10004869
4870/*[clinic input]
4871os._exit
4872
4873 status: int
4874
4875Exit to the system with specified status, without normal exit processing.
4876[clinic start generated code]*/
4877
Larry Hastings2f936352014-08-05 14:04:04 +10004878static PyObject *
4879os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004880/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004881{
4882 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004883 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004884}
4885
Martin v. Löwis114619e2002-10-07 06:44:21 +00004886#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4887static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004888free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004889{
Victor Stinner8c62be82010-05-06 00:08:46 +00004890 Py_ssize_t i;
4891 for (i = 0; i < count; i++)
4892 PyMem_Free(array[i]);
4893 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004894}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004895
Antoine Pitrou69f71142009-05-24 21:25:49 +00004896static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004897int fsconvert_strdup(PyObject *o, char**out)
4898{
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 PyObject *bytes;
4900 Py_ssize_t size;
4901 if (!PyUnicode_FSConverter(o, &bytes))
4902 return 0;
4903 size = PyBytes_GET_SIZE(bytes);
4904 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004905 if (!*out) {
4906 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004907 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004908 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 memcpy(*out, PyBytes_AsString(bytes), size+1);
4910 Py_DECREF(bytes);
4911 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004912}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004913#endif
4914
Ross Lagerwall7807c352011-03-17 20:20:30 +02004915#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004916static char**
4917parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4918{
Victor Stinner8c62be82010-05-06 00:08:46 +00004919 char **envlist;
4920 Py_ssize_t i, pos, envc;
4921 PyObject *keys=NULL, *vals=NULL;
4922 PyObject *key, *val, *key2, *val2;
4923 char *p, *k, *v;
4924 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004925
Victor Stinner8c62be82010-05-06 00:08:46 +00004926 i = PyMapping_Size(env);
4927 if (i < 0)
4928 return NULL;
4929 envlist = PyMem_NEW(char *, i + 1);
4930 if (envlist == NULL) {
4931 PyErr_NoMemory();
4932 return NULL;
4933 }
4934 envc = 0;
4935 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004936 if (!keys)
4937 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004938 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004939 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004940 goto error;
4941 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4942 PyErr_Format(PyExc_TypeError,
4943 "env.keys() or env.values() is not a list");
4944 goto error;
4945 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004946
Victor Stinner8c62be82010-05-06 00:08:46 +00004947 for (pos = 0; pos < i; pos++) {
4948 key = PyList_GetItem(keys, pos);
4949 val = PyList_GetItem(vals, pos);
4950 if (!key || !val)
4951 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004952
Victor Stinner8c62be82010-05-06 00:08:46 +00004953 if (PyUnicode_FSConverter(key, &key2) == 0)
4954 goto error;
4955 if (PyUnicode_FSConverter(val, &val2) == 0) {
4956 Py_DECREF(key2);
4957 goto error;
4958 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004959
Victor Stinner8c62be82010-05-06 00:08:46 +00004960 k = PyBytes_AsString(key2);
4961 v = PyBytes_AsString(val2);
4962 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004963
Victor Stinner8c62be82010-05-06 00:08:46 +00004964 p = PyMem_NEW(char, len);
4965 if (p == NULL) {
4966 PyErr_NoMemory();
4967 Py_DECREF(key2);
4968 Py_DECREF(val2);
4969 goto error;
4970 }
4971 PyOS_snprintf(p, len, "%s=%s", k, v);
4972 envlist[envc++] = p;
4973 Py_DECREF(key2);
4974 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004975 }
4976 Py_DECREF(vals);
4977 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004978
Victor Stinner8c62be82010-05-06 00:08:46 +00004979 envlist[envc] = 0;
4980 *envc_ptr = envc;
4981 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004982
4983error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004984 Py_XDECREF(keys);
4985 Py_XDECREF(vals);
4986 while (--envc >= 0)
4987 PyMem_DEL(envlist[envc]);
4988 PyMem_DEL(envlist);
4989 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004990}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004991
Ross Lagerwall7807c352011-03-17 20:20:30 +02004992static char**
4993parse_arglist(PyObject* argv, Py_ssize_t *argc)
4994{
4995 int i;
4996 char **argvlist = PyMem_NEW(char *, *argc+1);
4997 if (argvlist == NULL) {
4998 PyErr_NoMemory();
4999 return NULL;
5000 }
5001 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005002 PyObject* item = PySequence_ITEM(argv, i);
5003 if (item == NULL)
5004 goto fail;
5005 if (!fsconvert_strdup(item, &argvlist[i])) {
5006 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005007 goto fail;
5008 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005009 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005010 }
5011 argvlist[*argc] = NULL;
5012 return argvlist;
5013fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005014 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005015 free_string_array(argvlist, *argc);
5016 return NULL;
5017}
5018#endif
5019
Larry Hastings2f936352014-08-05 14:04:04 +10005020
Ross Lagerwall7807c352011-03-17 20:20:30 +02005021#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005022/*[clinic input]
5023os.execv
5024
5025 path: FSConverter
5026 Path of executable file.
5027 argv: object
5028 Tuple or list of strings.
5029 /
5030
5031Execute an executable path with arguments, replacing current process.
5032[clinic start generated code]*/
5033
Larry Hastings2f936352014-08-05 14:04:04 +10005034static PyObject *
5035os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005036/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005037{
5038 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005039 char **argvlist;
5040 Py_ssize_t argc;
5041
5042 /* execv has two arguments: (path, argv), where
5043 argv is a list or tuple of strings. */
5044
Larry Hastings2f936352014-08-05 14:04:04 +10005045 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005046 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5047 PyErr_SetString(PyExc_TypeError,
5048 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005049 return NULL;
5050 }
5051 argc = PySequence_Size(argv);
5052 if (argc < 1) {
5053 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005054 return NULL;
5055 }
5056
5057 argvlist = parse_arglist(argv, &argc);
5058 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005059 return NULL;
5060 }
5061
Larry Hastings2f936352014-08-05 14:04:04 +10005062 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005063
5064 /* If we get here it's definitely an error */
5065
5066 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005067 return posix_error();
5068}
5069
Larry Hastings2f936352014-08-05 14:04:04 +10005070
5071/*[clinic input]
5072os.execve
5073
5074 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5075 Path of executable file.
5076 argv: object
5077 Tuple or list of strings.
5078 env: object
5079 Dictionary of strings mapping to strings.
5080
5081Execute an executable path with arguments, replacing current process.
5082[clinic start generated code]*/
5083
Larry Hastings2f936352014-08-05 14:04:04 +10005084static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005085os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv,
5086 PyObject *env)
5087/*[clinic end generated code: output=181884fcdb21508e input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005088{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005089 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005091 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005092
Victor Stinner8c62be82010-05-06 00:08:46 +00005093 /* execve has three arguments: (path, argv, env), where
5094 argv is a list or tuple of strings and env is a dictionary
5095 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005096
Ross Lagerwall7807c352011-03-17 20:20:30 +02005097 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005098 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005099 "execve: argv must be a tuple or list");
5100 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005102 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 if (!PyMapping_Check(env)) {
5104 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005105 "execve: environment must be a mapping object");
5106 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005107 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005108
Ross Lagerwall7807c352011-03-17 20:20:30 +02005109 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005110 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005111 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005112 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005113
Victor Stinner8c62be82010-05-06 00:08:46 +00005114 envlist = parse_envlist(env, &envc);
5115 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005116 goto fail;
5117
Larry Hastings9cf065c2012-06-22 16:30:09 -07005118#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005119 if (path->fd > -1)
5120 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005121 else
5122#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005123 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124
5125 /* If we get here it's definitely an error */
5126
Larry Hastings2f936352014-08-05 14:04:04 +10005127 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005128
5129 while (--envc >= 0)
5130 PyMem_DEL(envlist[envc]);
5131 PyMem_DEL(envlist);
5132 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005133 if (argvlist)
5134 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005135 return NULL;
5136}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005137#endif /* HAVE_EXECV */
5138
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005139
Guido van Rossuma1065681999-01-25 23:20:23 +00005140#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005141/*[clinic input]
5142os.spawnv
5143
5144 mode: int
5145 Mode of process creation.
5146 path: FSConverter
5147 Path of executable file.
5148 argv: object
5149 Tuple or list of strings.
5150 /
5151
5152Execute the program specified by path in a new process.
5153[clinic start generated code]*/
5154
Larry Hastings2f936352014-08-05 14:04:04 +10005155static PyObject *
5156os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005157/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005158{
5159 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005160 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005161 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005162 Py_ssize_t argc;
5163 Py_intptr_t spawnval;
5164 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005165
Victor Stinner8c62be82010-05-06 00:08:46 +00005166 /* spawnv has three arguments: (mode, path, argv), where
5167 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005168
Larry Hastings2f936352014-08-05 14:04:04 +10005169 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 if (PyList_Check(argv)) {
5171 argc = PyList_Size(argv);
5172 getitem = PyList_GetItem;
5173 }
5174 else if (PyTuple_Check(argv)) {
5175 argc = PyTuple_Size(argv);
5176 getitem = PyTuple_GetItem;
5177 }
5178 else {
5179 PyErr_SetString(PyExc_TypeError,
5180 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005181 return NULL;
5182 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005183
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 argvlist = PyMem_NEW(char *, argc+1);
5185 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005186 return PyErr_NoMemory();
5187 }
5188 for (i = 0; i < argc; i++) {
5189 if (!fsconvert_strdup((*getitem)(argv, i),
5190 &argvlist[i])) {
5191 free_string_array(argvlist, i);
5192 PyErr_SetString(
5193 PyExc_TypeError,
5194 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005195 return NULL;
5196 }
5197 }
5198 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005199
Victor Stinner8c62be82010-05-06 00:08:46 +00005200 if (mode == _OLD_P_OVERLAY)
5201 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005202
Victor Stinner8c62be82010-05-06 00:08:46 +00005203 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005204 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005205 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005206
Victor Stinner8c62be82010-05-06 00:08:46 +00005207 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005208
Victor Stinner8c62be82010-05-06 00:08:46 +00005209 if (spawnval == -1)
5210 return posix_error();
5211 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005212 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005213}
5214
5215
Larry Hastings2f936352014-08-05 14:04:04 +10005216/*[clinic input]
5217os.spawnve
5218
5219 mode: int
5220 Mode of process creation.
5221 path: FSConverter
5222 Path of executable file.
5223 argv: object
5224 Tuple or list of strings.
5225 env: object
5226 Dictionary of strings mapping to strings.
5227 /
5228
5229Execute the program specified by path in a new process.
5230[clinic start generated code]*/
5231
Larry Hastings2f936352014-08-05 14:04:04 +10005232static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005233os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path,
5234 PyObject *argv, PyObject *env)
5235/*[clinic end generated code: output=e7f5f0703610531f input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005236{
5237 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005238 char **argvlist;
5239 char **envlist;
5240 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005241 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005242 Py_intptr_t spawnval;
5243 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5244 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005245
Victor Stinner8c62be82010-05-06 00:08:46 +00005246 /* spawnve has four arguments: (mode, path, argv, env), where
5247 argv is a list or tuple of strings and env is a dictionary
5248 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005249
Larry Hastings2f936352014-08-05 14:04:04 +10005250 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005251 if (PyList_Check(argv)) {
5252 argc = PyList_Size(argv);
5253 getitem = PyList_GetItem;
5254 }
5255 else if (PyTuple_Check(argv)) {
5256 argc = PyTuple_Size(argv);
5257 getitem = PyTuple_GetItem;
5258 }
5259 else {
5260 PyErr_SetString(PyExc_TypeError,
5261 "spawnve() arg 2 must be a tuple or list");
5262 goto fail_0;
5263 }
5264 if (!PyMapping_Check(env)) {
5265 PyErr_SetString(PyExc_TypeError,
5266 "spawnve() arg 3 must be a mapping object");
5267 goto fail_0;
5268 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005269
Victor Stinner8c62be82010-05-06 00:08:46 +00005270 argvlist = PyMem_NEW(char *, argc+1);
5271 if (argvlist == NULL) {
5272 PyErr_NoMemory();
5273 goto fail_0;
5274 }
5275 for (i = 0; i < argc; i++) {
5276 if (!fsconvert_strdup((*getitem)(argv, i),
5277 &argvlist[i]))
5278 {
5279 lastarg = i;
5280 goto fail_1;
5281 }
5282 }
5283 lastarg = argc;
5284 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005285
Victor Stinner8c62be82010-05-06 00:08:46 +00005286 envlist = parse_envlist(env, &envc);
5287 if (envlist == NULL)
5288 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005289
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 if (mode == _OLD_P_OVERLAY)
5291 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005292
Victor Stinner8c62be82010-05-06 00:08:46 +00005293 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005294 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005295 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005296
Victor Stinner8c62be82010-05-06 00:08:46 +00005297 if (spawnval == -1)
5298 (void) posix_error();
5299 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005300 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005301
Victor Stinner8c62be82010-05-06 00:08:46 +00005302 while (--envc >= 0)
5303 PyMem_DEL(envlist[envc]);
5304 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005305 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005306 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005307 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005308 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005309}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005310
Guido van Rossuma1065681999-01-25 23:20:23 +00005311#endif /* HAVE_SPAWNV */
5312
5313
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005314#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005315/*[clinic input]
5316os.fork1
5317
5318Fork a child process with a single multiplexed (i.e., not bound) thread.
5319
5320Return 0 to child process and PID of child to parent process.
5321[clinic start generated code]*/
5322
Larry Hastings2f936352014-08-05 14:04:04 +10005323static PyObject *
5324os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005325/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005326{
Victor Stinner8c62be82010-05-06 00:08:46 +00005327 pid_t pid;
5328 int result = 0;
5329 _PyImport_AcquireLock();
5330 pid = fork1();
5331 if (pid == 0) {
5332 /* child: this clobbers and resets the import lock. */
5333 PyOS_AfterFork();
5334 } else {
5335 /* parent: release the import lock. */
5336 result = _PyImport_ReleaseLock();
5337 }
5338 if (pid == -1)
5339 return posix_error();
5340 if (result < 0) {
5341 /* Don't clobber the OSError if the fork failed. */
5342 PyErr_SetString(PyExc_RuntimeError,
5343 "not holding the import lock");
5344 return NULL;
5345 }
5346 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005347}
Larry Hastings2f936352014-08-05 14:04:04 +10005348#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005349
5350
Guido van Rossumad0ee831995-03-01 10:34:45 +00005351#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005352/*[clinic input]
5353os.fork
5354
5355Fork a child process.
5356
5357Return 0 to child process and PID of child to parent process.
5358[clinic start generated code]*/
5359
Larry Hastings2f936352014-08-05 14:04:04 +10005360static PyObject *
5361os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005362/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005363{
Victor Stinner8c62be82010-05-06 00:08:46 +00005364 pid_t pid;
5365 int result = 0;
5366 _PyImport_AcquireLock();
5367 pid = fork();
5368 if (pid == 0) {
5369 /* child: this clobbers and resets the import lock. */
5370 PyOS_AfterFork();
5371 } else {
5372 /* parent: release the import lock. */
5373 result = _PyImport_ReleaseLock();
5374 }
5375 if (pid == -1)
5376 return posix_error();
5377 if (result < 0) {
5378 /* Don't clobber the OSError if the fork failed. */
5379 PyErr_SetString(PyExc_RuntimeError,
5380 "not holding the import lock");
5381 return NULL;
5382 }
5383 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005384}
Larry Hastings2f936352014-08-05 14:04:04 +10005385#endif /* HAVE_FORK */
5386
Guido van Rossum85e3b011991-06-03 12:42:10 +00005387
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005388#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005389#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005390/*[clinic input]
5391os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005392
Larry Hastings2f936352014-08-05 14:04:04 +10005393 policy: int
5394
5395Get the maximum scheduling priority for policy.
5396[clinic start generated code]*/
5397
Larry Hastings2f936352014-08-05 14:04:04 +10005398static PyObject *
5399os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005400/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005401{
5402 int max;
5403
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005404 max = sched_get_priority_max(policy);
5405 if (max < 0)
5406 return posix_error();
5407 return PyLong_FromLong(max);
5408}
5409
Larry Hastings2f936352014-08-05 14:04:04 +10005410
5411/*[clinic input]
5412os.sched_get_priority_min
5413
5414 policy: int
5415
5416Get the minimum scheduling priority for policy.
5417[clinic start generated code]*/
5418
Larry Hastings2f936352014-08-05 14:04:04 +10005419static PyObject *
5420os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005421/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005422{
5423 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005424 if (min < 0)
5425 return posix_error();
5426 return PyLong_FromLong(min);
5427}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005428#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5429
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005430
Larry Hastings2f936352014-08-05 14:04:04 +10005431#ifdef HAVE_SCHED_SETSCHEDULER
5432/*[clinic input]
5433os.sched_getscheduler
5434 pid: pid_t
5435 /
5436
5437Get the scheduling policy for the process identifiedy by pid.
5438
5439Passing 0 for pid returns the scheduling policy for the calling process.
5440[clinic start generated code]*/
5441
Larry Hastings2f936352014-08-05 14:04:04 +10005442static PyObject *
5443os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005444/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005445{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005446 int policy;
5447
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005448 policy = sched_getscheduler(pid);
5449 if (policy < 0)
5450 return posix_error();
5451 return PyLong_FromLong(policy);
5452}
Larry Hastings2f936352014-08-05 14:04:04 +10005453#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005454
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005455
5456#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005457/*[clinic input]
5458class os.sched_param "PyObject *" "&SchedParamType"
5459
5460@classmethod
5461os.sched_param.__new__
5462
5463 sched_priority: object
5464 A scheduling parameter.
5465
5466Current has only one field: sched_priority");
5467[clinic start generated code]*/
5468
Larry Hastings2f936352014-08-05 14:04:04 +10005469static PyObject *
5470os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005471/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005472{
5473 PyObject *res;
5474
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005475 res = PyStructSequence_New(type);
5476 if (!res)
5477 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005478 Py_INCREF(sched_priority);
5479 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005480 return res;
5481}
5482
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005483
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005484PyDoc_VAR(os_sched_param__doc__);
5485
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005486static PyStructSequence_Field sched_param_fields[] = {
5487 {"sched_priority", "the scheduling priority"},
5488 {0}
5489};
5490
5491static PyStructSequence_Desc sched_param_desc = {
5492 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005493 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005494 sched_param_fields,
5495 1
5496};
5497
5498static int
5499convert_sched_param(PyObject *param, struct sched_param *res)
5500{
5501 long priority;
5502
5503 if (Py_TYPE(param) != &SchedParamType) {
5504 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5505 return 0;
5506 }
5507 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5508 if (priority == -1 && PyErr_Occurred())
5509 return 0;
5510 if (priority > INT_MAX || priority < INT_MIN) {
5511 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5512 return 0;
5513 }
5514 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5515 return 1;
5516}
Larry Hastings2f936352014-08-05 14:04:04 +10005517#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005518
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005519
5520#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005521/*[clinic input]
5522os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005523
Larry Hastings2f936352014-08-05 14:04:04 +10005524 pid: pid_t
5525 policy: int
5526 param: sched_param
5527 /
5528
5529Set the scheduling policy for the process identified by pid.
5530
5531If pid is 0, the calling process is changed.
5532param is an instance of sched_param.
5533[clinic start generated code]*/
5534
Larry Hastings2f936352014-08-05 14:04:04 +10005535static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005536os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy,
5537 struct sched_param *param)
5538/*[clinic end generated code: output=37053e5c528c35c9 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005539{
Jesus Cea9c822272011-09-10 01:40:52 +02005540 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005541 ** sched_setscheduler() returns 0 in Linux, but the previous
5542 ** scheduling policy under Solaris/Illumos, and others.
5543 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005544 */
Larry Hastings2f936352014-08-05 14:04:04 +10005545 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005546 return posix_error();
5547 Py_RETURN_NONE;
5548}
Larry Hastings2f936352014-08-05 14:04:04 +10005549#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005550
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005551
5552#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005553/*[clinic input]
5554os.sched_getparam
5555 pid: pid_t
5556 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005557
Larry Hastings2f936352014-08-05 14:04:04 +10005558Returns scheduling parameters for the process identified by pid.
5559
5560If pid is 0, returns parameters for the calling process.
5561Return value is an instance of sched_param.
5562[clinic start generated code]*/
5563
Larry Hastings2f936352014-08-05 14:04:04 +10005564static PyObject *
5565os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005566/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005567{
5568 struct sched_param param;
5569 PyObject *result;
5570 PyObject *priority;
5571
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005572 if (sched_getparam(pid, &param))
5573 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005574 result = PyStructSequence_New(&SchedParamType);
5575 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005576 return NULL;
5577 priority = PyLong_FromLong(param.sched_priority);
5578 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005579 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005580 return NULL;
5581 }
Larry Hastings2f936352014-08-05 14:04:04 +10005582 PyStructSequence_SET_ITEM(result, 0, priority);
5583 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005584}
5585
Larry Hastings2f936352014-08-05 14:04:04 +10005586
5587/*[clinic input]
5588os.sched_setparam
5589 pid: pid_t
5590 param: sched_param
5591 /
5592
5593Set scheduling parameters for the process identified by pid.
5594
5595If pid is 0, sets parameters for the calling process.
5596param should be an instance of sched_param.
5597[clinic start generated code]*/
5598
Larry Hastings2f936352014-08-05 14:04:04 +10005599static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04005600os_sched_setparam_impl(PyModuleDef *module, pid_t pid,
5601 struct sched_param *param)
5602/*[clinic end generated code: output=b7a3c589436cec9b input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005603{
5604 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005605 return posix_error();
5606 Py_RETURN_NONE;
5607}
Larry Hastings2f936352014-08-05 14:04:04 +10005608#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005609
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005610
5611#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005612/*[clinic input]
5613os.sched_rr_get_interval -> double
5614 pid: pid_t
5615 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005616
Larry Hastings2f936352014-08-05 14:04:04 +10005617Return the round-robin quantum for the process identified by pid, in seconds.
5618
5619Value returned is a float.
5620[clinic start generated code]*/
5621
Larry Hastings2f936352014-08-05 14:04:04 +10005622static double
5623os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005624/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005625{
5626 struct timespec interval;
5627 if (sched_rr_get_interval(pid, &interval)) {
5628 posix_error();
5629 return -1.0;
5630 }
5631 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5632}
5633#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005634
Larry Hastings2f936352014-08-05 14:04:04 +10005635
5636/*[clinic input]
5637os.sched_yield
5638
5639Voluntarily relinquish the CPU.
5640[clinic start generated code]*/
5641
Larry Hastings2f936352014-08-05 14:04:04 +10005642static PyObject *
5643os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005644/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005645{
5646 if (sched_yield())
5647 return posix_error();
5648 Py_RETURN_NONE;
5649}
5650
Benjamin Peterson2740af82011-08-02 17:41:34 -05005651#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005652/* The minimum number of CPUs allocated in a cpu_set_t */
5653static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005654
Larry Hastings2f936352014-08-05 14:04:04 +10005655/*[clinic input]
5656os.sched_setaffinity
5657 pid: pid_t
5658 mask : object
5659 /
5660
5661Set the CPU affinity of the process identified by pid to mask.
5662
5663mask should be an iterable of integers identifying CPUs.
5664[clinic start generated code]*/
5665
Larry Hastings2f936352014-08-05 14:04:04 +10005666static PyObject *
5667os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005668/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005669{
Antoine Pitrou84869872012-08-04 16:16:35 +02005670 int ncpus;
5671 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005672 cpu_set_t *cpu_set = NULL;
5673 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005674
Larry Hastings2f936352014-08-05 14:04:04 +10005675 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005676 if (iterator == NULL)
5677 return NULL;
5678
5679 ncpus = NCPUS_START;
5680 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005681 cpu_set = CPU_ALLOC(ncpus);
5682 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005683 PyErr_NoMemory();
5684 goto error;
5685 }
Larry Hastings2f936352014-08-05 14:04:04 +10005686 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005687
5688 while ((item = PyIter_Next(iterator))) {
5689 long cpu;
5690 if (!PyLong_Check(item)) {
5691 PyErr_Format(PyExc_TypeError,
5692 "expected an iterator of ints, "
5693 "but iterator yielded %R",
5694 Py_TYPE(item));
5695 Py_DECREF(item);
5696 goto error;
5697 }
5698 cpu = PyLong_AsLong(item);
5699 Py_DECREF(item);
5700 if (cpu < 0) {
5701 if (!PyErr_Occurred())
5702 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5703 goto error;
5704 }
5705 if (cpu > INT_MAX - 1) {
5706 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5707 goto error;
5708 }
5709 if (cpu >= ncpus) {
5710 /* Grow CPU mask to fit the CPU number */
5711 int newncpus = ncpus;
5712 cpu_set_t *newmask;
5713 size_t newsetsize;
5714 while (newncpus <= cpu) {
5715 if (newncpus > INT_MAX / 2)
5716 newncpus = cpu + 1;
5717 else
5718 newncpus = newncpus * 2;
5719 }
5720 newmask = CPU_ALLOC(newncpus);
5721 if (newmask == NULL) {
5722 PyErr_NoMemory();
5723 goto error;
5724 }
5725 newsetsize = CPU_ALLOC_SIZE(newncpus);
5726 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005727 memcpy(newmask, cpu_set, setsize);
5728 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005729 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005730 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005731 ncpus = newncpus;
5732 }
Larry Hastings2f936352014-08-05 14:04:04 +10005733 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005734 }
5735 Py_CLEAR(iterator);
5736
Larry Hastings2f936352014-08-05 14:04:04 +10005737 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005738 posix_error();
5739 goto error;
5740 }
Larry Hastings2f936352014-08-05 14:04:04 +10005741 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005742 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005743
5744error:
Larry Hastings2f936352014-08-05 14:04:04 +10005745 if (cpu_set)
5746 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005747 Py_XDECREF(iterator);
5748 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005749}
5750
Larry Hastings2f936352014-08-05 14:04:04 +10005751
5752/*[clinic input]
5753os.sched_getaffinity
5754 pid: pid_t
5755 /
5756
Charles-François Natalidc87e4b2015-07-13 21:01:39 +01005757Return the affinity of the process identified by pid (or the current process if zero).
Larry Hastings2f936352014-08-05 14:04:04 +10005758
5759The affinity is returned as a set of CPU identifiers.
5760[clinic start generated code]*/
5761
Larry Hastings2f936352014-08-05 14:04:04 +10005762static PyObject *
5763os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Charles-François Natali80d62e62015-08-13 20:37:08 +01005764/*[clinic end generated code: output=b431a8f310e369e7 input=983ce7cb4a565980]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005765{
Antoine Pitrou84869872012-08-04 16:16:35 +02005766 int cpu, ncpus, count;
5767 size_t setsize;
5768 cpu_set_t *mask = NULL;
5769 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005770
Antoine Pitrou84869872012-08-04 16:16:35 +02005771 ncpus = NCPUS_START;
5772 while (1) {
5773 setsize = CPU_ALLOC_SIZE(ncpus);
5774 mask = CPU_ALLOC(ncpus);
5775 if (mask == NULL)
5776 return PyErr_NoMemory();
5777 if (sched_getaffinity(pid, setsize, mask) == 0)
5778 break;
5779 CPU_FREE(mask);
5780 if (errno != EINVAL)
5781 return posix_error();
5782 if (ncpus > INT_MAX / 2) {
5783 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5784 "a large enough CPU set");
5785 return NULL;
5786 }
5787 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005788 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005789
5790 res = PySet_New(NULL);
5791 if (res == NULL)
5792 goto error;
5793 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5794 if (CPU_ISSET_S(cpu, setsize, mask)) {
5795 PyObject *cpu_num = PyLong_FromLong(cpu);
5796 --count;
5797 if (cpu_num == NULL)
5798 goto error;
5799 if (PySet_Add(res, cpu_num)) {
5800 Py_DECREF(cpu_num);
5801 goto error;
5802 }
5803 Py_DECREF(cpu_num);
5804 }
5805 }
5806 CPU_FREE(mask);
5807 return res;
5808
5809error:
5810 if (mask)
5811 CPU_FREE(mask);
5812 Py_XDECREF(res);
5813 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005814}
5815
Benjamin Peterson2740af82011-08-02 17:41:34 -05005816#endif /* HAVE_SCHED_SETAFFINITY */
5817
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005818#endif /* HAVE_SCHED_H */
5819
Larry Hastings2f936352014-08-05 14:04:04 +10005820
Neal Norwitzb59798b2003-03-21 01:43:31 +00005821/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005822/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5823#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005824#define DEV_PTY_FILE "/dev/ptc"
5825#define HAVE_DEV_PTMX
5826#else
5827#define DEV_PTY_FILE "/dev/ptmx"
5828#endif
5829
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005830#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005831#ifdef HAVE_PTY_H
5832#include <pty.h>
5833#else
5834#ifdef HAVE_LIBUTIL_H
5835#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005836#else
5837#ifdef HAVE_UTIL_H
5838#include <util.h>
5839#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005840#endif /* HAVE_LIBUTIL_H */
5841#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005842#ifdef HAVE_STROPTS_H
5843#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005844#endif
5845#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005846
Larry Hastings2f936352014-08-05 14:04:04 +10005847
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005848#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005849/*[clinic input]
5850os.openpty
5851
5852Open a pseudo-terminal.
5853
5854Return a tuple of (master_fd, slave_fd) containing open file descriptors
5855for both the master and slave ends.
5856[clinic start generated code]*/
5857
Larry Hastings2f936352014-08-05 14:04:04 +10005858static PyObject *
5859os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005860/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005861{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005862 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005863#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005864 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005865#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005866#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005867 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005868#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005870#endif
5871#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005872
Thomas Wouters70c21a12000-07-14 14:28:33 +00005873#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005874 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005875 goto posix_error;
5876
5877 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5878 goto error;
5879 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5880 goto error;
5881
Neal Norwitzb59798b2003-03-21 01:43:31 +00005882#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005883 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5884 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005885 goto posix_error;
5886 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5887 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005888
Victor Stinnerdaf45552013-08-28 00:53:59 +02005889 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005891 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005892
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005893#else
Victor Stinner000de532013-11-25 23:19:58 +01005894 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005895 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005896 goto posix_error;
5897
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005899
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 /* change permission of slave */
5901 if (grantpt(master_fd) < 0) {
5902 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005903 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005904 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005905
Victor Stinner8c62be82010-05-06 00:08:46 +00005906 /* unlock slave */
5907 if (unlockpt(master_fd) < 0) {
5908 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005909 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005910 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005911
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005913
Victor Stinner8c62be82010-05-06 00:08:46 +00005914 slave_name = ptsname(master_fd); /* get name of slave */
5915 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005916 goto posix_error;
5917
5918 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005919 if (slave_fd == -1)
5920 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005921
5922 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5923 goto posix_error;
5924
Neal Norwitzb59798b2003-03-21 01:43:31 +00005925#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005926 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5927 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005928#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005929 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005930#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005931#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005932#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005933
Victor Stinner8c62be82010-05-06 00:08:46 +00005934 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005935
Victor Stinnerdaf45552013-08-28 00:53:59 +02005936posix_error:
5937 posix_error();
5938error:
5939 if (master_fd != -1)
5940 close(master_fd);
5941 if (slave_fd != -1)
5942 close(slave_fd);
5943 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005944}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005945#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005946
Larry Hastings2f936352014-08-05 14:04:04 +10005947
Fred Drake8cef4cf2000-06-28 16:40:38 +00005948#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005949/*[clinic input]
5950os.forkpty
5951
5952Fork a new process with a new pseudo-terminal as controlling tty.
5953
5954Returns a tuple of (pid, master_fd).
5955Like fork(), return pid of 0 to the child process,
5956and pid of child to the parent process.
5957To both, return fd of newly opened pseudo-terminal.
5958[clinic start generated code]*/
5959
Larry Hastings2f936352014-08-05 14:04:04 +10005960static PyObject *
5961os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005962/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005963{
Victor Stinner8c62be82010-05-06 00:08:46 +00005964 int master_fd = -1, result = 0;
5965 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005966
Victor Stinner8c62be82010-05-06 00:08:46 +00005967 _PyImport_AcquireLock();
5968 pid = forkpty(&master_fd, NULL, NULL, NULL);
5969 if (pid == 0) {
5970 /* child: this clobbers and resets the import lock. */
5971 PyOS_AfterFork();
5972 } else {
5973 /* parent: release the import lock. */
5974 result = _PyImport_ReleaseLock();
5975 }
5976 if (pid == -1)
5977 return posix_error();
5978 if (result < 0) {
5979 /* Don't clobber the OSError if the fork failed. */
5980 PyErr_SetString(PyExc_RuntimeError,
5981 "not holding the import lock");
5982 return NULL;
5983 }
5984 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005985}
Larry Hastings2f936352014-08-05 14:04:04 +10005986#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005987
Ross Lagerwall7807c352011-03-17 20:20:30 +02005988
Guido van Rossumad0ee831995-03-01 10:34:45 +00005989#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005990/*[clinic input]
5991os.getegid
5992
5993Return the current process's effective group id.
5994[clinic start generated code]*/
5995
Larry Hastings2f936352014-08-05 14:04:04 +10005996static PyObject *
5997os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005998/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005999{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006000 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006001}
Larry Hastings2f936352014-08-05 14:04:04 +10006002#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006003
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006004
Guido van Rossumad0ee831995-03-01 10:34:45 +00006005#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006006/*[clinic input]
6007os.geteuid
6008
6009Return the current process's effective user id.
6010[clinic start generated code]*/
6011
Larry Hastings2f936352014-08-05 14:04:04 +10006012static PyObject *
6013os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006014/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006015{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006016 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006017}
Larry Hastings2f936352014-08-05 14:04:04 +10006018#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006019
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006020
Guido van Rossumad0ee831995-03-01 10:34:45 +00006021#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006022/*[clinic input]
6023os.getgid
6024
6025Return the current process's group id.
6026[clinic start generated code]*/
6027
Larry Hastings2f936352014-08-05 14:04:04 +10006028static PyObject *
6029os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006030/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006031{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006032 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006033}
Larry Hastings2f936352014-08-05 14:04:04 +10006034#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006035
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006036
Larry Hastings2f936352014-08-05 14:04:04 +10006037/*[clinic input]
6038os.getpid
6039
6040Return the current process id.
6041[clinic start generated code]*/
6042
Larry Hastings2f936352014-08-05 14:04:04 +10006043static PyObject *
6044os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006045/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006046{
Victor Stinner8c62be82010-05-06 00:08:46 +00006047 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006048}
6049
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006050#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006051
6052/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006053PyDoc_STRVAR(posix_getgrouplist__doc__,
6054"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6055Returns a list of groups to which a user belongs.\n\n\
6056 user: username to lookup\n\
6057 group: base group id of the user");
6058
6059static PyObject *
6060posix_getgrouplist(PyObject *self, PyObject *args)
6061{
6062#ifdef NGROUPS_MAX
6063#define MAX_GROUPS NGROUPS_MAX
6064#else
6065 /* defined to be 16 on Solaris7, so this should be a small number */
6066#define MAX_GROUPS 64
6067#endif
6068
6069 const char *user;
6070 int i, ngroups;
6071 PyObject *list;
6072#ifdef __APPLE__
6073 int *groups, basegid;
6074#else
6075 gid_t *groups, basegid;
6076#endif
6077 ngroups = MAX_GROUPS;
6078
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006079#ifdef __APPLE__
6080 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006081 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006082#else
6083 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6084 _Py_Gid_Converter, &basegid))
6085 return NULL;
6086#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006087
6088#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006089 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006090#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006091 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006092#endif
6093 if (groups == NULL)
6094 return PyErr_NoMemory();
6095
6096 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6097 PyMem_Del(groups);
6098 return posix_error();
6099 }
6100
6101 list = PyList_New(ngroups);
6102 if (list == NULL) {
6103 PyMem_Del(groups);
6104 return NULL;
6105 }
6106
6107 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006108#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006109 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006110#else
6111 PyObject *o = _PyLong_FromGid(groups[i]);
6112#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006113 if (o == NULL) {
6114 Py_DECREF(list);
6115 PyMem_Del(groups);
6116 return NULL;
6117 }
6118 PyList_SET_ITEM(list, i, o);
6119 }
6120
6121 PyMem_Del(groups);
6122
6123 return list;
6124}
Larry Hastings2f936352014-08-05 14:04:04 +10006125#endif /* HAVE_GETGROUPLIST */
6126
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006127
Fred Drakec9680921999-12-13 16:37:25 +00006128#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006129/*[clinic input]
6130os.getgroups
6131
6132Return list of supplemental group IDs for the process.
6133[clinic start generated code]*/
6134
Larry Hastings2f936352014-08-05 14:04:04 +10006135static PyObject *
6136os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006137/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006138{
6139 PyObject *result = NULL;
6140
Fred Drakec9680921999-12-13 16:37:25 +00006141#ifdef NGROUPS_MAX
6142#define MAX_GROUPS NGROUPS_MAX
6143#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006144 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006145#define MAX_GROUPS 64
6146#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006147 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006148
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006149 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006150 * This is a helper variable to store the intermediate result when
6151 * that happens.
6152 *
6153 * To keep the code readable the OSX behaviour is unconditional,
6154 * according to the POSIX spec this should be safe on all unix-y
6155 * systems.
6156 */
6157 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006158 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006159
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006160#ifdef __APPLE__
6161 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6162 * there are more groups than can fit in grouplist. Therefore, on OS X
6163 * always first call getgroups with length 0 to get the actual number
6164 * of groups.
6165 */
6166 n = getgroups(0, NULL);
6167 if (n < 0) {
6168 return posix_error();
6169 } else if (n <= MAX_GROUPS) {
6170 /* groups will fit in existing array */
6171 alt_grouplist = grouplist;
6172 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006173 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006174 if (alt_grouplist == NULL) {
6175 errno = EINVAL;
6176 return posix_error();
6177 }
6178 }
6179
6180 n = getgroups(n, alt_grouplist);
6181 if (n == -1) {
6182 if (alt_grouplist != grouplist) {
6183 PyMem_Free(alt_grouplist);
6184 }
6185 return posix_error();
6186 }
6187#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006188 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006189 if (n < 0) {
6190 if (errno == EINVAL) {
6191 n = getgroups(0, NULL);
6192 if (n == -1) {
6193 return posix_error();
6194 }
6195 if (n == 0) {
6196 /* Avoid malloc(0) */
6197 alt_grouplist = grouplist;
6198 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006199 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006200 if (alt_grouplist == NULL) {
6201 errno = EINVAL;
6202 return posix_error();
6203 }
6204 n = getgroups(n, alt_grouplist);
6205 if (n == -1) {
6206 PyMem_Free(alt_grouplist);
6207 return posix_error();
6208 }
6209 }
6210 } else {
6211 return posix_error();
6212 }
6213 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006214#endif
6215
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006216 result = PyList_New(n);
6217 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 int i;
6219 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006220 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006221 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006222 Py_DECREF(result);
6223 result = NULL;
6224 break;
Fred Drakec9680921999-12-13 16:37:25 +00006225 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006226 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006227 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006228 }
6229
6230 if (alt_grouplist != grouplist) {
6231 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006232 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006233
Fred Drakec9680921999-12-13 16:37:25 +00006234 return result;
6235}
Larry Hastings2f936352014-08-05 14:04:04 +10006236#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006237
Antoine Pitroub7572f02009-12-02 20:46:48 +00006238#ifdef HAVE_INITGROUPS
6239PyDoc_STRVAR(posix_initgroups__doc__,
6240"initgroups(username, gid) -> None\n\n\
6241Call the system initgroups() to initialize the group access list with all of\n\
6242the groups of which the specified username is a member, plus the specified\n\
6243group id.");
6244
Larry Hastings2f936352014-08-05 14:04:04 +10006245/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006246static PyObject *
6247posix_initgroups(PyObject *self, PyObject *args)
6248{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006249 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006250 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006251 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006252#ifdef __APPLE__
6253 int gid;
6254#else
6255 gid_t gid;
6256#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006257
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006258#ifdef __APPLE__
6259 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6260 PyUnicode_FSConverter, &oname,
6261 &gid))
6262#else
6263 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6264 PyUnicode_FSConverter, &oname,
6265 _Py_Gid_Converter, &gid))
6266#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006267 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006268 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006269
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006270 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006271 Py_DECREF(oname);
6272 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006273 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006274
Victor Stinner8c62be82010-05-06 00:08:46 +00006275 Py_INCREF(Py_None);
6276 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006277}
Larry Hastings2f936352014-08-05 14:04:04 +10006278#endif /* HAVE_INITGROUPS */
6279
Antoine Pitroub7572f02009-12-02 20:46:48 +00006280
Martin v. Löwis606edc12002-06-13 21:09:11 +00006281#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006282/*[clinic input]
6283os.getpgid
6284
6285 pid: pid_t
6286
6287Call the system call getpgid(), and return the result.
6288[clinic start generated code]*/
6289
Larry Hastings2f936352014-08-05 14:04:04 +10006290static PyObject *
6291os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006292/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006293{
6294 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006295 if (pgid < 0)
6296 return posix_error();
6297 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006298}
6299#endif /* HAVE_GETPGID */
6300
6301
Guido van Rossumb6775db1994-08-01 11:34:53 +00006302#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006303/*[clinic input]
6304os.getpgrp
6305
6306Return the current process group id.
6307[clinic start generated code]*/
6308
Larry Hastings2f936352014-08-05 14:04:04 +10006309static PyObject *
6310os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006311/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006312{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006313#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006314 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006315#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006316 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006317#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006318}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006319#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006320
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006321
Guido van Rossumb6775db1994-08-01 11:34:53 +00006322#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006323/*[clinic input]
6324os.setpgrp
6325
6326Make the current process the leader of its process group.
6327[clinic start generated code]*/
6328
Larry Hastings2f936352014-08-05 14:04:04 +10006329static PyObject *
6330os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006331/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006332{
Guido van Rossum64933891994-10-20 21:56:42 +00006333#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006334 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006335#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006336 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006337#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006338 return posix_error();
6339 Py_INCREF(Py_None);
6340 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006341}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006342#endif /* HAVE_SETPGRP */
6343
Guido van Rossumad0ee831995-03-01 10:34:45 +00006344#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006345
6346#ifdef MS_WINDOWS
6347#include <tlhelp32.h>
6348
6349static PyObject*
6350win32_getppid()
6351{
6352 HANDLE snapshot;
6353 pid_t mypid;
6354 PyObject* result = NULL;
6355 BOOL have_record;
6356 PROCESSENTRY32 pe;
6357
6358 mypid = getpid(); /* This function never fails */
6359
6360 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6361 if (snapshot == INVALID_HANDLE_VALUE)
6362 return PyErr_SetFromWindowsErr(GetLastError());
6363
6364 pe.dwSize = sizeof(pe);
6365 have_record = Process32First(snapshot, &pe);
6366 while (have_record) {
6367 if (mypid == (pid_t)pe.th32ProcessID) {
6368 /* We could cache the ulong value in a static variable. */
6369 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6370 break;
6371 }
6372
6373 have_record = Process32Next(snapshot, &pe);
6374 }
6375
6376 /* If our loop exits and our pid was not found (result will be NULL)
6377 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6378 * error anyway, so let's raise it. */
6379 if (!result)
6380 result = PyErr_SetFromWindowsErr(GetLastError());
6381
6382 CloseHandle(snapshot);
6383
6384 return result;
6385}
6386#endif /*MS_WINDOWS*/
6387
Larry Hastings2f936352014-08-05 14:04:04 +10006388
6389/*[clinic input]
6390os.getppid
6391
6392Return the parent's process id.
6393
6394If the parent process has already exited, Windows machines will still
6395return its id; others systems will return the id of the 'init' process (1).
6396[clinic start generated code]*/
6397
Larry Hastings2f936352014-08-05 14:04:04 +10006398static PyObject *
6399os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006400/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006401{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006402#ifdef MS_WINDOWS
6403 return win32_getppid();
6404#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006405 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006406#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006407}
6408#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006409
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006410
Fred Drake12c6e2d1999-12-14 21:25:03 +00006411#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006412/*[clinic input]
6413os.getlogin
6414
6415Return the actual login name.
6416[clinic start generated code]*/
6417
Larry Hastings2f936352014-08-05 14:04:04 +10006418static PyObject *
6419os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006420/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006421{
Victor Stinner8c62be82010-05-06 00:08:46 +00006422 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006423#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006424 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006425 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006426
6427 if (GetUserNameW(user_name, &num_chars)) {
6428 /* num_chars is the number of unicode chars plus null terminator */
6429 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006430 }
6431 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006432 result = PyErr_SetFromWindowsErr(GetLastError());
6433#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006434 char *name;
6435 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006436
Victor Stinner8c62be82010-05-06 00:08:46 +00006437 errno = 0;
6438 name = getlogin();
6439 if (name == NULL) {
6440 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006441 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006442 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006443 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006444 }
6445 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006446 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006447 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006448#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006449 return result;
6450}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006451#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006452
Larry Hastings2f936352014-08-05 14:04:04 +10006453
Guido van Rossumad0ee831995-03-01 10:34:45 +00006454#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006455/*[clinic input]
6456os.getuid
6457
6458Return the current process's user id.
6459[clinic start generated code]*/
6460
Larry Hastings2f936352014-08-05 14:04:04 +10006461static PyObject *
6462os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006463/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006464{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006465 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006466}
Larry Hastings2f936352014-08-05 14:04:04 +10006467#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006468
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006469
Brian Curtineb24d742010-04-12 17:16:38 +00006470#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006471#define HAVE_KILL
6472#endif /* MS_WINDOWS */
6473
6474#ifdef HAVE_KILL
6475/*[clinic input]
6476os.kill
6477
6478 pid: pid_t
6479 signal: Py_ssize_t
6480 /
6481
6482Kill a process with a signal.
6483[clinic start generated code]*/
6484
Larry Hastings2f936352014-08-05 14:04:04 +10006485static PyObject *
6486os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006487/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006488#ifndef MS_WINDOWS
6489{
6490 if (kill(pid, (int)signal) == -1)
6491 return posix_error();
6492 Py_RETURN_NONE;
6493}
6494#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006495{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006496 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006497 DWORD sig = (DWORD)signal;
6498 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006499 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006500
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 /* Console processes which share a common console can be sent CTRL+C or
6502 CTRL+BREAK events, provided they handle said events. */
6503 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006504 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006505 err = GetLastError();
6506 PyErr_SetFromWindowsErr(err);
6507 }
6508 else
6509 Py_RETURN_NONE;
6510 }
Brian Curtineb24d742010-04-12 17:16:38 +00006511
Victor Stinner8c62be82010-05-06 00:08:46 +00006512 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6513 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006514 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006515 if (handle == NULL) {
6516 err = GetLastError();
6517 return PyErr_SetFromWindowsErr(err);
6518 }
Brian Curtineb24d742010-04-12 17:16:38 +00006519
Victor Stinner8c62be82010-05-06 00:08:46 +00006520 if (TerminateProcess(handle, sig) == 0) {
6521 err = GetLastError();
6522 result = PyErr_SetFromWindowsErr(err);
6523 } else {
6524 Py_INCREF(Py_None);
6525 result = Py_None;
6526 }
Brian Curtineb24d742010-04-12 17:16:38 +00006527
Victor Stinner8c62be82010-05-06 00:08:46 +00006528 CloseHandle(handle);
6529 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006530}
Larry Hastings2f936352014-08-05 14:04:04 +10006531#endif /* !MS_WINDOWS */
6532#endif /* HAVE_KILL */
6533
6534
6535#ifdef HAVE_KILLPG
6536/*[clinic input]
6537os.killpg
6538
6539 pgid: pid_t
6540 signal: int
6541 /
6542
6543Kill a process group with a signal.
6544[clinic start generated code]*/
6545
Larry Hastings2f936352014-08-05 14:04:04 +10006546static PyObject *
6547os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006548/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006549{
6550 /* XXX some man pages make the `pgid` parameter an int, others
6551 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6552 take the same type. Moreover, pid_t is always at least as wide as
6553 int (else compilation of this module fails), which is safe. */
6554 if (killpg(pgid, signal) == -1)
6555 return posix_error();
6556 Py_RETURN_NONE;
6557}
6558#endif /* HAVE_KILLPG */
6559
Brian Curtineb24d742010-04-12 17:16:38 +00006560
Guido van Rossumc0125471996-06-28 18:55:32 +00006561#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006562#ifdef HAVE_SYS_LOCK_H
6563#include <sys/lock.h>
6564#endif
6565
Larry Hastings2f936352014-08-05 14:04:04 +10006566/*[clinic input]
6567os.plock
6568 op: int
6569 /
6570
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006571Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006572[clinic start generated code]*/
6573
Larry Hastings2f936352014-08-05 14:04:04 +10006574static PyObject *
6575os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006576/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006577{
Victor Stinner8c62be82010-05-06 00:08:46 +00006578 if (plock(op) == -1)
6579 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006580 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006581}
Larry Hastings2f936352014-08-05 14:04:04 +10006582#endif /* HAVE_PLOCK */
6583
Guido van Rossumc0125471996-06-28 18:55:32 +00006584
Guido van Rossumb6775db1994-08-01 11:34:53 +00006585#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006586/*[clinic input]
6587os.setuid
6588
6589 uid: uid_t
6590 /
6591
6592Set the current process's user id.
6593[clinic start generated code]*/
6594
Larry Hastings2f936352014-08-05 14:04:04 +10006595static PyObject *
6596os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006597/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006598{
Victor Stinner8c62be82010-05-06 00:08:46 +00006599 if (setuid(uid) < 0)
6600 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006601 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006602}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006603#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006604
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006605
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006606#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006607/*[clinic input]
6608os.seteuid
6609
6610 euid: uid_t
6611 /
6612
6613Set the current process's effective user id.
6614[clinic start generated code]*/
6615
Larry Hastings2f936352014-08-05 14:04:04 +10006616static PyObject *
6617os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006618/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006619{
6620 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006621 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006622 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006623}
6624#endif /* HAVE_SETEUID */
6625
Larry Hastings2f936352014-08-05 14:04:04 +10006626
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006627#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006628/*[clinic input]
6629os.setegid
6630
6631 egid: gid_t
6632 /
6633
6634Set the current process's effective group id.
6635[clinic start generated code]*/
6636
Larry Hastings2f936352014-08-05 14:04:04 +10006637static PyObject *
6638os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006639/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006640{
6641 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006642 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006643 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006644}
6645#endif /* HAVE_SETEGID */
6646
Larry Hastings2f936352014-08-05 14:04:04 +10006647
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006648#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006649/*[clinic input]
6650os.setreuid
6651
6652 ruid: uid_t
6653 euid: uid_t
6654 /
6655
6656Set the current process's real and effective user ids.
6657[clinic start generated code]*/
6658
Larry Hastings2f936352014-08-05 14:04:04 +10006659static PyObject *
6660os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006661/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006662{
Victor Stinner8c62be82010-05-06 00:08:46 +00006663 if (setreuid(ruid, euid) < 0) {
6664 return posix_error();
6665 } else {
6666 Py_INCREF(Py_None);
6667 return Py_None;
6668 }
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006669}
6670#endif /* HAVE_SETREUID */
6671
Larry Hastings2f936352014-08-05 14:04:04 +10006672
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006673#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006674/*[clinic input]
6675os.setregid
6676
6677 rgid: gid_t
6678 egid: gid_t
6679 /
6680
6681Set the current process's real and effective group ids.
6682[clinic start generated code]*/
6683
Larry Hastings2f936352014-08-05 14:04:04 +10006684static PyObject *
6685os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006686/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006687{
6688 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006689 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006690 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b22000-07-13 01:26:58 +00006691}
6692#endif /* HAVE_SETREGID */
6693
Larry Hastings2f936352014-08-05 14:04:04 +10006694
Guido van Rossumb6775db1994-08-01 11:34:53 +00006695#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006696/*[clinic input]
6697os.setgid
6698 gid: gid_t
6699 /
6700
6701Set the current process's group id.
6702[clinic start generated code]*/
6703
Larry Hastings2f936352014-08-05 14:04:04 +10006704static PyObject *
6705os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006706/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006707{
Victor Stinner8c62be82010-05-06 00:08:46 +00006708 if (setgid(gid) < 0)
6709 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006710 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006711}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006712#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006713
Larry Hastings2f936352014-08-05 14:04:04 +10006714
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006715#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006716/*[clinic input]
6717os.setgroups
6718
6719 groups: object
6720 /
6721
6722Set the groups of the current process to list.
6723[clinic start generated code]*/
6724
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006725static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006726os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006727/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006728{
Victor Stinner8c62be82010-05-06 00:08:46 +00006729 int i, len;
6730 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006731
Victor Stinner8c62be82010-05-06 00:08:46 +00006732 if (!PySequence_Check(groups)) {
6733 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6734 return NULL;
6735 }
6736 len = PySequence_Size(groups);
6737 if (len > MAX_GROUPS) {
6738 PyErr_SetString(PyExc_ValueError, "too many groups");
6739 return NULL;
6740 }
6741 for(i = 0; i < len; i++) {
6742 PyObject *elem;
6743 elem = PySequence_GetItem(groups, i);
6744 if (!elem)
6745 return NULL;
6746 if (!PyLong_Check(elem)) {
6747 PyErr_SetString(PyExc_TypeError,
6748 "groups must be integers");
6749 Py_DECREF(elem);
6750 return NULL;
6751 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006752 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006753 Py_DECREF(elem);
6754 return NULL;
6755 }
6756 }
6757 Py_DECREF(elem);
6758 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006759
Victor Stinner8c62be82010-05-06 00:08:46 +00006760 if (setgroups(len, grouplist) < 0)
6761 return posix_error();
6762 Py_INCREF(Py_None);
6763 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006764}
6765#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006766
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006767#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6768static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006769wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006770{
Victor Stinner8c62be82010-05-06 00:08:46 +00006771 PyObject *result;
6772 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006773 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006774
Victor Stinner8c62be82010-05-06 00:08:46 +00006775 if (pid == -1)
6776 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006777
Victor Stinner8c62be82010-05-06 00:08:46 +00006778 if (struct_rusage == NULL) {
6779 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6780 if (m == NULL)
6781 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006782 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 Py_DECREF(m);
6784 if (struct_rusage == NULL)
6785 return NULL;
6786 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006787
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6789 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6790 if (!result)
6791 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006792
6793#ifndef doubletime
6794#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6795#endif
6796
Victor Stinner8c62be82010-05-06 00:08:46 +00006797 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006798 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006799 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006800 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006801#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006802 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6803 SET_INT(result, 2, ru->ru_maxrss);
6804 SET_INT(result, 3, ru->ru_ixrss);
6805 SET_INT(result, 4, ru->ru_idrss);
6806 SET_INT(result, 5, ru->ru_isrss);
6807 SET_INT(result, 6, ru->ru_minflt);
6808 SET_INT(result, 7, ru->ru_majflt);
6809 SET_INT(result, 8, ru->ru_nswap);
6810 SET_INT(result, 9, ru->ru_inblock);
6811 SET_INT(result, 10, ru->ru_oublock);
6812 SET_INT(result, 11, ru->ru_msgsnd);
6813 SET_INT(result, 12, ru->ru_msgrcv);
6814 SET_INT(result, 13, ru->ru_nsignals);
6815 SET_INT(result, 14, ru->ru_nvcsw);
6816 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006817#undef SET_INT
6818
Victor Stinner8c62be82010-05-06 00:08:46 +00006819 if (PyErr_Occurred()) {
6820 Py_DECREF(result);
6821 return NULL;
6822 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006823
Victor Stinner8c62be82010-05-06 00:08:46 +00006824 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006825}
6826#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6827
Larry Hastings2f936352014-08-05 14:04:04 +10006828
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006830/*[clinic input]
6831os.wait3
6832
6833 options: int
6834Wait for completion of a child process.
6835
6836Returns a tuple of information about the child process:
6837 (pid, status, rusage)
6838[clinic start generated code]*/
6839
Larry Hastings2f936352014-08-05 14:04:04 +10006840static PyObject *
6841os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006842/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843{
Victor Stinner8c62be82010-05-06 00:08:46 +00006844 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006845 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006846 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006847 WAIT_TYPE status;
6848 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006850 do {
6851 Py_BEGIN_ALLOW_THREADS
6852 pid = wait3(&status, options, &ru);
6853 Py_END_ALLOW_THREADS
6854 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6855 if (pid < 0)
6856 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006857
Victor Stinner4195b5c2012-02-08 23:03:19 +01006858 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006859}
6860#endif /* HAVE_WAIT3 */
6861
Larry Hastings2f936352014-08-05 14:04:04 +10006862
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006863#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006864/*[clinic input]
6865
6866os.wait4
6867
6868 pid: pid_t
6869 options: int
6870
6871Wait for completion of a specific child process.
6872
6873Returns a tuple of information about the child process:
6874 (pid, status, rusage)
6875[clinic start generated code]*/
6876
Larry Hastings2f936352014-08-05 14:04:04 +10006877static PyObject *
6878os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006879/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006880{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006881 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006882 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006883 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006884 WAIT_TYPE status;
6885 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006886
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006887 do {
6888 Py_BEGIN_ALLOW_THREADS
6889 res = wait4(pid, &status, options, &ru);
6890 Py_END_ALLOW_THREADS
6891 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6892 if (res < 0)
6893 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006894
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006895 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006896}
6897#endif /* HAVE_WAIT4 */
6898
Larry Hastings2f936352014-08-05 14:04:04 +10006899
Ross Lagerwall7807c352011-03-17 20:20:30 +02006900#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006901/*[clinic input]
6902os.waitid
6903
6904 idtype: idtype_t
6905 Must be one of be P_PID, P_PGID or P_ALL.
6906 id: id_t
6907 The id to wait on.
6908 options: int
6909 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6910 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6911 /
6912
6913Returns the result of waiting for a process or processes.
6914
6915Returns either waitid_result or None if WNOHANG is specified and there are
6916no children in a waitable state.
6917[clinic start generated code]*/
6918
Larry Hastings2f936352014-08-05 14:04:04 +10006919static PyObject *
6920os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006921/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006922{
6923 PyObject *result;
6924 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006925 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006926 siginfo_t si;
6927 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006928
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006929 do {
6930 Py_BEGIN_ALLOW_THREADS
6931 res = waitid(idtype, id, &si, options);
6932 Py_END_ALLOW_THREADS
6933 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6934 if (res < 0)
6935 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006936
6937 if (si.si_pid == 0)
6938 Py_RETURN_NONE;
6939
6940 result = PyStructSequence_New(&WaitidResultType);
6941 if (!result)
6942 return NULL;
6943
6944 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006945 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006946 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6947 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6948 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6949 if (PyErr_Occurred()) {
6950 Py_DECREF(result);
6951 return NULL;
6952 }
6953
6954 return result;
6955}
Larry Hastings2f936352014-08-05 14:04:04 +10006956#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006957
Larry Hastings2f936352014-08-05 14:04:04 +10006958
6959#if defined(HAVE_WAITPID)
6960/*[clinic input]
6961os.waitpid
6962 pid: pid_t
6963 options: int
6964 /
6965
6966Wait for completion of a given child process.
6967
6968Returns a tuple of information regarding the child process:
6969 (pid, status)
6970
6971The options argument is ignored on Windows.
6972[clinic start generated code]*/
6973
Larry Hastings2f936352014-08-05 14:04:04 +10006974static PyObject *
6975os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006976/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006977{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006978 pid_t res;
6979 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006980 WAIT_TYPE status;
6981 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006982
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006983 do {
6984 Py_BEGIN_ALLOW_THREADS
6985 res = waitpid(pid, &status, options);
6986 Py_END_ALLOW_THREADS
6987 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6988 if (res < 0)
6989 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006990
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006991 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006992}
Tim Petersab034fa2002-02-01 11:27:43 +00006993#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006994/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006995/*[clinic input]
6996os.waitpid
6997 pid: Py_intptr_t
6998 options: int
6999 /
7000
7001Wait for completion of a given process.
7002
7003Returns a tuple of information regarding the process:
7004 (pid, status << 8)
7005
7006The options argument is ignored on Windows.
7007[clinic start generated code]*/
7008
Larry Hastings2f936352014-08-05 14:04:04 +10007009static PyObject *
7010os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007011/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007012{
7013 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007014 Py_intptr_t res;
7015 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007016
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007017 do {
7018 Py_BEGIN_ALLOW_THREADS
7019 res = _cwait(&status, pid, options);
7020 Py_END_ALLOW_THREADS
7021 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007022 if (res < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007023 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007024
Victor Stinner8c62be82010-05-06 00:08:46 +00007025 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007026 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007027}
Larry Hastings2f936352014-08-05 14:04:04 +10007028#endif
7029
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007030
Guido van Rossumad0ee831995-03-01 10:34:45 +00007031#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007032/*[clinic input]
7033os.wait
7034
7035Wait for completion of a child process.
7036
7037Returns a tuple of information about the child process:
7038 (pid, status)
7039[clinic start generated code]*/
7040
Larry Hastings2f936352014-08-05 14:04:04 +10007041static PyObject *
7042os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007043/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007044{
Victor Stinner8c62be82010-05-06 00:08:46 +00007045 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007046 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007047 WAIT_TYPE status;
7048 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007049
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007050 do {
7051 Py_BEGIN_ALLOW_THREADS
7052 pid = wait(&status);
7053 Py_END_ALLOW_THREADS
7054 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7055 if (pid < 0)
7056 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007057
Victor Stinner8c62be82010-05-06 00:08:46 +00007058 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007059}
Larry Hastings2f936352014-08-05 14:04:04 +10007060#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007061
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007062
Larry Hastings9cf065c2012-06-22 16:30:09 -07007063#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7064PyDoc_STRVAR(readlink__doc__,
7065"readlink(path, *, dir_fd=None) -> path\n\n\
7066Return a string representing the path to which the symbolic link points.\n\
7067\n\
7068If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7069 and path should be relative; path will then be relative to that directory.\n\
7070dir_fd may not be implemented on your platform.\n\
7071 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007072#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007073
Guido van Rossumb6775db1994-08-01 11:34:53 +00007074#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007075
Larry Hastings2f936352014-08-05 14:04:04 +10007076/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007077static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007078posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007079{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007080 path_t path;
7081 int dir_fd = DEFAULT_DIR_FD;
7082 char buffer[MAXPATHLEN];
7083 ssize_t length;
7084 PyObject *return_value = NULL;
7085 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007086
Larry Hastings9cf065c2012-06-22 16:30:09 -07007087 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007088 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007089 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7090 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007091 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007092 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007093
Victor Stinner8c62be82010-05-06 00:08:46 +00007094 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007095#ifdef HAVE_READLINKAT
7096 if (dir_fd != DEFAULT_DIR_FD)
7097 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007098 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007099#endif
7100 length = readlink(path.narrow, buffer, sizeof(buffer));
7101 Py_END_ALLOW_THREADS
7102
7103 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007104 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007105 goto exit;
7106 }
7107
7108 if (PyUnicode_Check(path.object))
7109 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7110 else
7111 return_value = PyBytes_FromStringAndSize(buffer, length);
7112exit:
7113 path_cleanup(&path);
7114 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007115}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007116
Guido van Rossumb6775db1994-08-01 11:34:53 +00007117#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007118
Larry Hastings2f936352014-08-05 14:04:04 +10007119#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7120
7121static PyObject *
7122win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7123{
7124 wchar_t *path;
7125 DWORD n_bytes_returned;
7126 DWORD io_result;
7127 PyObject *po, *result;
7128 int dir_fd;
7129 HANDLE reparse_point_handle;
7130
7131 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7132 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7133 wchar_t *print_name;
7134
7135 static char *keywords[] = {"path", "dir_fd", NULL};
7136
7137 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7138 &po,
7139 dir_fd_unavailable, &dir_fd
7140 ))
7141 return NULL;
7142
7143 path = PyUnicode_AsUnicode(po);
7144 if (path == NULL)
7145 return NULL;
7146
7147 /* First get a handle to the reparse point */
7148 Py_BEGIN_ALLOW_THREADS
7149 reparse_point_handle = CreateFileW(
7150 path,
7151 0,
7152 0,
7153 0,
7154 OPEN_EXISTING,
7155 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7156 0);
7157 Py_END_ALLOW_THREADS
7158
7159 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7160 return win32_error_object("readlink", po);
7161
7162 Py_BEGIN_ALLOW_THREADS
7163 /* New call DeviceIoControl to read the reparse point */
7164 io_result = DeviceIoControl(
7165 reparse_point_handle,
7166 FSCTL_GET_REPARSE_POINT,
7167 0, 0, /* in buffer */
7168 target_buffer, sizeof(target_buffer),
7169 &n_bytes_returned,
7170 0 /* we're not using OVERLAPPED_IO */
7171 );
7172 CloseHandle(reparse_point_handle);
7173 Py_END_ALLOW_THREADS
7174
7175 if (io_result==0)
7176 return win32_error_object("readlink", po);
7177
7178 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7179 {
7180 PyErr_SetString(PyExc_ValueError,
7181 "not a symbolic link");
7182 return NULL;
7183 }
7184 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7185 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7186
7187 result = PyUnicode_FromWideChar(print_name,
7188 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7189 return result;
7190}
7191
7192#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7193
7194
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007195
Larry Hastings9cf065c2012-06-22 16:30:09 -07007196#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007197
7198#if defined(MS_WINDOWS)
7199
7200/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7201static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7202static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007203
Larry Hastings9cf065c2012-06-22 16:30:09 -07007204static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007205check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007206{
7207 HINSTANCE hKernel32;
7208 /* only recheck */
7209 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7210 return 1;
7211 hKernel32 = GetModuleHandleW(L"KERNEL32");
7212 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7213 "CreateSymbolicLinkW");
7214 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7215 "CreateSymbolicLinkA");
7216 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7217}
7218
Victor Stinner31b3b922013-06-05 01:49:17 +02007219/* Remove the last portion of the path */
7220static void
7221_dirnameW(WCHAR *path)
7222{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007223 WCHAR *ptr;
7224
7225 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007226 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007227 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007228 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007229 }
7230 *ptr = 0;
7231}
7232
Victor Stinner31b3b922013-06-05 01:49:17 +02007233/* Remove the last portion of the path */
7234static void
7235_dirnameA(char *path)
7236{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007237 char *ptr;
7238
7239 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007240 for(ptr = path + strlen(path); ptr != path; ptr--) {
7241 if (*ptr == '\\' || *ptr == '/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007242 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007243 }
7244 *ptr = 0;
7245}
7246
Victor Stinner31b3b922013-06-05 01:49:17 +02007247/* Is this path absolute? */
7248static int
7249_is_absW(const WCHAR *path)
7250{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007251 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7252
7253}
7254
Victor Stinner31b3b922013-06-05 01:49:17 +02007255/* Is this path absolute? */
7256static int
7257_is_absA(const char *path)
7258{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007259 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7260
7261}
7262
Victor Stinner31b3b922013-06-05 01:49:17 +02007263/* join root and rest with a backslash */
7264static void
7265_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7266{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007267 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007268
Victor Stinner31b3b922013-06-05 01:49:17 +02007269 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007270 wcscpy(dest_path, rest);
7271 return;
7272 }
7273
7274 root_len = wcslen(root);
7275
7276 wcscpy(dest_path, root);
7277 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007278 dest_path[root_len] = L'\\';
7279 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007280 }
7281 wcscpy(dest_path+root_len, rest);
7282}
7283
Victor Stinner31b3b922013-06-05 01:49:17 +02007284/* join root and rest with a backslash */
7285static void
7286_joinA(char *dest_path, const char *root, const char *rest)
7287{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007288 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007289
Victor Stinner31b3b922013-06-05 01:49:17 +02007290 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007291 strcpy(dest_path, rest);
7292 return;
7293 }
7294
7295 root_len = strlen(root);
7296
7297 strcpy(dest_path, root);
7298 if(root_len) {
7299 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007300 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007301 }
7302 strcpy(dest_path+root_len, rest);
7303}
7304
Victor Stinner31b3b922013-06-05 01:49:17 +02007305/* Return True if the path at src relative to dest is a directory */
7306static int
7307_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007308{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007309 WIN32_FILE_ATTRIBUTE_DATA src_info;
7310 WCHAR dest_parent[MAX_PATH];
7311 WCHAR src_resolved[MAX_PATH] = L"";
7312
7313 /* dest_parent = os.path.dirname(dest) */
7314 wcscpy(dest_parent, dest);
7315 _dirnameW(dest_parent);
7316 /* src_resolved = os.path.join(dest_parent, src) */
7317 _joinW(src_resolved, dest_parent, src);
7318 return (
7319 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7320 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7321 );
7322}
7323
Victor Stinner31b3b922013-06-05 01:49:17 +02007324/* Return True if the path at src relative to dest is a directory */
7325static int
7326_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007327{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007328 WIN32_FILE_ATTRIBUTE_DATA src_info;
7329 char dest_parent[MAX_PATH];
7330 char src_resolved[MAX_PATH] = "";
7331
7332 /* dest_parent = os.path.dirname(dest) */
7333 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007334 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007335 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007336 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007337 return (
7338 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7339 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7340 );
7341}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007342#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007343
Larry Hastings2f936352014-08-05 14:04:04 +10007344
7345/*[clinic input]
7346os.symlink
7347 src: path_t
7348 dst: path_t
7349 target_is_directory: bool = False
7350 *
7351 dir_fd: dir_fd(requires='symlinkat')=None
7352
7353# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7354
7355Create a symbolic link pointing to src named dst.
7356
7357target_is_directory is required on Windows if the target is to be
7358 interpreted as a directory. (On Windows, symlink requires
7359 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7360 target_is_directory is ignored on non-Windows platforms.
7361
7362If dir_fd is not None, it should be a file descriptor open to a directory,
7363 and path should be relative; path will then be relative to that directory.
7364dir_fd may not be implemented on your platform.
7365 If it is unavailable, using it will raise a NotImplementedError.
7366
7367[clinic start generated code]*/
7368
Larry Hastings2f936352014-08-05 14:04:04 +10007369static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04007370os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst,
7371 int target_is_directory, int dir_fd)
7372/*[clinic end generated code: output=a01b4bcf32403ccd input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007373{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007374#ifdef MS_WINDOWS
7375 DWORD result;
7376#else
7377 int result;
7378#endif
7379
Larry Hastings9cf065c2012-06-22 16:30:09 -07007380#ifdef MS_WINDOWS
7381 if (!check_CreateSymbolicLink()) {
7382 PyErr_SetString(PyExc_NotImplementedError,
7383 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007384 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007385 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007386 if (!win32_can_symlink) {
7387 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007388 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007389 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390#endif
7391
Larry Hastings2f936352014-08-05 14:04:04 +10007392 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007393 PyErr_SetString(PyExc_ValueError,
7394 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007395 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396 }
7397
7398#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007399
Larry Hastings9cf065c2012-06-22 16:30:09 -07007400 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007401 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007402 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007403 target_is_directory |= _check_dirW(src->wide, dst->wide);
7404 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007405 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007406 }
7407 else {
7408 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007409 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7410 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007411 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007412 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007413 Py_END_ALLOW_THREADS
7414
Larry Hastings2f936352014-08-05 14:04:04 +10007415 if (!result)
7416 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007417
7418#else
7419
7420 Py_BEGIN_ALLOW_THREADS
7421#if HAVE_SYMLINKAT
7422 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007423 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007424 else
7425#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007426 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007427 Py_END_ALLOW_THREADS
7428
Larry Hastings2f936352014-08-05 14:04:04 +10007429 if (result)
7430 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007431#endif
7432
Larry Hastings2f936352014-08-05 14:04:04 +10007433 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007434}
7435#endif /* HAVE_SYMLINK */
7436
Larry Hastings9cf065c2012-06-22 16:30:09 -07007437
Brian Curtind40e6f72010-07-08 21:39:08 +00007438
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007439
Larry Hastings605a62d2012-06-24 04:33:36 -07007440static PyStructSequence_Field times_result_fields[] = {
7441 {"user", "user time"},
7442 {"system", "system time"},
7443 {"children_user", "user time of children"},
7444 {"children_system", "system time of children"},
7445 {"elapsed", "elapsed time since an arbitrary point in the past"},
7446 {NULL}
7447};
7448
7449PyDoc_STRVAR(times_result__doc__,
7450"times_result: Result from os.times().\n\n\
7451This object may be accessed either as a tuple of\n\
7452 (user, system, children_user, children_system, elapsed),\n\
7453or via the attributes user, system, children_user, children_system,\n\
7454and elapsed.\n\
7455\n\
7456See os.times for more information.");
7457
7458static PyStructSequence_Desc times_result_desc = {
7459 "times_result", /* name */
7460 times_result__doc__, /* doc */
7461 times_result_fields,
7462 5
7463};
7464
7465static PyTypeObject TimesResultType;
7466
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007467#ifdef MS_WINDOWS
7468#define HAVE_TIMES /* mandatory, for the method table */
7469#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007470
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007471#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007472
7473static PyObject *
7474build_times_result(double user, double system,
7475 double children_user, double children_system,
7476 double elapsed)
7477{
7478 PyObject *value = PyStructSequence_New(&TimesResultType);
7479 if (value == NULL)
7480 return NULL;
7481
7482#define SET(i, field) \
7483 { \
7484 PyObject *o = PyFloat_FromDouble(field); \
7485 if (!o) { \
7486 Py_DECREF(value); \
7487 return NULL; \
7488 } \
7489 PyStructSequence_SET_ITEM(value, i, o); \
7490 } \
7491
7492 SET(0, user);
7493 SET(1, system);
7494 SET(2, children_user);
7495 SET(3, children_system);
7496 SET(4, elapsed);
7497
7498#undef SET
7499
7500 return value;
7501}
7502
Larry Hastings605a62d2012-06-24 04:33:36 -07007503
Larry Hastings2f936352014-08-05 14:04:04 +10007504#ifndef MS_WINDOWS
7505#define NEED_TICKS_PER_SECOND
7506static long ticks_per_second = -1;
7507#endif /* MS_WINDOWS */
7508
7509/*[clinic input]
7510os.times
7511
7512Return a collection containing process timing information.
7513
7514The object returned behaves like a named tuple with these fields:
7515 (utime, stime, cutime, cstime, elapsed_time)
7516All fields are floating point numbers.
7517[clinic start generated code]*/
7518
Larry Hastings2f936352014-08-05 14:04:04 +10007519static PyObject *
7520os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007521/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007522#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007523{
Victor Stinner8c62be82010-05-06 00:08:46 +00007524 FILETIME create, exit, kernel, user;
7525 HANDLE hProc;
7526 hProc = GetCurrentProcess();
7527 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7528 /* The fields of a FILETIME structure are the hi and lo part
7529 of a 64-bit value expressed in 100 nanosecond units.
7530 1e7 is one second in such units; 1e-7 the inverse.
7531 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7532 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007533 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007534 (double)(user.dwHighDateTime*429.4967296 +
7535 user.dwLowDateTime*1e-7),
7536 (double)(kernel.dwHighDateTime*429.4967296 +
7537 kernel.dwLowDateTime*1e-7),
7538 (double)0,
7539 (double)0,
7540 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007541}
Larry Hastings2f936352014-08-05 14:04:04 +10007542#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007543{
Larry Hastings2f936352014-08-05 14:04:04 +10007544
7545
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007546 struct tms t;
7547 clock_t c;
7548 errno = 0;
7549 c = times(&t);
7550 if (c == (clock_t) -1)
7551 return posix_error();
7552 return build_times_result(
7553 (double)t.tms_utime / ticks_per_second,
7554 (double)t.tms_stime / ticks_per_second,
7555 (double)t.tms_cutime / ticks_per_second,
7556 (double)t.tms_cstime / ticks_per_second,
7557 (double)c / ticks_per_second);
7558}
Larry Hastings2f936352014-08-05 14:04:04 +10007559#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007560#endif /* HAVE_TIMES */
7561
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007562
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007563#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007564/*[clinic input]
7565os.getsid
7566
7567 pid: pid_t
7568 /
7569
7570Call the system call getsid(pid) and return the result.
7571[clinic start generated code]*/
7572
Larry Hastings2f936352014-08-05 14:04:04 +10007573static PyObject *
7574os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007575/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007576{
Victor Stinner8c62be82010-05-06 00:08:46 +00007577 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007578 sid = getsid(pid);
7579 if (sid < 0)
7580 return posix_error();
7581 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007582}
7583#endif /* HAVE_GETSID */
7584
7585
Guido van Rossumb6775db1994-08-01 11:34:53 +00007586#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007587/*[clinic input]
7588os.setsid
7589
7590Call the system call setsid().
7591[clinic start generated code]*/
7592
Larry Hastings2f936352014-08-05 14:04:04 +10007593static PyObject *
7594os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007595/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007596{
Victor Stinner8c62be82010-05-06 00:08:46 +00007597 if (setsid() < 0)
7598 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007599 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007600}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007601#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007602
Larry Hastings2f936352014-08-05 14:04:04 +10007603
Guido van Rossumb6775db1994-08-01 11:34:53 +00007604#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007605/*[clinic input]
7606os.setpgid
7607
7608 pid: pid_t
7609 pgrp: pid_t
7610 /
7611
7612Call the system call setpgid(pid, pgrp).
7613[clinic start generated code]*/
7614
Larry Hastings2f936352014-08-05 14:04:04 +10007615static PyObject *
7616os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007617/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007618{
Victor Stinner8c62be82010-05-06 00:08:46 +00007619 if (setpgid(pid, pgrp) < 0)
7620 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007621 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007622}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007623#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007624
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007625
Guido van Rossumb6775db1994-08-01 11:34:53 +00007626#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007627/*[clinic input]
7628os.tcgetpgrp
7629
7630 fd: int
7631 /
7632
7633Return the process group associated with the terminal specified by fd.
7634[clinic start generated code]*/
7635
Larry Hastings2f936352014-08-05 14:04:04 +10007636static PyObject *
7637os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007638/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007639{
7640 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007641 if (pgid < 0)
7642 return posix_error();
7643 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007644}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007645#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007646
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007647
Guido van Rossumb6775db1994-08-01 11:34:53 +00007648#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007649/*[clinic input]
7650os.tcsetpgrp
7651
7652 fd: int
7653 pgid: pid_t
7654 /
7655
7656Set the process group associated with the terminal specified by fd.
7657[clinic start generated code]*/
7658
Larry Hastings2f936352014-08-05 14:04:04 +10007659static PyObject *
7660os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007661/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007662{
Victor Stinner8c62be82010-05-06 00:08:46 +00007663 if (tcsetpgrp(fd, pgid) < 0)
7664 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007665 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007666}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007667#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007668
Guido van Rossum687dd131993-05-17 08:34:16 +00007669/* Functions acting on file descriptors */
7670
Victor Stinnerdaf45552013-08-28 00:53:59 +02007671#ifdef O_CLOEXEC
7672extern int _Py_open_cloexec_works;
7673#endif
7674
Larry Hastings2f936352014-08-05 14:04:04 +10007675
7676/*[clinic input]
7677os.open -> int
7678 path: path_t
7679 flags: int
7680 mode: int = 0o777
7681 *
7682 dir_fd: dir_fd(requires='openat') = None
7683
7684# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7685
7686Open a file for low level IO. Returns a file descriptor (integer).
7687
7688If dir_fd is not None, it should be a file descriptor open to a directory,
7689 and path should be relative; path will then be relative to that directory.
7690dir_fd may not be implemented on your platform.
7691 If it is unavailable, using it will raise a NotImplementedError.
7692[clinic start generated code]*/
7693
Larry Hastings2f936352014-08-05 14:04:04 +10007694static int
Larry Hastings89964c42015-04-14 18:07:59 -04007695os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode,
7696 int dir_fd)
7697/*[clinic end generated code: output=47e8cc63559f5ddd input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007698{
7699 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007700 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007701
Victor Stinnerdaf45552013-08-28 00:53:59 +02007702#ifdef O_CLOEXEC
7703 int *atomic_flag_works = &_Py_open_cloexec_works;
7704#elif !defined(MS_WINDOWS)
7705 int *atomic_flag_works = NULL;
7706#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007707
Victor Stinnerdaf45552013-08-28 00:53:59 +02007708#ifdef MS_WINDOWS
7709 flags |= O_NOINHERIT;
7710#elif defined(O_CLOEXEC)
7711 flags |= O_CLOEXEC;
7712#endif
7713
Steve Dower8fc89802015-04-12 00:26:27 -04007714 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007715 do {
7716 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007717#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007718 if (path->wide)
7719 fd = _wopen(path->wide, flags, mode);
7720 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007721#endif
7722#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007723 if (dir_fd != DEFAULT_DIR_FD)
7724 fd = openat(dir_fd, path->narrow, flags, mode);
7725 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007726#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007727 fd = open(path->narrow, flags, mode);
7728 Py_END_ALLOW_THREADS
7729 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007730 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007731
Victor Stinnerd3ffd322015-09-15 10:11:03 +02007732 if (fd < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007733 if (!async_err)
7734 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007735 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007736 }
7737
Victor Stinnerdaf45552013-08-28 00:53:59 +02007738#ifndef MS_WINDOWS
7739 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7740 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007741 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007742 }
7743#endif
7744
Larry Hastings2f936352014-08-05 14:04:04 +10007745 return fd;
7746}
7747
7748
7749/*[clinic input]
7750os.close
7751
7752 fd: int
7753
7754Close a file descriptor.
7755[clinic start generated code]*/
7756
Barry Warsaw53699e91996-12-10 23:23:01 +00007757static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007758os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007759/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007760{
Larry Hastings2f936352014-08-05 14:04:04 +10007761 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007762 if (!_PyVerify_fd(fd))
7763 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007764 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7765 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7766 * for more details.
7767 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007768 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007769 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007770 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007771 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007772 Py_END_ALLOW_THREADS
7773 if (res < 0)
7774 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007775 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007776}
7777
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007778
Larry Hastings2f936352014-08-05 14:04:04 +10007779/*[clinic input]
7780os.closerange
7781
7782 fd_low: int
7783 fd_high: int
7784 /
7785
7786Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7787[clinic start generated code]*/
7788
Larry Hastings2f936352014-08-05 14:04:04 +10007789static PyObject *
7790os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007791/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007792{
7793 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007794 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007795 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007796 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007797 if (_PyVerify_fd(i))
7798 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007799 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007800 Py_END_ALLOW_THREADS
7801 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007802}
7803
7804
Larry Hastings2f936352014-08-05 14:04:04 +10007805/*[clinic input]
7806os.dup -> int
7807
7808 fd: int
7809 /
7810
7811Return a duplicate of a file descriptor.
7812[clinic start generated code]*/
7813
Larry Hastings2f936352014-08-05 14:04:04 +10007814static int
7815os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007816/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007817{
7818 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007819}
7820
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007821
Larry Hastings2f936352014-08-05 14:04:04 +10007822/*[clinic input]
7823os.dup2
7824 fd: int
7825 fd2: int
7826 inheritable: bool=True
7827
7828Duplicate file descriptor.
7829[clinic start generated code]*/
7830
Larry Hastings2f936352014-08-05 14:04:04 +10007831static PyObject *
7832os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007833/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007834{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007835 int res;
7836#if defined(HAVE_DUP3) && \
7837 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7838 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7839 int dup3_works = -1;
7840#endif
7841
Victor Stinner8c62be82010-05-06 00:08:46 +00007842 if (!_PyVerify_fd_dup2(fd, fd2))
7843 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007844
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007845 /* dup2() can fail with EINTR if the target FD is already open, because it
7846 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7847 * upon close(), and therefore below.
7848 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007849#ifdef MS_WINDOWS
7850 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007851 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007852 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007853 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007854 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007855 if (res < 0)
7856 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007857
7858 /* Character files like console cannot be make non-inheritable */
7859 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7860 close(fd2);
7861 return NULL;
7862 }
7863
7864#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7865 Py_BEGIN_ALLOW_THREADS
7866 if (!inheritable)
7867 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7868 else
7869 res = dup2(fd, fd2);
7870 Py_END_ALLOW_THREADS
7871 if (res < 0)
7872 return posix_error();
7873
7874#else
7875
7876#ifdef HAVE_DUP3
7877 if (!inheritable && dup3_works != 0) {
7878 Py_BEGIN_ALLOW_THREADS
7879 res = dup3(fd, fd2, O_CLOEXEC);
7880 Py_END_ALLOW_THREADS
7881 if (res < 0) {
7882 if (dup3_works == -1)
7883 dup3_works = (errno != ENOSYS);
7884 if (dup3_works)
7885 return posix_error();
7886 }
7887 }
7888
7889 if (inheritable || dup3_works == 0)
7890 {
7891#endif
7892 Py_BEGIN_ALLOW_THREADS
7893 res = dup2(fd, fd2);
7894 Py_END_ALLOW_THREADS
7895 if (res < 0)
7896 return posix_error();
7897
7898 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7899 close(fd2);
7900 return NULL;
7901 }
7902#ifdef HAVE_DUP3
7903 }
7904#endif
7905
7906#endif
7907
Larry Hastings2f936352014-08-05 14:04:04 +10007908 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007909}
7910
Larry Hastings2f936352014-08-05 14:04:04 +10007911
Ross Lagerwall7807c352011-03-17 20:20:30 +02007912#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007913/*[clinic input]
7914os.lockf
7915
7916 fd: int
7917 An open file descriptor.
7918 command: int
7919 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7920 length: Py_off_t
7921 The number of bytes to lock, starting at the current position.
7922 /
7923
7924Apply, test or remove a POSIX lock on an open file descriptor.
7925
7926[clinic start generated code]*/
7927
Larry Hastings2f936352014-08-05 14:04:04 +10007928static PyObject *
7929os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007930/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007931{
7932 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007933
7934 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007935 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007936 Py_END_ALLOW_THREADS
7937
7938 if (res < 0)
7939 return posix_error();
7940
7941 Py_RETURN_NONE;
7942}
Larry Hastings2f936352014-08-05 14:04:04 +10007943#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007944
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007945
Larry Hastings2f936352014-08-05 14:04:04 +10007946/*[clinic input]
7947os.lseek -> Py_off_t
7948
7949 fd: int
7950 position: Py_off_t
7951 how: int
7952 /
7953
7954Set the position of a file descriptor. Return the new position.
7955
7956Return the new cursor position in number of bytes
7957relative to the beginning of the file.
7958[clinic start generated code]*/
7959
Larry Hastings2f936352014-08-05 14:04:04 +10007960static Py_off_t
7961os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007962/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007963{
7964 Py_off_t result;
7965
7966 if (!_PyVerify_fd(fd)) {
7967 posix_error();
7968 return -1;
7969 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007970#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007971 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7972 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007973 case 0: how = SEEK_SET; break;
7974 case 1: how = SEEK_CUR; break;
7975 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007976 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007977#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007978
Victor Stinner8c62be82010-05-06 00:08:46 +00007979 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007980 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007981
Larry Hastings2f936352014-08-05 14:04:04 +10007982 if (!_PyVerify_fd(fd)) {
7983 posix_error();
7984 return -1;
7985 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007986 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007987 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007988#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007989 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007990#else
Larry Hastings2f936352014-08-05 14:04:04 +10007991 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007992#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007993 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007994 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007995 if (result < 0)
7996 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007997
Larry Hastings2f936352014-08-05 14:04:04 +10007998 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007999}
8000
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008001
Larry Hastings2f936352014-08-05 14:04:04 +10008002/*[clinic input]
8003os.read
8004 fd: int
8005 length: Py_ssize_t
8006 /
8007
8008Read from a file descriptor. Returns a bytes object.
8009[clinic start generated code]*/
8010
Larry Hastings2f936352014-08-05 14:04:04 +10008011static PyObject *
8012os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008013/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008014{
Victor Stinner8c62be82010-05-06 00:08:46 +00008015 Py_ssize_t n;
8016 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008017
8018 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 errno = EINVAL;
8020 return posix_error();
8021 }
Larry Hastings2f936352014-08-05 14:04:04 +10008022
8023#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008024 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008025 if (length > INT_MAX)
8026 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008027#endif
8028
8029 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008030 if (buffer == NULL)
8031 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008032
Victor Stinner66aab0c2015-03-19 22:53:20 +01008033 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8034 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008035 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008036 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008037 }
Larry Hastings2f936352014-08-05 14:04:04 +10008038
8039 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008040 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008041
Victor Stinner8c62be82010-05-06 00:08:46 +00008042 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008043}
8044
Ross Lagerwall7807c352011-03-17 20:20:30 +02008045#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8046 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008047static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8049{
8050 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008051 Py_ssize_t blen, total = 0;
8052
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008053 *iov = PyMem_New(struct iovec, cnt);
8054 if (*iov == NULL) {
8055 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008056 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008058
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 *buf = PyMem_New(Py_buffer, cnt);
8060 if (*buf == NULL) {
8061 PyMem_Del(*iov);
8062 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008063 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008064 }
8065
8066 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008067 PyObject *item = PySequence_GetItem(seq, i);
8068 if (item == NULL)
8069 goto fail;
8070 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8071 Py_DECREF(item);
8072 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008074 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008075 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008076 blen = (*buf)[i].len;
8077 (*iov)[i].iov_len = blen;
8078 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008079 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008080 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008081
8082fail:
8083 PyMem_Del(*iov);
8084 for (j = 0; j < i; j++) {
8085 PyBuffer_Release(&(*buf)[j]);
8086 }
8087 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008088 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008089}
8090
8091static void
8092iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8093{
8094 int i;
8095 PyMem_Del(iov);
8096 for (i = 0; i < cnt; i++) {
8097 PyBuffer_Release(&buf[i]);
8098 }
8099 PyMem_Del(buf);
8100}
8101#endif
8102
Larry Hastings2f936352014-08-05 14:04:04 +10008103
Ross Lagerwall7807c352011-03-17 20:20:30 +02008104#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008105/*[clinic input]
8106os.readv -> Py_ssize_t
8107
8108 fd: int
8109 buffers: object
8110 /
8111
8112Read from a file descriptor fd into an iterable of buffers.
8113
8114The buffers should be mutable buffers accepting bytes.
8115readv will transfer data into each buffer until it is full
8116and then move on to the next buffer in the sequence to hold
8117the rest of the data.
8118
8119readv returns the total number of bytes read,
8120which may be less than the total capacity of all the buffers.
8121[clinic start generated code]*/
8122
Larry Hastings2f936352014-08-05 14:04:04 +10008123static Py_ssize_t
8124os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008125/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008126{
8127 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008128 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008129 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008130 struct iovec *iov;
8131 Py_buffer *buf;
8132
Larry Hastings2f936352014-08-05 14:04:04 +10008133 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008134 PyErr_SetString(PyExc_TypeError,
8135 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008136 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008137 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008138
Larry Hastings2f936352014-08-05 14:04:04 +10008139 cnt = PySequence_Size(buffers);
8140
8141 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8142 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008143
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008144 do {
8145 Py_BEGIN_ALLOW_THREADS
8146 n = readv(fd, iov, cnt);
8147 Py_END_ALLOW_THREADS
8148 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008149
8150 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008151 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008152 if (!async_err)
8153 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008154 return -1;
8155 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008156
Larry Hastings2f936352014-08-05 14:04:04 +10008157 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008158}
Larry Hastings2f936352014-08-05 14:04:04 +10008159#endif /* HAVE_READV */
8160
Ross Lagerwall7807c352011-03-17 20:20:30 +02008161
8162#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008163/*[clinic input]
8164# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8165os.pread
8166
8167 fd: int
8168 length: int
8169 offset: Py_off_t
8170 /
8171
8172Read a number of bytes from a file descriptor starting at a particular offset.
8173
8174Read length bytes from file descriptor fd, starting at offset bytes from
8175the beginning of the file. The file offset remains unchanged.
8176[clinic start generated code]*/
8177
Larry Hastings2f936352014-08-05 14:04:04 +10008178static PyObject *
8179os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008180/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008181{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008182 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008183 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008184 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008185
Larry Hastings2f936352014-08-05 14:04:04 +10008186 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008187 errno = EINVAL;
8188 return posix_error();
8189 }
Larry Hastings2f936352014-08-05 14:04:04 +10008190 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008191 if (buffer == NULL)
8192 return NULL;
8193 if (!_PyVerify_fd(fd)) {
8194 Py_DECREF(buffer);
8195 return posix_error();
8196 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008197
8198 do {
8199 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008200 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008201 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008202 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008203 Py_END_ALLOW_THREADS
8204 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8205
Ross Lagerwall7807c352011-03-17 20:20:30 +02008206 if (n < 0) {
8207 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008208 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008209 }
Larry Hastings2f936352014-08-05 14:04:04 +10008210 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008211 _PyBytes_Resize(&buffer, n);
8212 return buffer;
8213}
Larry Hastings2f936352014-08-05 14:04:04 +10008214#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008215
Larry Hastings2f936352014-08-05 14:04:04 +10008216
8217/*[clinic input]
8218os.write -> Py_ssize_t
8219
8220 fd: int
8221 data: Py_buffer
8222 /
8223
8224Write a bytes object to a file descriptor.
8225[clinic start generated code]*/
8226
Larry Hastings2f936352014-08-05 14:04:04 +10008227static Py_ssize_t
8228os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008229/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008230{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008231 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008232}
8233
8234#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008235PyDoc_STRVAR(posix_sendfile__doc__,
Martin Panterbf19d162015-09-09 01:01:13 +00008236"sendfile(out, in, offset, count) -> byteswritten\n\
Martin Panter94994132015-09-09 05:29:24 +00008237sendfile(out, in, offset, count[, headers][, trailers], flags=0)\n\
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008238 -> byteswritten\n\
Martin Panterbf19d162015-09-09 01:01:13 +00008239Copy count bytes from file descriptor in to file descriptor out.");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008240
Larry Hastings2f936352014-08-05 14:04:04 +10008241/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008242static PyObject *
8243posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8244{
8245 int in, out;
8246 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008247 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008248 off_t offset;
8249
8250#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8251#ifndef __APPLE__
8252 Py_ssize_t len;
8253#endif
8254 PyObject *headers = NULL, *trailers = NULL;
8255 Py_buffer *hbuf, *tbuf;
8256 off_t sbytes;
8257 struct sf_hdtr sf;
8258 int flags = 0;
Martin Panterbf19d162015-09-09 01:01:13 +00008259 /* Beware that "in" clashes with Python's own "in" operator keyword */
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008260 static char *keywords[] = {"out", "in",
8261 "offset", "count",
8262 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008263
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008264 sf.headers = NULL;
8265 sf.trailers = NULL;
8266
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008267#ifdef __APPLE__
8268 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008269 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008270#else
8271 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008272 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008273#endif
8274 &headers, &trailers, &flags))
8275 return NULL;
8276 if (headers != NULL) {
8277 if (!PySequence_Check(headers)) {
8278 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008279 "sendfile() headers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008280 return NULL;
8281 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008282 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008283 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008284 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008285 (i = iov_setup(&(sf.headers), &hbuf,
8286 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008287 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008288#ifdef __APPLE__
8289 sbytes += i;
8290#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008291 }
8292 }
8293 if (trailers != NULL) {
8294 if (!PySequence_Check(trailers)) {
8295 PyErr_SetString(PyExc_TypeError,
Martin Panter94994132015-09-09 05:29:24 +00008296 "sendfile() trailers must be a sequence");
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008297 return NULL;
8298 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008299 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008300 sf.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008301 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008302 (i = iov_setup(&(sf.trailers), &tbuf,
8303 trailers, sf.trl_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008304 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008305#ifdef __APPLE__
8306 sbytes += i;
8307#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008308 }
8309 }
8310
Steve Dower8fc89802015-04-12 00:26:27 -04008311 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008312 do {
8313 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008314#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008315 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008316#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008317 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008318#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008319 Py_END_ALLOW_THREADS
8320 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008321 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008322
8323 if (sf.headers != NULL)
8324 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8325 if (sf.trailers != NULL)
8326 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8327
8328 if (ret < 0) {
8329 if ((errno == EAGAIN) || (errno == EBUSY)) {
8330 if (sbytes != 0) {
8331 // some data has been sent
8332 goto done;
8333 }
8334 else {
8335 // no data has been sent; upper application is supposed
8336 // to retry on EAGAIN or EBUSY
8337 return posix_error();
8338 }
8339 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008340 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008341 }
8342 goto done;
8343
8344done:
8345 #if !defined(HAVE_LARGEFILE_SUPPORT)
8346 return Py_BuildValue("l", sbytes);
8347 #else
8348 return Py_BuildValue("L", sbytes);
8349 #endif
8350
8351#else
8352 Py_ssize_t count;
8353 PyObject *offobj;
8354 static char *keywords[] = {"out", "in",
8355 "offset", "count", NULL};
8356 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8357 keywords, &out, &in, &offobj, &count))
8358 return NULL;
8359#ifdef linux
8360 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008361 do {
8362 Py_BEGIN_ALLOW_THREADS
8363 ret = sendfile(out, in, NULL, count);
8364 Py_END_ALLOW_THREADS
8365 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008366 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008367 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008368 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008369 }
8370#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008371 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008372 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008373
8374 do {
8375 Py_BEGIN_ALLOW_THREADS
8376 ret = sendfile(out, in, &offset, count);
8377 Py_END_ALLOW_THREADS
8378 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008379 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008380 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008381 return Py_BuildValue("n", ret);
8382#endif
8383}
Larry Hastings2f936352014-08-05 14:04:04 +10008384#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008385
Larry Hastings2f936352014-08-05 14:04:04 +10008386
8387/*[clinic input]
8388os.fstat
8389
8390 fd : int
8391
8392Perform a stat system call on the given file descriptor.
8393
8394Like stat(), but for an open file descriptor.
8395Equivalent to os.stat(fd).
8396[clinic start generated code]*/
8397
Larry Hastings2f936352014-08-05 14:04:04 +10008398static PyObject *
8399os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008400/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008401{
Victor Stinner8c62be82010-05-06 00:08:46 +00008402 STRUCT_STAT st;
8403 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008404 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008405
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008406 do {
8407 Py_BEGIN_ALLOW_THREADS
8408 res = FSTAT(fd, &st);
8409 Py_END_ALLOW_THREADS
8410 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008411 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008412#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008413 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008414#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008415 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008416#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008417 }
Tim Peters5aa91602002-01-30 05:46:57 +00008418
Victor Stinner4195b5c2012-02-08 23:03:19 +01008419 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008420}
8421
Larry Hastings2f936352014-08-05 14:04:04 +10008422
8423/*[clinic input]
8424os.isatty -> bool
8425 fd: int
8426 /
8427
8428Return True if the fd is connected to a terminal.
8429
8430Return True if the file descriptor is an open file descriptor
8431connected to the slave end of a terminal.
8432[clinic start generated code]*/
8433
Larry Hastings2f936352014-08-05 14:04:04 +10008434static int
8435os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008436/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008437{
Steve Dower8fc89802015-04-12 00:26:27 -04008438 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008439 if (!_PyVerify_fd(fd))
8440 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008441 _Py_BEGIN_SUPPRESS_IPH
8442 return_value = isatty(fd);
8443 _Py_END_SUPPRESS_IPH
8444 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008445}
8446
8447
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008448#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008449/*[clinic input]
8450os.pipe
8451
8452Create a pipe.
8453
8454Returns a tuple of two file descriptors:
8455 (read_fd, write_fd)
8456[clinic start generated code]*/
8457
Larry Hastings2f936352014-08-05 14:04:04 +10008458static PyObject *
8459os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008460/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008461{
Victor Stinner8c62be82010-05-06 00:08:46 +00008462 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008463#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008464 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008465 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008466 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008467#else
8468 int res;
8469#endif
8470
8471#ifdef MS_WINDOWS
8472 attr.nLength = sizeof(attr);
8473 attr.lpSecurityDescriptor = NULL;
8474 attr.bInheritHandle = FALSE;
8475
8476 Py_BEGIN_ALLOW_THREADS
8477 ok = CreatePipe(&read, &write, &attr, 0);
8478 if (ok) {
8479 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8480 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8481 if (fds[0] == -1 || fds[1] == -1) {
8482 CloseHandle(read);
8483 CloseHandle(write);
8484 ok = 0;
8485 }
8486 }
8487 Py_END_ALLOW_THREADS
8488
Victor Stinner8c62be82010-05-06 00:08:46 +00008489 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008490 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008491#else
8492
8493#ifdef HAVE_PIPE2
8494 Py_BEGIN_ALLOW_THREADS
8495 res = pipe2(fds, O_CLOEXEC);
8496 Py_END_ALLOW_THREADS
8497
8498 if (res != 0 && errno == ENOSYS)
8499 {
8500#endif
8501 Py_BEGIN_ALLOW_THREADS
8502 res = pipe(fds);
8503 Py_END_ALLOW_THREADS
8504
8505 if (res == 0) {
8506 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8507 close(fds[0]);
8508 close(fds[1]);
8509 return NULL;
8510 }
8511 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8512 close(fds[0]);
8513 close(fds[1]);
8514 return NULL;
8515 }
8516 }
8517#ifdef HAVE_PIPE2
8518 }
8519#endif
8520
8521 if (res != 0)
8522 return PyErr_SetFromErrno(PyExc_OSError);
8523#endif /* !MS_WINDOWS */
8524 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008525}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008526#endif /* HAVE_PIPE */
8527
Larry Hastings2f936352014-08-05 14:04:04 +10008528
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008529#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008530/*[clinic input]
8531os.pipe2
8532
8533 flags: int
8534 /
8535
8536Create a pipe with flags set atomically.
8537
8538Returns a tuple of two file descriptors:
8539 (read_fd, write_fd)
8540
8541flags can be constructed by ORing together one or more of these values:
8542O_NONBLOCK, O_CLOEXEC.
8543[clinic start generated code]*/
8544
Larry Hastings2f936352014-08-05 14:04:04 +10008545static PyObject *
8546os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008547/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008548{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008549 int fds[2];
8550 int res;
8551
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008552 res = pipe2(fds, flags);
8553 if (res != 0)
8554 return posix_error();
8555 return Py_BuildValue("(ii)", fds[0], fds[1]);
8556}
8557#endif /* HAVE_PIPE2 */
8558
Larry Hastings2f936352014-08-05 14:04:04 +10008559
Ross Lagerwall7807c352011-03-17 20:20:30 +02008560#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008561/*[clinic input]
8562os.writev -> Py_ssize_t
8563 fd: int
8564 buffers: object
8565 /
8566
8567Iterate over buffers, and write the contents of each to a file descriptor.
8568
8569Returns the total number of bytes written.
8570buffers must be a sequence of bytes-like objects.
8571[clinic start generated code]*/
8572
Larry Hastings2f936352014-08-05 14:04:04 +10008573static Py_ssize_t
8574os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008575/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008576{
8577 int cnt;
8578 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008579 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008580 struct iovec *iov;
8581 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008582
8583 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008584 PyErr_SetString(PyExc_TypeError,
8585 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008586 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008587 }
Larry Hastings2f936352014-08-05 14:04:04 +10008588 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008589
Larry Hastings2f936352014-08-05 14:04:04 +10008590 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8591 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008592 }
8593
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008594 do {
8595 Py_BEGIN_ALLOW_THREADS
8596 result = writev(fd, iov, cnt);
8597 Py_END_ALLOW_THREADS
8598 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008599
8600 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008601 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008602 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008603
Georg Brandl306336b2012-06-24 12:55:33 +02008604 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008605}
Larry Hastings2f936352014-08-05 14:04:04 +10008606#endif /* HAVE_WRITEV */
8607
8608
8609#ifdef HAVE_PWRITE
8610/*[clinic input]
8611os.pwrite -> Py_ssize_t
8612
8613 fd: int
8614 buffer: Py_buffer
8615 offset: Py_off_t
8616 /
8617
8618Write bytes to a file descriptor starting at a particular offset.
8619
8620Write buffer to fd, starting at offset bytes from the beginning of
8621the file. Returns the number of bytes writte. Does not change the
8622current file offset.
8623[clinic start generated code]*/
8624
Larry Hastings2f936352014-08-05 14:04:04 +10008625static Py_ssize_t
Larry Hastings89964c42015-04-14 18:07:59 -04008626os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer,
8627 Py_off_t offset)
8628/*[clinic end generated code: output=93aabdb40e17d325 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008629{
8630 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008631 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008632
8633 if (!_PyVerify_fd(fd)) {
8634 posix_error();
8635 return -1;
8636 }
8637
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008638 do {
8639 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008640 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008641 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008642 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008643 Py_END_ALLOW_THREADS
8644 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008645
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008646 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008647 posix_error();
8648 return size;
8649}
8650#endif /* HAVE_PWRITE */
8651
8652
8653#ifdef HAVE_MKFIFO
8654/*[clinic input]
8655os.mkfifo
8656
8657 path: path_t
8658 mode: int=0o666
8659 *
8660 dir_fd: dir_fd(requires='mkfifoat')=None
8661
8662Create a "fifo" (a POSIX named pipe).
8663
8664If dir_fd is not None, it should be a file descriptor open to a directory,
8665 and path should be relative; path will then be relative to that directory.
8666dir_fd may not be implemented on your platform.
8667 If it is unavailable, using it will raise a NotImplementedError.
8668[clinic start generated code]*/
8669
Larry Hastings2f936352014-08-05 14:04:04 +10008670static PyObject *
8671os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008672/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008673{
8674 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008675 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008676
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008677 do {
8678 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008679#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008680 if (dir_fd != DEFAULT_DIR_FD)
8681 result = mkfifoat(dir_fd, path->narrow, mode);
8682 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008683#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008684 result = mkfifo(path->narrow, mode);
8685 Py_END_ALLOW_THREADS
8686 } while (result != 0 && errno == EINTR &&
8687 !(async_err = PyErr_CheckSignals()));
8688 if (result != 0)
8689 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008690
8691 Py_RETURN_NONE;
8692}
8693#endif /* HAVE_MKFIFO */
8694
8695
8696#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8697/*[clinic input]
8698os.mknod
8699
8700 path: path_t
8701 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008702 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008703 *
8704 dir_fd: dir_fd(requires='mknodat')=None
8705
8706Create a node in the file system.
8707
8708Create a node in the file system (file, device special file or named pipe)
8709at path. mode specifies both the permissions to use and the
8710type of node to be created, being combined (bitwise OR) with one of
8711S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8712device defines the newly created device special file (probably using
8713os.makedev()). Otherwise device is ignored.
8714
8715If dir_fd is not None, it should be a file descriptor open to a directory,
8716 and path should be relative; path will then be relative to that directory.
8717dir_fd may not be implemented on your platform.
8718 If it is unavailable, using it will raise a NotImplementedError.
8719[clinic start generated code]*/
8720
Larry Hastings2f936352014-08-05 14:04:04 +10008721static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008722os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device,
8723 int dir_fd)
8724/*[clinic end generated code: output=5151a8a9f754d272 input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008725{
8726 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008727 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008728
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008729 do {
8730 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008731#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008732 if (dir_fd != DEFAULT_DIR_FD)
8733 result = mknodat(dir_fd, path->narrow, mode, device);
8734 else
Larry Hastings2f936352014-08-05 14:04:04 +10008735#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008736 result = mknod(path->narrow, mode, device);
8737 Py_END_ALLOW_THREADS
8738 } while (result != 0 && errno == EINTR &&
8739 !(async_err = PyErr_CheckSignals()));
8740 if (result != 0)
8741 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008742
8743 Py_RETURN_NONE;
8744}
8745#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8746
8747
8748#ifdef HAVE_DEVICE_MACROS
8749/*[clinic input]
8750os.major -> unsigned_int
8751
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008752 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008753 /
8754
8755Extracts a device major number from a raw device number.
8756[clinic start generated code]*/
8757
Larry Hastings2f936352014-08-05 14:04:04 +10008758static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008759os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008760/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008761{
8762 return major(device);
8763}
8764
8765
8766/*[clinic input]
8767os.minor -> unsigned_int
8768
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008769 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008770 /
8771
8772Extracts a device minor number from a raw device number.
8773[clinic start generated code]*/
8774
Larry Hastings2f936352014-08-05 14:04:04 +10008775static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008776os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008777/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008778{
8779 return minor(device);
8780}
8781
8782
8783/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008784os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008785
8786 major: int
8787 minor: int
8788 /
8789
8790Composes a raw device number from the major and minor device numbers.
8791[clinic start generated code]*/
8792
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008793static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008794os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008795/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008796{
8797 return makedev(major, minor);
8798}
8799#endif /* HAVE_DEVICE_MACROS */
8800
8801
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008802#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008803/*[clinic input]
8804os.ftruncate
8805
8806 fd: int
8807 length: Py_off_t
8808 /
8809
8810Truncate a file, specified by file descriptor, to a specific length.
8811[clinic start generated code]*/
8812
Larry Hastings2f936352014-08-05 14:04:04 +10008813static PyObject *
8814os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008815/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008816{
8817 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008818 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008819
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008820 if (!_PyVerify_fd(fd))
8821 return posix_error();
8822
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008823 do {
8824 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008825 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008826#ifdef MS_WINDOWS
8827 result = _chsize_s(fd, length);
8828#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008829 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008830#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008831 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008832 Py_END_ALLOW_THREADS
8833 } while (result != 0 && errno == EINTR &&
8834 !(async_err = PyErr_CheckSignals()));
8835 if (result != 0)
8836 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008837 Py_RETURN_NONE;
8838}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008839#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008840
8841
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008842#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008843/*[clinic input]
8844os.truncate
8845 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8846 length: Py_off_t
8847
8848Truncate a file, specified by path, to a specific length.
8849
8850On some platforms, path may also be specified as an open file descriptor.
8851 If this functionality is unavailable, using it raises an exception.
8852[clinic start generated code]*/
8853
Larry Hastings2f936352014-08-05 14:04:04 +10008854static PyObject *
8855os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008856/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008857{
8858 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008859#ifdef MS_WINDOWS
8860 int fd;
8861#endif
8862
8863 if (path->fd != -1)
8864 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008865
8866 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008867 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008868#ifdef MS_WINDOWS
8869 if (path->wide)
8870 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008871 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008872 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Victor Stinnercc0bbbc2015-04-25 00:21:52 +02008873 if (fd < 0)
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008874 result = -1;
8875 else {
8876 result = _chsize_s(fd, length);
8877 close(fd);
8878 if (result < 0)
8879 errno = result;
8880 }
8881#else
8882 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008883#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008884 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008885 Py_END_ALLOW_THREADS
8886 if (result < 0)
8887 return path_error(path);
8888
8889 Py_RETURN_NONE;
8890}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008891#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008892
Ross Lagerwall7807c352011-03-17 20:20:30 +02008893
Victor Stinnerd6b17692014-09-30 12:20:05 +02008894/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8895 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8896 defined, which is the case in Python on AIX. AIX bug report:
8897 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8898#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8899# define POSIX_FADVISE_AIX_BUG
8900#endif
8901
Victor Stinnerec39e262014-09-30 12:35:58 +02008902
Victor Stinnerd6b17692014-09-30 12:20:05 +02008903#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008904/*[clinic input]
8905os.posix_fallocate
8906
8907 fd: int
8908 offset: Py_off_t
8909 length: Py_off_t
8910 /
8911
8912Ensure a file has allocated at least a particular number of bytes on disk.
8913
8914Ensure that the file specified by fd encompasses a range of bytes
8915starting at offset bytes from the beginning and continuing for length bytes.
8916[clinic start generated code]*/
8917
Larry Hastings2f936352014-08-05 14:04:04 +10008918static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008919os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset,
8920 Py_off_t length)
8921/*[clinic end generated code: output=7f6f87a8c751e1b4 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008922{
8923 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008924 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008925
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008926 do {
8927 Py_BEGIN_ALLOW_THREADS
8928 result = posix_fallocate(fd, offset, length);
8929 Py_END_ALLOW_THREADS
8930 } while (result != 0 && errno == EINTR &&
8931 !(async_err = PyErr_CheckSignals()));
8932 if (result != 0)
8933 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008934 Py_RETURN_NONE;
8935}
Victor Stinnerec39e262014-09-30 12:35:58 +02008936#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008937
Ross Lagerwall7807c352011-03-17 20:20:30 +02008938
Victor Stinnerd6b17692014-09-30 12:20:05 +02008939#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008940/*[clinic input]
8941os.posix_fadvise
8942
8943 fd: int
8944 offset: Py_off_t
8945 length: Py_off_t
8946 advice: int
8947 /
8948
8949Announce an intention to access data in a specific pattern.
8950
8951Announce an intention to access data in a specific pattern, thus allowing
8952the kernel to make optimizations.
8953The advice applies to the region of the file specified by fd starting at
8954offset and continuing for length bytes.
8955advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8956POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8957POSIX_FADV_DONTNEED.
8958[clinic start generated code]*/
8959
Larry Hastings2f936352014-08-05 14:04:04 +10008960static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -04008961os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset,
8962 Py_off_t length, int advice)
8963/*[clinic end generated code: output=457ce6a67189e10d input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008964{
8965 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008966 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008967
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008968 do {
8969 Py_BEGIN_ALLOW_THREADS
8970 result = posix_fadvise(fd, offset, length, advice);
8971 Py_END_ALLOW_THREADS
8972 } while (result != 0 && errno == EINTR &&
8973 !(async_err = PyErr_CheckSignals()));
8974 if (result != 0)
8975 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008976 Py_RETURN_NONE;
8977}
Victor Stinnerec39e262014-09-30 12:35:58 +02008978#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008979
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008980#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008981
Fred Drake762e2061999-08-26 17:23:54 +00008982/* Save putenv() parameters as values here, so we can collect them when they
8983 * get re-set with another call for the same key. */
8984static PyObject *posix_putenv_garbage;
8985
Larry Hastings2f936352014-08-05 14:04:04 +10008986static void
8987posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008988{
Larry Hastings2f936352014-08-05 14:04:04 +10008989 /* Install the first arg and newstr in posix_putenv_garbage;
8990 * this will cause previous value to be collected. This has to
8991 * happen after the real putenv() call because the old value
8992 * was still accessible until then. */
8993 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8994 /* really not much we can do; just leak */
8995 PyErr_Clear();
8996 else
8997 Py_DECREF(value);
8998}
8999
9000
Thomas Hellerf78f12a2007-11-08 19:33:05 +00009001#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009002/*[clinic input]
9003os.putenv
9004
9005 name: unicode
9006 value: unicode
9007 /
9008
9009Change or add an environment variable.
9010[clinic start generated code]*/
9011
Larry Hastings2f936352014-08-05 14:04:04 +10009012static PyObject *
9013os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009014/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009015{
9016 wchar_t *env;
9017
9018 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
9019 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00009020 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009021 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009022 }
Larry Hastings2f936352014-08-05 14:04:04 +10009023 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009024 PyErr_Format(PyExc_ValueError,
9025 "the environment variable is longer than %u characters",
9026 _MAX_ENV);
9027 goto error;
9028 }
9029
Larry Hastings2f936352014-08-05 14:04:04 +10009030 env = PyUnicode_AsUnicode(unicode);
9031 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009032 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009033 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009034 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009035 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009036 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009037
Larry Hastings2f936352014-08-05 14:04:04 +10009038 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009039 Py_RETURN_NONE;
9040
9041error:
Larry Hastings2f936352014-08-05 14:04:04 +10009042 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009043 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009044}
Larry Hastings2f936352014-08-05 14:04:04 +10009045#else /* MS_WINDOWS */
9046/*[clinic input]
9047os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009048
Larry Hastings2f936352014-08-05 14:04:04 +10009049 name: FSConverter
9050 value: FSConverter
9051 /
9052
9053Change or add an environment variable.
9054[clinic start generated code]*/
9055
Larry Hastings2f936352014-08-05 14:04:04 +10009056static PyObject *
9057os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009058/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009059{
9060 PyObject *bytes = NULL;
9061 char *env;
9062 char *name_string = PyBytes_AsString(name);
9063 char *value_string = PyBytes_AsString(value);
9064
9065 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9066 if (bytes == NULL) {
9067 PyErr_NoMemory();
9068 return NULL;
9069 }
9070
9071 env = PyBytes_AS_STRING(bytes);
9072 if (putenv(env)) {
9073 Py_DECREF(bytes);
9074 return posix_error();
9075 }
9076
9077 posix_putenv_garbage_setitem(name, bytes);
9078 Py_RETURN_NONE;
9079}
9080#endif /* MS_WINDOWS */
9081#endif /* HAVE_PUTENV */
9082
9083
9084#ifdef HAVE_UNSETENV
9085/*[clinic input]
9086os.unsetenv
9087 name: FSConverter
9088 /
9089
9090Delete an environment variable.
9091[clinic start generated code]*/
9092
Larry Hastings2f936352014-08-05 14:04:04 +10009093static PyObject *
9094os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009095/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009096{
Victor Stinner984890f2011-11-24 13:53:38 +01009097#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009098 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009099#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009100
Victor Stinner984890f2011-11-24 13:53:38 +01009101#ifdef HAVE_BROKEN_UNSETENV
9102 unsetenv(PyBytes_AS_STRING(name));
9103#else
Victor Stinner65170952011-11-22 22:16:17 +01009104 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009105 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009106 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009107#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009108
Victor Stinner8c62be82010-05-06 00:08:46 +00009109 /* Remove the key from posix_putenv_garbage;
9110 * this will cause it to be collected. This has to
9111 * happen after the real unsetenv() call because the
9112 * old value was still accessible until then.
9113 */
Victor Stinner65170952011-11-22 22:16:17 +01009114 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009115 /* really not much we can do; just leak */
9116 PyErr_Clear();
9117 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009118 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009119}
Larry Hastings2f936352014-08-05 14:04:04 +10009120#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009121
Larry Hastings2f936352014-08-05 14:04:04 +10009122
9123/*[clinic input]
9124os.strerror
9125
9126 code: int
9127 /
9128
9129Translate an error code to a message string.
9130[clinic start generated code]*/
9131
Larry Hastings2f936352014-08-05 14:04:04 +10009132static PyObject *
9133os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009134/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009135{
9136 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009137 if (message == NULL) {
9138 PyErr_SetString(PyExc_ValueError,
9139 "strerror() argument out of range");
9140 return NULL;
9141 }
Victor Stinner1b579672011-12-17 05:47:23 +01009142 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009143}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009144
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009145
Guido van Rossumc9641791998-08-04 15:26:23 +00009146#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009147#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009148/*[clinic input]
9149os.WCOREDUMP -> bool
9150
9151 status: int
9152 /
9153
9154Return True if the process returning status was dumped to a core file.
9155[clinic start generated code]*/
9156
Larry Hastings2f936352014-08-05 14:04:04 +10009157static int
9158os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009159/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009160{
9161 WAIT_TYPE wait_status;
9162 WAIT_STATUS_INT(wait_status) = status;
9163 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009164}
9165#endif /* WCOREDUMP */
9166
Larry Hastings2f936352014-08-05 14:04:04 +10009167
Fred Drake106c1a02002-04-23 15:58:02 +00009168#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009169/*[clinic input]
9170os.WIFCONTINUED -> bool
9171
9172 status: int
9173
9174Return True if a particular process was continued from a job control stop.
9175
9176Return True if the process returning status was continued from a
9177job control stop.
9178[clinic start generated code]*/
9179
Larry Hastings2f936352014-08-05 14:04:04 +10009180static int
9181os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009182/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009183{
9184 WAIT_TYPE wait_status;
9185 WAIT_STATUS_INT(wait_status) = status;
9186 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009187}
9188#endif /* WIFCONTINUED */
9189
Larry Hastings2f936352014-08-05 14:04:04 +10009190
Guido van Rossumc9641791998-08-04 15:26:23 +00009191#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009192/*[clinic input]
9193os.WIFSTOPPED -> bool
9194
9195 status: int
9196
9197Return True if the process returning status was stopped.
9198[clinic start generated code]*/
9199
Larry Hastings2f936352014-08-05 14:04:04 +10009200static int
9201os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009202/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009203{
9204 WAIT_TYPE wait_status;
9205 WAIT_STATUS_INT(wait_status) = status;
9206 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009207}
9208#endif /* WIFSTOPPED */
9209
Larry Hastings2f936352014-08-05 14:04:04 +10009210
Guido van Rossumc9641791998-08-04 15:26:23 +00009211#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009212/*[clinic input]
9213os.WIFSIGNALED -> bool
9214
9215 status: int
9216
9217Return True if the process returning status was terminated by a signal.
9218[clinic start generated code]*/
9219
Larry Hastings2f936352014-08-05 14:04:04 +10009220static int
9221os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009222/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009223{
9224 WAIT_TYPE wait_status;
9225 WAIT_STATUS_INT(wait_status) = status;
9226 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009227}
9228#endif /* WIFSIGNALED */
9229
Larry Hastings2f936352014-08-05 14:04:04 +10009230
Guido van Rossumc9641791998-08-04 15:26:23 +00009231#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009232/*[clinic input]
9233os.WIFEXITED -> bool
9234
9235 status: int
9236
9237Return True if the process returning status exited via the exit() system call.
9238[clinic start generated code]*/
9239
Larry Hastings2f936352014-08-05 14:04:04 +10009240static int
9241os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009242/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009243{
9244 WAIT_TYPE wait_status;
9245 WAIT_STATUS_INT(wait_status) = status;
9246 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009247}
9248#endif /* WIFEXITED */
9249
Larry Hastings2f936352014-08-05 14:04:04 +10009250
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009251#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009252/*[clinic input]
9253os.WEXITSTATUS -> int
9254
9255 status: int
9256
9257Return the process return code from status.
9258[clinic start generated code]*/
9259
Larry Hastings2f936352014-08-05 14:04:04 +10009260static int
9261os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009262/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009263{
9264 WAIT_TYPE wait_status;
9265 WAIT_STATUS_INT(wait_status) = status;
9266 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009267}
9268#endif /* WEXITSTATUS */
9269
Larry Hastings2f936352014-08-05 14:04:04 +10009270
Guido van Rossumc9641791998-08-04 15:26:23 +00009271#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009272/*[clinic input]
9273os.WTERMSIG -> int
9274
9275 status: int
9276
9277Return the signal that terminated the process that provided the status value.
9278[clinic start generated code]*/
9279
Larry Hastings2f936352014-08-05 14:04:04 +10009280static int
9281os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009282/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009283{
9284 WAIT_TYPE wait_status;
9285 WAIT_STATUS_INT(wait_status) = status;
9286 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009287}
9288#endif /* WTERMSIG */
9289
Larry Hastings2f936352014-08-05 14:04:04 +10009290
Guido van Rossumc9641791998-08-04 15:26:23 +00009291#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009292/*[clinic input]
9293os.WSTOPSIG -> int
9294
9295 status: int
9296
9297Return the signal that stopped the process that provided the status value.
9298[clinic start generated code]*/
9299
Larry Hastings2f936352014-08-05 14:04:04 +10009300static int
9301os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009302/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009303{
9304 WAIT_TYPE wait_status;
9305 WAIT_STATUS_INT(wait_status) = status;
9306 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009307}
9308#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009309#endif /* HAVE_SYS_WAIT_H */
9310
9311
Thomas Wouters477c8d52006-05-27 19:21:47 +00009312#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009313#ifdef _SCO_DS
9314/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9315 needed definitions in sys/statvfs.h */
9316#define _SVID3
9317#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009318#include <sys/statvfs.h>
9319
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009320static PyObject*
9321_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009322 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9323 if (v == NULL)
9324 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009325
9326#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009327 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9328 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9329 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9330 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9331 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9332 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9333 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9334 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9335 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9336 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009337#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009338 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9339 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9340 PyStructSequence_SET_ITEM(v, 2,
9341 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9342 PyStructSequence_SET_ITEM(v, 3,
9343 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9344 PyStructSequence_SET_ITEM(v, 4,
9345 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9346 PyStructSequence_SET_ITEM(v, 5,
9347 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9348 PyStructSequence_SET_ITEM(v, 6,
9349 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9350 PyStructSequence_SET_ITEM(v, 7,
9351 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9352 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9353 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009354#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009355 if (PyErr_Occurred()) {
9356 Py_DECREF(v);
9357 return NULL;
9358 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009359
Victor Stinner8c62be82010-05-06 00:08:46 +00009360 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009361}
9362
Larry Hastings2f936352014-08-05 14:04:04 +10009363
9364/*[clinic input]
9365os.fstatvfs
9366 fd: int
9367 /
9368
9369Perform an fstatvfs system call on the given fd.
9370
9371Equivalent to statvfs(fd).
9372[clinic start generated code]*/
9373
Larry Hastings2f936352014-08-05 14:04:04 +10009374static PyObject *
9375os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009376/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009377{
9378 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009379 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009380 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009381
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009382 do {
9383 Py_BEGIN_ALLOW_THREADS
9384 result = fstatvfs(fd, &st);
9385 Py_END_ALLOW_THREADS
9386 } while (result != 0 && errno == EINTR &&
9387 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009388 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009389 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009390
Victor Stinner8c62be82010-05-06 00:08:46 +00009391 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009392}
Larry Hastings2f936352014-08-05 14:04:04 +10009393#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009394
9395
Thomas Wouters477c8d52006-05-27 19:21:47 +00009396#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009397#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009398/*[clinic input]
9399os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009400
Larry Hastings2f936352014-08-05 14:04:04 +10009401 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9402
9403Perform a statvfs system call on the given path.
9404
9405path may always be specified as a string.
9406On some platforms, path may also be specified as an open file descriptor.
9407 If this functionality is unavailable, using it raises an exception.
9408[clinic start generated code]*/
9409
Larry Hastings2f936352014-08-05 14:04:04 +10009410static PyObject *
9411os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009412/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009413{
9414 int result;
9415 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009416
9417 Py_BEGIN_ALLOW_THREADS
9418#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009419 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009420#ifdef __APPLE__
9421 /* handle weak-linking on Mac OS X 10.3 */
9422 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009423 fd_specified("statvfs", path->fd);
9424 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009425 }
9426#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009427 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009428 }
9429 else
9430#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009431 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009432 Py_END_ALLOW_THREADS
9433
9434 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009435 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009436 }
9437
Larry Hastings2f936352014-08-05 14:04:04 +10009438 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009439}
Larry Hastings2f936352014-08-05 14:04:04 +10009440#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9441
Guido van Rossum94f6f721999-01-06 18:42:14 +00009442
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009443#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009444/*[clinic input]
9445os._getdiskusage
9446
9447 path: Py_UNICODE
9448
9449Return disk usage statistics about the given path as a (total, free) tuple.
9450[clinic start generated code]*/
9451
Larry Hastings2f936352014-08-05 14:04:04 +10009452static PyObject *
9453os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009454/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009455{
9456 BOOL retval;
9457 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009458
9459 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009460 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009461 Py_END_ALLOW_THREADS
9462 if (retval == 0)
9463 return PyErr_SetFromWindowsErr(0);
9464
9465 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9466}
Larry Hastings2f936352014-08-05 14:04:04 +10009467#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009468
9469
Fred Drakec9680921999-12-13 16:37:25 +00009470/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9471 * It maps strings representing configuration variable names to
9472 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009473 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009474 * rarely-used constants. There are three separate tables that use
9475 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009476 *
9477 * This code is always included, even if none of the interfaces that
9478 * need it are included. The #if hackery needed to avoid it would be
9479 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009480 */
9481struct constdef {
Serhiy Storchaka2d06e842015-12-25 19:53:18 +02009482 const char *name;
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009483 int value;
Fred Drakec9680921999-12-13 16:37:25 +00009484};
9485
Fred Drake12c6e2d1999-12-14 21:25:03 +00009486static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009487conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009488 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009489{
Christian Heimes217cfd12007-12-02 14:31:20 +00009490 if (PyLong_Check(arg)) {
Serhiy Storchaka56f6e762015-09-06 21:25:30 +03009491 int value = _PyLong_AsInt(arg);
9492 if (value == -1 && PyErr_Occurred())
9493 return 0;
9494 *valuep = value;
Stefan Krah0e803b32010-11-26 16:16:47 +00009495 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009496 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009497 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009498 /* look up the value in the table using a binary search */
9499 size_t lo = 0;
9500 size_t mid;
9501 size_t hi = tablesize;
9502 int cmp;
9503 const char *confname;
9504 if (!PyUnicode_Check(arg)) {
9505 PyErr_SetString(PyExc_TypeError,
9506 "configuration names must be strings or integers");
9507 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009508 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009509 confname = _PyUnicode_AsString(arg);
9510 if (confname == NULL)
9511 return 0;
9512 while (lo < hi) {
9513 mid = (lo + hi) / 2;
9514 cmp = strcmp(confname, table[mid].name);
9515 if (cmp < 0)
9516 hi = mid;
9517 else if (cmp > 0)
9518 lo = mid + 1;
9519 else {
9520 *valuep = table[mid].value;
9521 return 1;
9522 }
9523 }
9524 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9525 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009526 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009527}
9528
9529
9530#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9531static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009532#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009534#endif
9535#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009537#endif
Fred Drakec9680921999-12-13 16:37:25 +00009538#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
9541#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
9559#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009560 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009561#endif
9562#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009563 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009564#endif
9565#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009566 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009567#endif
9568#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009569 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009570#endif
9571#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009572 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009573#endif
9574#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009575 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009576#endif
9577#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009578 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009579#endif
9580#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009581 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009582#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009583#ifdef _PC_ACL_ENABLED
9584 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9585#endif
9586#ifdef _PC_MIN_HOLE_SIZE
9587 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9588#endif
9589#ifdef _PC_ALLOC_SIZE_MIN
9590 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9591#endif
9592#ifdef _PC_REC_INCR_XFER_SIZE
9593 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9594#endif
9595#ifdef _PC_REC_MAX_XFER_SIZE
9596 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9597#endif
9598#ifdef _PC_REC_MIN_XFER_SIZE
9599 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9600#endif
9601#ifdef _PC_REC_XFER_ALIGN
9602 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9603#endif
9604#ifdef _PC_SYMLINK_MAX
9605 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9606#endif
9607#ifdef _PC_XATTR_ENABLED
9608 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9609#endif
9610#ifdef _PC_XATTR_EXISTS
9611 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9612#endif
9613#ifdef _PC_TIMESTAMP_RESOLUTION
9614 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9615#endif
Fred Drakec9680921999-12-13 16:37:25 +00009616};
9617
Fred Drakec9680921999-12-13 16:37:25 +00009618static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009619conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009620{
9621 return conv_confname(arg, valuep, posix_constants_pathconf,
9622 sizeof(posix_constants_pathconf)
9623 / sizeof(struct constdef));
9624}
9625#endif
9626
Larry Hastings2f936352014-08-05 14:04:04 +10009627
Fred Drakec9680921999-12-13 16:37:25 +00009628#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009629/*[clinic input]
9630os.fpathconf -> long
9631
9632 fd: int
9633 name: path_confname
9634 /
9635
9636Return the configuration limit name for the file descriptor fd.
9637
9638If there is no limit, return -1.
9639[clinic start generated code]*/
9640
Larry Hastings2f936352014-08-05 14:04:04 +10009641static long
9642os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009643/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009644{
9645 long limit;
9646
9647 errno = 0;
9648 limit = fpathconf(fd, name);
9649 if (limit == -1 && errno != 0)
9650 posix_error();
9651
9652 return limit;
9653}
9654#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009655
9656
9657#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009658/*[clinic input]
9659os.pathconf -> long
9660 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9661 name: path_confname
9662
9663Return the configuration limit name for the file or directory path.
9664
9665If there is no limit, return -1.
9666On some platforms, path may also be specified as an open file descriptor.
9667 If this functionality is unavailable, using it raises an exception.
9668[clinic start generated code]*/
9669
Larry Hastings2f936352014-08-05 14:04:04 +10009670static long
9671os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009672/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009673{
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009675
Victor Stinner8c62be82010-05-06 00:08:46 +00009676 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009677#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009678 if (path->fd != -1)
9679 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009680 else
9681#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009682 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 if (limit == -1 && errno != 0) {
9684 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009685 /* could be a path or name problem */
9686 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009687 else
Larry Hastings2f936352014-08-05 14:04:04 +10009688 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 }
Larry Hastings2f936352014-08-05 14:04:04 +10009690
9691 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009692}
Larry Hastings2f936352014-08-05 14:04:04 +10009693#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009694
9695#ifdef HAVE_CONFSTR
9696static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009697#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009699#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009700#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009702#endif
9703#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009705#endif
Fred Draked86ed291999-12-15 15:34:33 +00009706#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009708#endif
9709#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009711#endif
9712#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009714#endif
9715#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009717#endif
Fred Drakec9680921999-12-13 16:37:25 +00009718#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009720#endif
9721#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
9724#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009726#endif
9727#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009729#endif
9730#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009732#endif
9733#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009735#endif
9736#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
Fred Draked86ed291999-12-15 15:34:33 +00009742#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009744#endif
Fred Drakec9680921999-12-13 16:37:25 +00009745#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
Fred Draked86ed291999-12-15 15:34:33 +00009748#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009750#endif
9751#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009753#endif
9754#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009756#endif
9757#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009759#endif
Fred Drakec9680921999-12-13 16:37:25 +00009760#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
9784#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009786#endif
9787#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009789#endif
9790#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009792#endif
9793#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009795#endif
9796#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009798#endif
9799#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009801#endif
9802#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009804#endif
9805#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009807#endif
Fred Draked86ed291999-12-15 15:34:33 +00009808#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009810#endif
9811#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009813#endif
9814#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009816#endif
9817#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009819#endif
9820#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009822#endif
9823#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009824 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009825#endif
9826#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009827 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009828#endif
9829#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009830 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009831#endif
9832#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009833 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009834#endif
9835#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009836 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009837#endif
9838#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009839 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009840#endif
9841#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009842 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009843#endif
9844#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009845 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009846#endif
Fred Drakec9680921999-12-13 16:37:25 +00009847};
9848
9849static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009850conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009851{
9852 return conv_confname(arg, valuep, posix_constants_confstr,
9853 sizeof(posix_constants_confstr)
9854 / sizeof(struct constdef));
9855}
9856
Larry Hastings2f936352014-08-05 14:04:04 +10009857
9858/*[clinic input]
9859os.confstr
9860
9861 name: confstr_confname
9862 /
9863
9864Return a string-valued system configuration variable.
9865[clinic start generated code]*/
9866
Larry Hastings2f936352014-08-05 14:04:04 +10009867static PyObject *
9868os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009869/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009870{
9871 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009872 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009873 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009874
Victor Stinnercb043522010-09-10 23:49:04 +00009875 errno = 0;
9876 len = confstr(name, buffer, sizeof(buffer));
9877 if (len == 0) {
9878 if (errno) {
9879 posix_error();
9880 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009881 }
9882 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009883 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009884 }
9885 }
Victor Stinnercb043522010-09-10 23:49:04 +00009886
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009887 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009888 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009889 char *buf = PyMem_Malloc(len);
9890 if (buf == NULL)
9891 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009892 len2 = confstr(name, buf, len);
9893 assert(len == len2);
Christian Heimes8714cfd2015-04-21 10:57:41 +02009894 result = PyUnicode_DecodeFSDefaultAndSize(buf, len2-1);
Victor Stinnercb043522010-09-10 23:49:04 +00009895 PyMem_Free(buf);
9896 }
9897 else
9898 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009899 return result;
9900}
Larry Hastings2f936352014-08-05 14:04:04 +10009901#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009902
9903
9904#ifdef HAVE_SYSCONF
9905static struct constdef posix_constants_sysconf[] = {
9906#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
9912#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009914#endif
9915#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009917#endif
9918#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
9921#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
Fred Draked86ed291999-12-15 15:34:33 +00009936#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009938#endif
9939#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009941#endif
Fred Drakec9680921999-12-13 16:37:25 +00009942#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
Fred Drakec9680921999-12-13 16:37:25 +00009945#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
9954#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009956#endif
9957#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
Fred Draked86ed291999-12-15 15:34:33 +00009960#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009962#endif
Fred Drakec9680921999-12-13 16:37:25 +00009963#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
Fred Draked86ed291999-12-15 15:34:33 +00009978#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009980#endif
Fred Drakec9680921999-12-13 16:37:25 +00009981#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
10026#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010028#endif
10029#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
10038#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010040#endif
10041#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
10044#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010046#endif
10047#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010049#endif
Fred Draked86ed291999-12-15 15:34:33 +000010050#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010052#endif
Fred Drakec9680921999-12-13 16:37:25 +000010053#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
Fred Draked86ed291999-12-15 15:34:33 +000010062#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010064#endif
Fred Drakec9680921999-12-13 16:37:25 +000010065#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
Fred Draked86ed291999-12-15 15:34:33 +000010068#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010070#endif
10071#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010073#endif
Fred Drakec9680921999-12-13 16:37:25 +000010074#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
Fred Draked86ed291999-12-15 15:34:33 +000010086#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010088#endif
Fred Drakec9680921999-12-13 16:37:25 +000010089#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
10095#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010097#endif
10098#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
Fred Draked86ed291999-12-15 15:34:33 +000010110#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010112#endif
Fred Drakec9680921999-12-13 16:37:25 +000010113#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
Fred Draked86ed291999-12-15 15:34:33 +000010119#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010121#endif
Fred Drakec9680921999-12-13 16:37:25 +000010122#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
10125#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010127#endif
10128#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010130#endif
10131#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
Fred Draked86ed291999-12-15 15:34:33 +000010149#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010151#endif
10152#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010154#endif
Fred Drakec9680921999-12-13 16:37:25 +000010155#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
10236#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010238#endif
10239#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
Fred Draked86ed291999-12-15 15:34:33 +000010260#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010262#endif
Fred Drakec9680921999-12-13 16:37:25 +000010263#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010375 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010376#endif
10377#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010378 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010379#endif
10380#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010381 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010382#endif
10383#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010384 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010385#endif
10386#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010387 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010388#endif
10389#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010390 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010391#endif
10392#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010393 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010394#endif
10395#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010396 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010397#endif
10398};
10399
10400static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010401conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010402{
10403 return conv_confname(arg, valuep, posix_constants_sysconf,
10404 sizeof(posix_constants_sysconf)
10405 / sizeof(struct constdef));
10406}
10407
Larry Hastings2f936352014-08-05 14:04:04 +100010408
10409/*[clinic input]
10410os.sysconf -> long
10411 name: sysconf_confname
10412 /
10413
10414Return an integer-valued system configuration variable.
10415[clinic start generated code]*/
10416
Larry Hastings2f936352014-08-05 14:04:04 +100010417static long
10418os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010419/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010420{
10421 long value;
10422
10423 errno = 0;
10424 value = sysconf(name);
10425 if (value == -1 && errno != 0)
10426 posix_error();
10427 return value;
10428}
10429#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010430
10431
Fred Drakebec628d1999-12-15 18:31:10 +000010432/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010433 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010434 * the exported dictionaries that are used to publish information about the
10435 * names available on the host platform.
10436 *
10437 * Sorting the table at runtime ensures that the table is properly ordered
10438 * when used, even for platforms we're not able to test on. It also makes
10439 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010440 */
Fred Drakebec628d1999-12-15 18:31:10 +000010441
10442static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010443cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010444{
10445 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010446 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010447 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010448 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010449
10450 return strcmp(c1->name, c2->name);
10451}
10452
10453static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010454setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010455 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010456{
Fred Drakebec628d1999-12-15 18:31:10 +000010457 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010458 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010459
10460 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10461 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010462 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010463 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010464
Barry Warsaw3155db32000-04-13 15:20:40 +000010465 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010466 PyObject *o = PyLong_FromLong(table[i].value);
10467 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10468 Py_XDECREF(o);
10469 Py_DECREF(d);
10470 return -1;
10471 }
10472 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010473 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010474 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010475}
10476
Fred Drakebec628d1999-12-15 18:31:10 +000010477/* Return -1 on failure, 0 on success. */
10478static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010479setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010480{
10481#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010482 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010483 sizeof(posix_constants_pathconf)
10484 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010485 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010486 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010487#endif
10488#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010489 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010490 sizeof(posix_constants_confstr)
10491 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010492 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010493 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010494#endif
10495#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010496 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010497 sizeof(posix_constants_sysconf)
10498 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010499 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010500 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010501#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010502 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010503}
Fred Draked86ed291999-12-15 15:34:33 +000010504
10505
Larry Hastings2f936352014-08-05 14:04:04 +100010506/*[clinic input]
10507os.abort
10508
10509Abort the interpreter immediately.
10510
10511This function 'dumps core' or otherwise fails in the hardest way possible
10512on the hosting operating system. This function never returns.
10513[clinic start generated code]*/
10514
Larry Hastings2f936352014-08-05 14:04:04 +100010515static PyObject *
10516os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010517/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010518{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010519 abort();
10520 /*NOTREACHED*/
10521 Py_FatalError("abort() called from Python code didn't abort!");
10522 return NULL;
10523}
Fred Drakebec628d1999-12-15 18:31:10 +000010524
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010525#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010526/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010527PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010528"startfile(filepath [, operation])\n\
10529\n\
10530Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010531\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010532When \"operation\" is not specified or \"open\", this acts like\n\
10533double-clicking the file in Explorer, or giving the file name as an\n\
10534argument to the DOS \"start\" command: the file is opened with whatever\n\
10535application (if any) its extension is associated.\n\
10536When another \"operation\" is given, it specifies what should be done with\n\
10537the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010538\n\
10539startfile returns as soon as the associated application is launched.\n\
10540There is no option to wait for the application to close, and no way\n\
10541to retrieve the application's exit status.\n\
10542\n\
10543The filepath is relative to the current directory. If you want to use\n\
10544an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010545the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010546
Steve Dower7d0e0c92015-01-24 08:18:24 -080010547/* Grab ShellExecute dynamically from shell32 */
10548static int has_ShellExecute = -1;
10549static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10550 LPCSTR, INT);
10551static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10552 LPCWSTR, INT);
10553static int
10554check_ShellExecute()
10555{
10556 HINSTANCE hShell32;
10557
10558 /* only recheck */
10559 if (-1 == has_ShellExecute) {
10560 Py_BEGIN_ALLOW_THREADS
10561 hShell32 = LoadLibraryW(L"SHELL32");
10562 Py_END_ALLOW_THREADS
10563 if (hShell32) {
10564 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10565 "ShellExecuteA");
10566 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10567 "ShellExecuteW");
10568 has_ShellExecute = Py_ShellExecuteA &&
10569 Py_ShellExecuteW;
10570 } else {
10571 has_ShellExecute = 0;
10572 }
10573 }
10574 return has_ShellExecute;
10575}
10576
10577
Tim Petersf58a7aa2000-09-22 10:05:54 +000010578static PyObject *
10579win32_startfile(PyObject *self, PyObject *args)
10580{
Victor Stinner8c62be82010-05-06 00:08:46 +000010581 PyObject *ofilepath;
10582 char *filepath;
10583 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010584 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010585 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010586
Victor Stinnereb5657a2011-09-30 01:44:27 +020010587 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010588
10589 if(!check_ShellExecute()) {
10590 /* If the OS doesn't have ShellExecute, return a
10591 NotImplementedError. */
10592 return PyErr_Format(PyExc_NotImplementedError,
10593 "startfile not available on this platform");
10594 }
10595
Victor Stinner8c62be82010-05-06 00:08:46 +000010596 if (!PyArg_ParseTuple(args, "U|s:startfile",
10597 &unipath, &operation)) {
10598 PyErr_Clear();
10599 goto normal;
10600 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010601
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010603 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010604 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010605 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010606 PyErr_Clear();
10607 operation = NULL;
10608 goto normal;
10609 }
10610 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010611
Victor Stinnereb5657a2011-09-30 01:44:27 +020010612 wpath = PyUnicode_AsUnicode(unipath);
10613 if (wpath == NULL)
10614 goto normal;
10615 if (uoperation) {
10616 woperation = PyUnicode_AsUnicode(uoperation);
10617 if (woperation == NULL)
10618 goto normal;
10619 }
10620 else
10621 woperation = NULL;
10622
Victor Stinner8c62be82010-05-06 00:08:46 +000010623 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010624 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10625 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010626 Py_END_ALLOW_THREADS
10627
Victor Stinnereb5657a2011-09-30 01:44:27 +020010628 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010629 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010630 win32_error_object("startfile", unipath);
10631 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010632 }
10633 Py_INCREF(Py_None);
10634 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010635
10636normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010637 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10638 PyUnicode_FSConverter, &ofilepath,
10639 &operation))
10640 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010641 if (win32_warn_bytes_api()) {
10642 Py_DECREF(ofilepath);
10643 return NULL;
10644 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010645 filepath = PyBytes_AsString(ofilepath);
10646 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010647 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10648 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010649 Py_END_ALLOW_THREADS
10650 if (rc <= (HINSTANCE)32) {
10651 PyObject *errval = win32_error("startfile", filepath);
10652 Py_DECREF(ofilepath);
10653 return errval;
10654 }
10655 Py_DECREF(ofilepath);
10656 Py_INCREF(Py_None);
10657 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010658}
Larry Hastings2f936352014-08-05 14:04:04 +100010659#endif /* MS_WINDOWS */
10660
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010661
Martin v. Löwis438b5342002-12-27 10:16:42 +000010662#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010663/*[clinic input]
10664os.getloadavg
10665
10666Return average recent system load information.
10667
10668Return the number of processes in the system run queue averaged over
10669the last 1, 5, and 15 minutes as a tuple of three floats.
10670Raises OSError if the load average was unobtainable.
10671[clinic start generated code]*/
10672
Larry Hastings2f936352014-08-05 14:04:04 +100010673static PyObject *
10674os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010675/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010676{
10677 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010678 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010679 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10680 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010681 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010682 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010683}
Larry Hastings2f936352014-08-05 14:04:04 +100010684#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010685
Larry Hastings2f936352014-08-05 14:04:04 +100010686
10687/*[clinic input]
10688os.device_encoding
10689 fd: int
10690
10691Return a string describing the encoding of a terminal's file descriptor.
10692
10693The file descriptor must be attached to a terminal.
10694If the device is not a terminal, return None.
10695[clinic start generated code]*/
10696
Larry Hastings2f936352014-08-05 14:04:04 +100010697static PyObject *
10698os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010699/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010700{
Brett Cannonefb00c02012-02-29 18:31:31 -050010701 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010702}
10703
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010704
Larry Hastings2f936352014-08-05 14:04:04 +100010705#ifdef HAVE_SETRESUID
10706/*[clinic input]
10707os.setresuid
10708
10709 ruid: uid_t
10710 euid: uid_t
10711 suid: uid_t
10712 /
10713
10714Set the current process's real, effective, and saved user ids.
10715[clinic start generated code]*/
10716
Larry Hastings2f936352014-08-05 14:04:04 +100010717static PyObject *
10718os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010719/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010720{
Victor Stinner8c62be82010-05-06 00:08:46 +000010721 if (setresuid(ruid, euid, suid) < 0)
10722 return posix_error();
10723 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010724}
Larry Hastings2f936352014-08-05 14:04:04 +100010725#endif /* HAVE_SETRESUID */
10726
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010727
10728#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010729/*[clinic input]
10730os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010731
Larry Hastings2f936352014-08-05 14:04:04 +100010732 rgid: gid_t
10733 egid: gid_t
10734 sgid: gid_t
10735 /
10736
10737Set the current process's real, effective, and saved group ids.
10738[clinic start generated code]*/
10739
Larry Hastings2f936352014-08-05 14:04:04 +100010740static PyObject *
10741os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010742/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010743{
Victor Stinner8c62be82010-05-06 00:08:46 +000010744 if (setresgid(rgid, egid, sgid) < 0)
10745 return posix_error();
10746 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010747}
Larry Hastings2f936352014-08-05 14:04:04 +100010748#endif /* HAVE_SETRESGID */
10749
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010750
10751#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010752/*[clinic input]
10753os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010754
Larry Hastings2f936352014-08-05 14:04:04 +100010755Return a tuple of the current process's real, effective, and saved user ids.
10756[clinic start generated code]*/
10757
Larry Hastings2f936352014-08-05 14:04:04 +100010758static PyObject *
10759os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010760/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010761{
Victor Stinner8c62be82010-05-06 00:08:46 +000010762 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010763 if (getresuid(&ruid, &euid, &suid) < 0)
10764 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010765 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10766 _PyLong_FromUid(euid),
10767 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010768}
Larry Hastings2f936352014-08-05 14:04:04 +100010769#endif /* HAVE_GETRESUID */
10770
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010771
10772#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010773/*[clinic input]
10774os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010775
Larry Hastings2f936352014-08-05 14:04:04 +100010776Return a tuple of the current process's real, effective, and saved group ids.
10777[clinic start generated code]*/
10778
Larry Hastings2f936352014-08-05 14:04:04 +100010779static PyObject *
10780os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010781/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010782{
10783 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010784 if (getresgid(&rgid, &egid, &sgid) < 0)
10785 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010786 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10787 _PyLong_FromGid(egid),
10788 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010789}
Larry Hastings2f936352014-08-05 14:04:04 +100010790#endif /* HAVE_GETRESGID */
10791
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010792
Benjamin Peterson9428d532011-09-14 11:45:52 -040010793#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010794/*[clinic input]
10795os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010796
Larry Hastings2f936352014-08-05 14:04:04 +100010797 path: path_t(allow_fd=True)
10798 attribute: path_t
10799 *
10800 follow_symlinks: bool = True
10801
10802Return the value of extended attribute attribute on path.
10803
10804path may be either a string or an open file descriptor.
10805If follow_symlinks is False, and the last element of the path is a symbolic
10806 link, getxattr will examine the symbolic link itself instead of the file
10807 the link points to.
10808
10809[clinic start generated code]*/
10810
Larry Hastings2f936352014-08-05 14:04:04 +100010811static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010812os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10813 int follow_symlinks)
10814/*[clinic end generated code: output=cf2cede74bd5d412 input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010815{
10816 Py_ssize_t i;
10817 PyObject *buffer = NULL;
10818
10819 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10820 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010821
Larry Hastings9cf065c2012-06-22 16:30:09 -070010822 for (i = 0; ; i++) {
10823 void *ptr;
10824 ssize_t result;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010825 static const Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
Larry Hastings9cf065c2012-06-22 16:30:09 -070010826 Py_ssize_t buffer_size = buffer_sizes[i];
10827 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010828 path_error(path);
10829 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010830 }
10831 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10832 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010833 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010834 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010835
Larry Hastings9cf065c2012-06-22 16:30:09 -070010836 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010837 if (path->fd >= 0)
10838 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010839 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010840 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010841 else
Larry Hastings2f936352014-08-05 14:04:04 +100010842 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010843 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010844
Larry Hastings9cf065c2012-06-22 16:30:09 -070010845 if (result < 0) {
10846 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010847 if (errno == ERANGE)
10848 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010849 path_error(path);
10850 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010851 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010852
Larry Hastings9cf065c2012-06-22 16:30:09 -070010853 if (result != buffer_size) {
10854 /* Can only shrink. */
10855 _PyBytes_Resize(&buffer, result);
10856 }
10857 break;
10858 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010859
Larry Hastings9cf065c2012-06-22 16:30:09 -070010860 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010861}
10862
Larry Hastings2f936352014-08-05 14:04:04 +100010863
10864/*[clinic input]
10865os.setxattr
10866
10867 path: path_t(allow_fd=True)
10868 attribute: path_t
10869 value: Py_buffer
10870 flags: int = 0
10871 *
10872 follow_symlinks: bool = True
10873
10874Set extended attribute attribute on path to value.
10875
10876path may be either a string or an open file descriptor.
10877If follow_symlinks is False, and the last element of the path is a symbolic
10878 link, setxattr will modify the symbolic link itself instead of the file
10879 the link points to.
10880
10881[clinic start generated code]*/
10882
Benjamin Peterson799bd802011-08-31 22:15:17 -040010883static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010884os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10885 Py_buffer *value, int flags, int follow_symlinks)
10886/*[clinic end generated code: output=1b395ef82880fea0 input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010887{
Larry Hastings2f936352014-08-05 14:04:04 +100010888 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010889
Larry Hastings2f936352014-08-05 14:04:04 +100010890 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010891 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010892
Benjamin Peterson799bd802011-08-31 22:15:17 -040010893 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010894 if (path->fd > -1)
10895 result = fsetxattr(path->fd, attribute->narrow,
10896 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010897 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010898 result = setxattr(path->narrow, attribute->narrow,
10899 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010900 else
Larry Hastings2f936352014-08-05 14:04:04 +100010901 result = lsetxattr(path->narrow, attribute->narrow,
10902 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010903 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010904
Larry Hastings9cf065c2012-06-22 16:30:09 -070010905 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010906 path_error(path);
10907 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010908 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010909
Larry Hastings2f936352014-08-05 14:04:04 +100010910 Py_RETURN_NONE;
10911}
10912
10913
10914/*[clinic input]
10915os.removexattr
10916
10917 path: path_t(allow_fd=True)
10918 attribute: path_t
10919 *
10920 follow_symlinks: bool = True
10921
10922Remove extended attribute attribute on path.
10923
10924path may be either a string or an open file descriptor.
10925If follow_symlinks is False, and the last element of the path is a symbolic
10926 link, removexattr will modify the symbolic link itself instead of the file
10927 the link points to.
10928
10929[clinic start generated code]*/
10930
Larry Hastings2f936352014-08-05 14:04:04 +100010931static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040010932os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute,
10933 int follow_symlinks)
10934/*[clinic end generated code: output=f92bb39ab992650d input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010935{
10936 ssize_t result;
10937
10938 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10939 return NULL;
10940
10941 Py_BEGIN_ALLOW_THREADS;
10942 if (path->fd > -1)
10943 result = fremovexattr(path->fd, attribute->narrow);
10944 else if (follow_symlinks)
10945 result = removexattr(path->narrow, attribute->narrow);
10946 else
10947 result = lremovexattr(path->narrow, attribute->narrow);
10948 Py_END_ALLOW_THREADS;
10949
10950 if (result) {
10951 return path_error(path);
10952 }
10953
10954 Py_RETURN_NONE;
10955}
10956
10957
10958/*[clinic input]
10959os.listxattr
10960
10961 path: path_t(allow_fd=True, nullable=True) = None
10962 *
10963 follow_symlinks: bool = True
10964
10965Return a list of extended attributes on path.
10966
10967path may be either None, a string, or an open file descriptor.
10968if path is None, listxattr will examine the current directory.
10969If follow_symlinks is False, and the last element of the path is a symbolic
10970 link, listxattr will examine the symbolic link itself instead of the file
10971 the link points to.
10972[clinic start generated code]*/
10973
Larry Hastings2f936352014-08-05 14:04:04 +100010974static PyObject *
10975os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010976/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010977{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010978 Py_ssize_t i;
10979 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010980 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010981 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010982
Larry Hastings2f936352014-08-05 14:04:04 +100010983 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010984 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010985
Larry Hastings2f936352014-08-05 14:04:04 +100010986 name = path->narrow ? path->narrow : ".";
10987
Larry Hastings9cf065c2012-06-22 16:30:09 -070010988 for (i = 0; ; i++) {
10989 char *start, *trace, *end;
10990 ssize_t length;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020010991 static const Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
Larry Hastings9cf065c2012-06-22 16:30:09 -070010992 Py_ssize_t buffer_size = buffer_sizes[i];
10993 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010994 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010995 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 break;
10997 }
10998 buffer = PyMem_MALLOC(buffer_size);
10999 if (!buffer) {
11000 PyErr_NoMemory();
11001 break;
11002 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011003
Larry Hastings9cf065c2012-06-22 16:30:09 -070011004 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100011005 if (path->fd > -1)
11006 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011007 else if (follow_symlinks)
11008 length = listxattr(name, buffer, buffer_size);
11009 else
11010 length = llistxattr(name, buffer, buffer_size);
11011 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011012
Larry Hastings9cf065c2012-06-22 16:30:09 -070011013 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020011014 if (errno == ERANGE) {
11015 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050011016 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070011017 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020011018 }
Larry Hastings2f936352014-08-05 14:04:04 +100011019 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070011020 break;
11021 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011022
Larry Hastings9cf065c2012-06-22 16:30:09 -070011023 result = PyList_New(0);
11024 if (!result) {
11025 goto exit;
11026 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011027
Larry Hastings9cf065c2012-06-22 16:30:09 -070011028 end = buffer + length;
11029 for (trace = start = buffer; trace != end; trace++) {
11030 if (!*trace) {
11031 int error;
11032 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11033 trace - start);
11034 if (!attribute) {
11035 Py_DECREF(result);
11036 result = NULL;
11037 goto exit;
11038 }
11039 error = PyList_Append(result, attribute);
11040 Py_DECREF(attribute);
11041 if (error) {
11042 Py_DECREF(result);
11043 result = NULL;
11044 goto exit;
11045 }
11046 start = trace + 1;
11047 }
11048 }
11049 break;
11050 }
11051exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011052 if (buffer)
11053 PyMem_FREE(buffer);
11054 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011055}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011056#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011057
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011058
Larry Hastings2f936352014-08-05 14:04:04 +100011059/*[clinic input]
11060os.urandom
11061
11062 size: Py_ssize_t
11063 /
11064
11065Return a bytes object containing random bytes suitable for cryptographic use.
11066[clinic start generated code]*/
11067
Larry Hastings2f936352014-08-05 14:04:04 +100011068static PyObject *
11069os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011070/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011071{
11072 PyObject *bytes;
11073 int result;
11074
Georg Brandl2fb477c2012-02-21 00:33:36 +010011075 if (size < 0)
11076 return PyErr_Format(PyExc_ValueError,
11077 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011078 bytes = PyBytes_FromStringAndSize(NULL, size);
11079 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011080 return NULL;
11081
Larry Hastings2f936352014-08-05 14:04:04 +100011082 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11083 PyBytes_GET_SIZE(bytes));
11084 if (result == -1) {
11085 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011086 return NULL;
11087 }
Larry Hastings2f936352014-08-05 14:04:04 +100011088 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011089}
11090
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011091/* Terminal size querying */
11092
11093static PyTypeObject TerminalSizeType;
11094
11095PyDoc_STRVAR(TerminalSize_docstring,
11096 "A tuple of (columns, lines) for holding terminal window size");
11097
11098static PyStructSequence_Field TerminalSize_fields[] = {
11099 {"columns", "width of the terminal window in characters"},
11100 {"lines", "height of the terminal window in characters"},
11101 {NULL, NULL}
11102};
11103
11104static PyStructSequence_Desc TerminalSize_desc = {
11105 "os.terminal_size",
11106 TerminalSize_docstring,
11107 TerminalSize_fields,
11108 2,
11109};
11110
11111#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011112/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011113PyDoc_STRVAR(termsize__doc__,
11114 "Return the size of the terminal window as (columns, lines).\n" \
11115 "\n" \
11116 "The optional argument fd (default standard output) specifies\n" \
11117 "which file descriptor should be queried.\n" \
11118 "\n" \
11119 "If the file descriptor is not connected to a terminal, an OSError\n" \
11120 "is thrown.\n" \
11121 "\n" \
11122 "This function will only be defined if an implementation is\n" \
11123 "available for this system.\n" \
11124 "\n" \
11125 "shutil.get_terminal_size is the high-level function which should \n" \
11126 "normally be used, os.get_terminal_size is the low-level implementation.");
11127
11128static PyObject*
11129get_terminal_size(PyObject *self, PyObject *args)
11130{
11131 int columns, lines;
11132 PyObject *termsize;
11133
11134 int fd = fileno(stdout);
11135 /* Under some conditions stdout may not be connected and
11136 * fileno(stdout) may point to an invalid file descriptor. For example
11137 * GUI apps don't have valid standard streams by default.
11138 *
11139 * If this happens, and the optional fd argument is not present,
11140 * the ioctl below will fail returning EBADF. This is what we want.
11141 */
11142
11143 if (!PyArg_ParseTuple(args, "|i", &fd))
11144 return NULL;
11145
11146#ifdef TERMSIZE_USE_IOCTL
11147 {
11148 struct winsize w;
11149 if (ioctl(fd, TIOCGWINSZ, &w))
11150 return PyErr_SetFromErrno(PyExc_OSError);
11151 columns = w.ws_col;
11152 lines = w.ws_row;
11153 }
11154#endif /* TERMSIZE_USE_IOCTL */
11155
11156#ifdef TERMSIZE_USE_CONIO
11157 {
11158 DWORD nhandle;
11159 HANDLE handle;
11160 CONSOLE_SCREEN_BUFFER_INFO csbi;
11161 switch (fd) {
11162 case 0: nhandle = STD_INPUT_HANDLE;
11163 break;
11164 case 1: nhandle = STD_OUTPUT_HANDLE;
11165 break;
11166 case 2: nhandle = STD_ERROR_HANDLE;
11167 break;
11168 default:
11169 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11170 }
11171 handle = GetStdHandle(nhandle);
11172 if (handle == NULL)
11173 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11174 if (handle == INVALID_HANDLE_VALUE)
11175 return PyErr_SetFromWindowsErr(0);
11176
11177 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11178 return PyErr_SetFromWindowsErr(0);
11179
11180 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11181 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11182 }
11183#endif /* TERMSIZE_USE_CONIO */
11184
11185 termsize = PyStructSequence_New(&TerminalSizeType);
11186 if (termsize == NULL)
11187 return NULL;
11188 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11189 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11190 if (PyErr_Occurred()) {
11191 Py_DECREF(termsize);
11192 return NULL;
11193 }
11194 return termsize;
11195}
11196#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11197
Larry Hastings2f936352014-08-05 14:04:04 +100011198
11199/*[clinic input]
11200os.cpu_count
11201
Charles-François Natali80d62e62015-08-13 20:37:08 +010011202Return the number of CPUs in the system; return None if indeterminable.
11203
11204This number is not equivalent to the number of CPUs the current process can
11205use. The number of usable CPUs can be obtained with
11206``len(os.sched_getaffinity(0))``
Larry Hastings2f936352014-08-05 14:04:04 +100011207[clinic start generated code]*/
11208
Larry Hastings2f936352014-08-05 14:04:04 +100011209static PyObject *
11210os_cpu_count_impl(PyModuleDef *module)
Charles-François Natali80d62e62015-08-13 20:37:08 +010011211/*[clinic end generated code: output=c59ee7f6bce832b8 input=e7c8f4ba6dbbadd3]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011212{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011213 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011214#ifdef MS_WINDOWS
11215 SYSTEM_INFO sysinfo;
11216 GetSystemInfo(&sysinfo);
11217 ncpu = sysinfo.dwNumberOfProcessors;
11218#elif defined(__hpux)
11219 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11220#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11221 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011222#elif defined(__DragonFly__) || \
11223 defined(__OpenBSD__) || \
11224 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011225 defined(__NetBSD__) || \
11226 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011227 int mib[2];
11228 size_t len = sizeof(ncpu);
11229 mib[0] = CTL_HW;
11230 mib[1] = HW_NCPU;
11231 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11232 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011233#endif
11234 if (ncpu >= 1)
11235 return PyLong_FromLong(ncpu);
11236 else
11237 Py_RETURN_NONE;
11238}
11239
Victor Stinnerdaf45552013-08-28 00:53:59 +020011240
Larry Hastings2f936352014-08-05 14:04:04 +100011241/*[clinic input]
11242os.get_inheritable -> bool
11243
11244 fd: int
11245 /
11246
11247Get the close-on-exe flag of the specified file descriptor.
11248[clinic start generated code]*/
11249
Larry Hastings2f936352014-08-05 14:04:04 +100011250static int
11251os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011252/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011253{
Steve Dower8fc89802015-04-12 00:26:27 -040011254 int return_value;
11255 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011256 posix_error();
11257 return -1;
11258 }
11259
Steve Dower8fc89802015-04-12 00:26:27 -040011260 _Py_BEGIN_SUPPRESS_IPH
11261 return_value = _Py_get_inheritable(fd);
11262 _Py_END_SUPPRESS_IPH
11263 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011264}
11265
11266
11267/*[clinic input]
11268os.set_inheritable
11269 fd: int
11270 inheritable: int
11271 /
11272
11273Set the inheritable flag of the specified file descriptor.
11274[clinic start generated code]*/
11275
Larry Hastings2f936352014-08-05 14:04:04 +100011276static PyObject *
11277os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011278/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011279{
Steve Dower8fc89802015-04-12 00:26:27 -040011280 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011281 if (!_PyVerify_fd(fd))
11282 return posix_error();
11283
Steve Dower8fc89802015-04-12 00:26:27 -040011284 _Py_BEGIN_SUPPRESS_IPH
11285 result = _Py_set_inheritable(fd, inheritable, NULL);
11286 _Py_END_SUPPRESS_IPH
11287 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011288 return NULL;
11289 Py_RETURN_NONE;
11290}
11291
11292
11293#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011294/*[clinic input]
11295os.get_handle_inheritable -> bool
11296 handle: Py_intptr_t
11297 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011298
Larry Hastings2f936352014-08-05 14:04:04 +100011299Get the close-on-exe flag of the specified file descriptor.
11300[clinic start generated code]*/
11301
Larry Hastings2f936352014-08-05 14:04:04 +100011302static int
11303os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011304/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011305{
11306 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011307
11308 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11309 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011310 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011311 }
11312
Larry Hastings2f936352014-08-05 14:04:04 +100011313 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011314}
11315
Victor Stinnerdaf45552013-08-28 00:53:59 +020011316
Larry Hastings2f936352014-08-05 14:04:04 +100011317/*[clinic input]
11318os.set_handle_inheritable
11319 handle: Py_intptr_t
11320 inheritable: bool
11321 /
11322
11323Set the inheritable flag of the specified handle.
11324[clinic start generated code]*/
11325
Larry Hastings2f936352014-08-05 14:04:04 +100011326static PyObject *
Larry Hastings89964c42015-04-14 18:07:59 -040011327os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle,
11328 int inheritable)
11329/*[clinic end generated code: output=d2e111a96c9eb296 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011330{
11331 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011332 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11333 PyErr_SetFromWindowsErr(0);
11334 return NULL;
11335 }
11336 Py_RETURN_NONE;
11337}
Larry Hastings2f936352014-08-05 14:04:04 +100011338#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011339
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011340#ifndef MS_WINDOWS
11341PyDoc_STRVAR(get_blocking__doc__,
11342 "get_blocking(fd) -> bool\n" \
11343 "\n" \
11344 "Get the blocking mode of the file descriptor:\n" \
11345 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11346
11347static PyObject*
11348posix_get_blocking(PyObject *self, PyObject *args)
11349{
11350 int fd;
11351 int blocking;
11352
11353 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11354 return NULL;
11355
11356 if (!_PyVerify_fd(fd))
11357 return posix_error();
11358
Steve Dower8fc89802015-04-12 00:26:27 -040011359 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011360 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011361 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011362 if (blocking < 0)
11363 return NULL;
11364 return PyBool_FromLong(blocking);
11365}
11366
11367PyDoc_STRVAR(set_blocking__doc__,
11368 "set_blocking(fd, blocking)\n" \
11369 "\n" \
11370 "Set the blocking mode of the specified file descriptor.\n" \
11371 "Set the O_NONBLOCK flag if blocking is False,\n" \
11372 "clear the O_NONBLOCK flag otherwise.");
11373
11374static PyObject*
11375posix_set_blocking(PyObject *self, PyObject *args)
11376{
Steve Dower8fc89802015-04-12 00:26:27 -040011377 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011378
11379 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11380 return NULL;
11381
11382 if (!_PyVerify_fd(fd))
11383 return posix_error();
11384
Steve Dower8fc89802015-04-12 00:26:27 -040011385 _Py_BEGIN_SUPPRESS_IPH
11386 result = _Py_set_blocking(fd, blocking);
11387 _Py_END_SUPPRESS_IPH
11388 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011389 return NULL;
11390 Py_RETURN_NONE;
11391}
11392#endif /* !MS_WINDOWS */
11393
11394
Victor Stinner6036e442015-03-08 01:58:04 +010011395PyDoc_STRVAR(posix_scandir__doc__,
11396"scandir(path='.') -> iterator of DirEntry objects for given path");
11397
11398static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11399
11400typedef struct {
11401 PyObject_HEAD
11402 PyObject *name;
11403 PyObject *path;
11404 PyObject *stat;
11405 PyObject *lstat;
11406#ifdef MS_WINDOWS
11407 struct _Py_stat_struct win32_lstat;
11408 __int64 win32_file_index;
11409 int got_file_index;
11410#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011411#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011412 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011413#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011414 ino_t d_ino;
11415#endif
11416} DirEntry;
11417
11418static void
11419DirEntry_dealloc(DirEntry *entry)
11420{
11421 Py_XDECREF(entry->name);
11422 Py_XDECREF(entry->path);
11423 Py_XDECREF(entry->stat);
11424 Py_XDECREF(entry->lstat);
11425 Py_TYPE(entry)->tp_free((PyObject *)entry);
11426}
11427
11428/* Forward reference */
11429static int
11430DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11431
11432/* Set exception and return -1 on error, 0 for False, 1 for True */
11433static int
11434DirEntry_is_symlink(DirEntry *self)
11435{
11436#ifdef MS_WINDOWS
11437 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011438#elif defined(HAVE_DIRENT_D_TYPE)
11439 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011440 if (self->d_type != DT_UNKNOWN)
11441 return self->d_type == DT_LNK;
11442 else
11443 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011444#else
11445 /* POSIX without d_type */
11446 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011447#endif
11448}
11449
11450static PyObject *
11451DirEntry_py_is_symlink(DirEntry *self)
11452{
11453 int result;
11454
11455 result = DirEntry_is_symlink(self);
11456 if (result == -1)
11457 return NULL;
11458 return PyBool_FromLong(result);
11459}
11460
11461static PyObject *
11462DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11463{
11464 int result;
11465 struct _Py_stat_struct st;
11466
11467#ifdef MS_WINDOWS
11468 wchar_t *path;
11469
11470 path = PyUnicode_AsUnicode(self->path);
11471 if (!path)
11472 return NULL;
11473
11474 if (follow_symlinks)
11475 result = win32_stat_w(path, &st);
11476 else
11477 result = win32_lstat_w(path, &st);
11478
11479 if (result != 0) {
11480 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11481 0, self->path);
11482 }
11483#else /* POSIX */
11484 PyObject *bytes;
11485 char *path;
11486
11487 if (!PyUnicode_FSConverter(self->path, &bytes))
11488 return NULL;
11489 path = PyBytes_AS_STRING(bytes);
11490
11491 if (follow_symlinks)
11492 result = STAT(path, &st);
11493 else
11494 result = LSTAT(path, &st);
11495 Py_DECREF(bytes);
11496
11497 if (result != 0)
11498 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11499#endif
11500
11501 return _pystat_fromstructstat(&st);
11502}
11503
11504static PyObject *
11505DirEntry_get_lstat(DirEntry *self)
11506{
11507 if (!self->lstat) {
11508#ifdef MS_WINDOWS
11509 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11510#else /* POSIX */
11511 self->lstat = DirEntry_fetch_stat(self, 0);
11512#endif
11513 }
11514 Py_XINCREF(self->lstat);
11515 return self->lstat;
11516}
11517
11518static PyObject *
11519DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11520{
11521 if (!follow_symlinks)
11522 return DirEntry_get_lstat(self);
11523
11524 if (!self->stat) {
11525 int result = DirEntry_is_symlink(self);
11526 if (result == -1)
11527 return NULL;
11528 else if (result)
11529 self->stat = DirEntry_fetch_stat(self, 1);
11530 else
11531 self->stat = DirEntry_get_lstat(self);
11532 }
11533
11534 Py_XINCREF(self->stat);
11535 return self->stat;
11536}
11537
11538static PyObject *
11539DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11540{
11541 int follow_symlinks = 1;
11542
11543 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11544 follow_symlinks_keywords, &follow_symlinks))
11545 return NULL;
11546
11547 return DirEntry_get_stat(self, follow_symlinks);
11548}
11549
11550/* Set exception and return -1 on error, 0 for False, 1 for True */
11551static int
11552DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11553{
11554 PyObject *stat = NULL;
11555 PyObject *st_mode = NULL;
11556 long mode;
11557 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011558#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011559 int is_symlink;
11560 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011561#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011562#ifdef MS_WINDOWS
11563 unsigned long dir_bits;
11564#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011565 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011566
11567#ifdef MS_WINDOWS
11568 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11569 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011570#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011571 is_symlink = self->d_type == DT_LNK;
11572 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11573#endif
11574
Victor Stinner35a97c02015-03-08 02:59:09 +010011575#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011576 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011577#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011578 stat = DirEntry_get_stat(self, follow_symlinks);
11579 if (!stat) {
11580 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11581 /* If file doesn't exist (anymore), then return False
11582 (i.e., say it's not a file/directory) */
11583 PyErr_Clear();
11584 return 0;
11585 }
11586 goto error;
11587 }
11588 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11589 if (!st_mode)
11590 goto error;
11591
11592 mode = PyLong_AsLong(st_mode);
11593 if (mode == -1 && PyErr_Occurred())
11594 goto error;
11595 Py_CLEAR(st_mode);
11596 Py_CLEAR(stat);
11597 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011598#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011599 }
11600 else if (is_symlink) {
11601 assert(mode_bits != S_IFLNK);
11602 result = 0;
11603 }
11604 else {
11605 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11606#ifdef MS_WINDOWS
11607 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11608 if (mode_bits == S_IFDIR)
11609 result = dir_bits != 0;
11610 else
11611 result = dir_bits == 0;
11612#else /* POSIX */
11613 if (mode_bits == S_IFDIR)
11614 result = self->d_type == DT_DIR;
11615 else
11616 result = self->d_type == DT_REG;
11617#endif
11618 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011619#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011620
11621 return result;
11622
11623error:
11624 Py_XDECREF(st_mode);
11625 Py_XDECREF(stat);
11626 return -1;
11627}
11628
11629static PyObject *
11630DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11631{
11632 int result;
11633
11634 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11635 if (result == -1)
11636 return NULL;
11637 return PyBool_FromLong(result);
11638}
11639
11640static PyObject *
11641DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11642{
11643 int follow_symlinks = 1;
11644
11645 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11646 follow_symlinks_keywords, &follow_symlinks))
11647 return NULL;
11648
11649 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11650}
11651
11652static PyObject *
11653DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11654{
11655 int follow_symlinks = 1;
11656
11657 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11658 follow_symlinks_keywords, &follow_symlinks))
11659 return NULL;
11660
11661 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11662}
11663
11664static PyObject *
11665DirEntry_inode(DirEntry *self)
11666{
11667#ifdef MS_WINDOWS
11668 if (!self->got_file_index) {
11669 wchar_t *path;
11670 struct _Py_stat_struct stat;
11671
11672 path = PyUnicode_AsUnicode(self->path);
11673 if (!path)
11674 return NULL;
11675
11676 if (win32_lstat_w(path, &stat) != 0) {
11677 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11678 0, self->path);
11679 }
11680
11681 self->win32_file_index = stat.st_ino;
11682 self->got_file_index = 1;
11683 }
11684 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11685#else /* POSIX */
11686#ifdef HAVE_LARGEFILE_SUPPORT
11687 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11688#else
11689 return PyLong_FromLong((long)self->d_ino);
11690#endif
11691#endif
11692}
11693
11694static PyObject *
11695DirEntry_repr(DirEntry *self)
11696{
11697 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11698}
11699
11700static PyMemberDef DirEntry_members[] = {
11701 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11702 "the entry's base filename, relative to scandir() \"path\" argument"},
11703 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11704 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11705 {NULL}
11706};
11707
11708static PyMethodDef DirEntry_methods[] = {
11709 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11710 "return True if the entry is a directory; cached per entry"
11711 },
11712 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11713 "return True if the entry is a file; cached per entry"
11714 },
11715 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11716 "return True if the entry is a symbolic link; cached per entry"
11717 },
11718 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11719 "return stat_result object for the entry; cached per entry"
11720 },
11721 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11722 "return inode of the entry; cached per entry",
11723 },
11724 {NULL}
11725};
11726
Benjamin Peterson5646de42015-04-12 17:56:34 -040011727static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011728 PyVarObject_HEAD_INIT(NULL, 0)
11729 MODNAME ".DirEntry", /* tp_name */
11730 sizeof(DirEntry), /* tp_basicsize */
11731 0, /* tp_itemsize */
11732 /* methods */
11733 (destructor)DirEntry_dealloc, /* tp_dealloc */
11734 0, /* tp_print */
11735 0, /* tp_getattr */
11736 0, /* tp_setattr */
11737 0, /* tp_compare */
11738 (reprfunc)DirEntry_repr, /* tp_repr */
11739 0, /* tp_as_number */
11740 0, /* tp_as_sequence */
11741 0, /* tp_as_mapping */
11742 0, /* tp_hash */
11743 0, /* tp_call */
11744 0, /* tp_str */
11745 0, /* tp_getattro */
11746 0, /* tp_setattro */
11747 0, /* tp_as_buffer */
11748 Py_TPFLAGS_DEFAULT, /* tp_flags */
11749 0, /* tp_doc */
11750 0, /* tp_traverse */
11751 0, /* tp_clear */
11752 0, /* tp_richcompare */
11753 0, /* tp_weaklistoffset */
11754 0, /* tp_iter */
11755 0, /* tp_iternext */
11756 DirEntry_methods, /* tp_methods */
11757 DirEntry_members, /* tp_members */
11758};
11759
11760#ifdef MS_WINDOWS
11761
11762static wchar_t *
11763join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11764{
11765 Py_ssize_t path_len;
11766 Py_ssize_t size;
11767 wchar_t *result;
11768 wchar_t ch;
11769
11770 if (!path_wide) { /* Default arg: "." */
11771 path_wide = L".";
11772 path_len = 1;
11773 }
11774 else {
11775 path_len = wcslen(path_wide);
11776 }
11777
11778 /* The +1's are for the path separator and the NUL */
11779 size = path_len + 1 + wcslen(filename) + 1;
11780 result = PyMem_New(wchar_t, size);
11781 if (!result) {
11782 PyErr_NoMemory();
11783 return NULL;
11784 }
11785 wcscpy(result, path_wide);
11786 if (path_len > 0) {
11787 ch = result[path_len - 1];
11788 if (ch != SEP && ch != ALTSEP && ch != L':')
11789 result[path_len++] = SEP;
11790 wcscpy(result + path_len, filename);
11791 }
11792 return result;
11793}
11794
11795static PyObject *
11796DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11797{
11798 DirEntry *entry;
11799 BY_HANDLE_FILE_INFORMATION file_info;
11800 ULONG reparse_tag;
11801 wchar_t *joined_path;
11802
11803 entry = PyObject_New(DirEntry, &DirEntryType);
11804 if (!entry)
11805 return NULL;
11806 entry->name = NULL;
11807 entry->path = NULL;
11808 entry->stat = NULL;
11809 entry->lstat = NULL;
11810 entry->got_file_index = 0;
11811
11812 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11813 if (!entry->name)
11814 goto error;
11815
11816 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11817 if (!joined_path)
11818 goto error;
11819
11820 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11821 PyMem_Free(joined_path);
11822 if (!entry->path)
11823 goto error;
11824
11825 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11826 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11827
11828 return (PyObject *)entry;
11829
11830error:
11831 Py_DECREF(entry);
11832 return NULL;
11833}
11834
11835#else /* POSIX */
11836
11837static char *
11838join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11839{
11840 Py_ssize_t path_len;
11841 Py_ssize_t size;
11842 char *result;
11843
11844 if (!path_narrow) { /* Default arg: "." */
11845 path_narrow = ".";
11846 path_len = 1;
11847 }
11848 else {
11849 path_len = strlen(path_narrow);
11850 }
11851
11852 if (filename_len == -1)
11853 filename_len = strlen(filename);
11854
11855 /* The +1's are for the path separator and the NUL */
11856 size = path_len + 1 + filename_len + 1;
11857 result = PyMem_New(char, size);
11858 if (!result) {
11859 PyErr_NoMemory();
11860 return NULL;
11861 }
11862 strcpy(result, path_narrow);
11863 if (path_len > 0 && result[path_len - 1] != '/')
11864 result[path_len++] = '/';
11865 strcpy(result + path_len, filename);
11866 return result;
11867}
11868
11869static PyObject *
11870DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011871 ino_t d_ino
11872#ifdef HAVE_DIRENT_D_TYPE
11873 , unsigned char d_type
11874#endif
11875 )
Victor Stinner6036e442015-03-08 01:58:04 +010011876{
11877 DirEntry *entry;
11878 char *joined_path;
11879
11880 entry = PyObject_New(DirEntry, &DirEntryType);
11881 if (!entry)
11882 return NULL;
11883 entry->name = NULL;
11884 entry->path = NULL;
11885 entry->stat = NULL;
11886 entry->lstat = NULL;
11887
11888 joined_path = join_path_filename(path->narrow, name, name_len);
11889 if (!joined_path)
11890 goto error;
11891
11892 if (!path->narrow || !PyBytes_Check(path->object)) {
11893 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11894 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11895 }
11896 else {
11897 entry->name = PyBytes_FromStringAndSize(name, name_len);
11898 entry->path = PyBytes_FromString(joined_path);
11899 }
11900 PyMem_Free(joined_path);
11901 if (!entry->name || !entry->path)
11902 goto error;
11903
Victor Stinner35a97c02015-03-08 02:59:09 +010011904#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011905 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011906#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011907 entry->d_ino = d_ino;
11908
11909 return (PyObject *)entry;
11910
11911error:
11912 Py_XDECREF(entry);
11913 return NULL;
11914}
11915
11916#endif
11917
11918
11919typedef struct {
11920 PyObject_HEAD
11921 path_t path;
11922#ifdef MS_WINDOWS
11923 HANDLE handle;
11924 WIN32_FIND_DATAW file_data;
11925 int first_time;
11926#else /* POSIX */
11927 DIR *dirp;
11928#endif
11929} ScandirIterator;
11930
11931#ifdef MS_WINDOWS
11932
11933static void
11934ScandirIterator_close(ScandirIterator *iterator)
11935{
11936 if (iterator->handle == INVALID_HANDLE_VALUE)
11937 return;
11938
11939 Py_BEGIN_ALLOW_THREADS
11940 FindClose(iterator->handle);
11941 Py_END_ALLOW_THREADS
11942 iterator->handle = INVALID_HANDLE_VALUE;
11943}
11944
11945static PyObject *
11946ScandirIterator_iternext(ScandirIterator *iterator)
11947{
11948 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11949 BOOL success;
11950
11951 /* Happens if the iterator is iterated twice */
11952 if (iterator->handle == INVALID_HANDLE_VALUE) {
11953 PyErr_SetNone(PyExc_StopIteration);
11954 return NULL;
11955 }
11956
11957 while (1) {
11958 if (!iterator->first_time) {
11959 Py_BEGIN_ALLOW_THREADS
11960 success = FindNextFileW(iterator->handle, file_data);
11961 Py_END_ALLOW_THREADS
11962 if (!success) {
11963 if (GetLastError() != ERROR_NO_MORE_FILES)
11964 return path_error(&iterator->path);
11965 /* No more files found in directory, stop iterating */
11966 break;
11967 }
11968 }
11969 iterator->first_time = 0;
11970
11971 /* Skip over . and .. */
11972 if (wcscmp(file_data->cFileName, L".") != 0 &&
11973 wcscmp(file_data->cFileName, L"..") != 0)
11974 return DirEntry_from_find_data(&iterator->path, file_data);
11975
11976 /* Loop till we get a non-dot directory or finish iterating */
11977 }
11978
11979 ScandirIterator_close(iterator);
11980
11981 PyErr_SetNone(PyExc_StopIteration);
11982 return NULL;
11983}
11984
11985#else /* POSIX */
11986
11987static void
11988ScandirIterator_close(ScandirIterator *iterator)
11989{
11990 if (!iterator->dirp)
11991 return;
11992
11993 Py_BEGIN_ALLOW_THREADS
11994 closedir(iterator->dirp);
11995 Py_END_ALLOW_THREADS
11996 iterator->dirp = NULL;
11997 return;
11998}
11999
12000static PyObject *
12001ScandirIterator_iternext(ScandirIterator *iterator)
12002{
12003 struct dirent *direntp;
12004 Py_ssize_t name_len;
12005 int is_dot;
Victor Stinner6036e442015-03-08 01:58:04 +010012006
12007 /* Happens if the iterator is iterated twice */
12008 if (!iterator->dirp) {
12009 PyErr_SetNone(PyExc_StopIteration);
12010 return NULL;
12011 }
12012
12013 while (1) {
12014 errno = 0;
12015 Py_BEGIN_ALLOW_THREADS
12016 direntp = readdir(iterator->dirp);
12017 Py_END_ALLOW_THREADS
12018
12019 if (!direntp) {
12020 if (errno != 0)
12021 return path_error(&iterator->path);
12022 /* No more files found in directory, stop iterating */
12023 break;
12024 }
12025
12026 /* Skip over . and .. */
12027 name_len = NAMLEN(direntp);
12028 is_dot = direntp->d_name[0] == '.' &&
12029 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
12030 if (!is_dot) {
Victor Stinner6036e442015-03-08 01:58:04 +010012031 return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012032 name_len, direntp->d_ino
12033#ifdef HAVE_DIRENT_D_TYPE
12034 , direntp->d_type
12035#endif
12036 );
Victor Stinner6036e442015-03-08 01:58:04 +010012037 }
12038
12039 /* Loop till we get a non-dot directory or finish iterating */
12040 }
12041
12042 ScandirIterator_close(iterator);
12043
12044 PyErr_SetNone(PyExc_StopIteration);
12045 return NULL;
12046}
12047
12048#endif
12049
12050static void
12051ScandirIterator_dealloc(ScandirIterator *iterator)
12052{
12053 ScandirIterator_close(iterator);
12054 Py_XDECREF(iterator->path.object);
12055 path_cleanup(&iterator->path);
12056 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12057}
12058
Benjamin Peterson5646de42015-04-12 17:56:34 -040012059static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012060 PyVarObject_HEAD_INIT(NULL, 0)
12061 MODNAME ".ScandirIterator", /* tp_name */
12062 sizeof(ScandirIterator), /* tp_basicsize */
12063 0, /* tp_itemsize */
12064 /* methods */
12065 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12066 0, /* tp_print */
12067 0, /* tp_getattr */
12068 0, /* tp_setattr */
12069 0, /* tp_compare */
12070 0, /* tp_repr */
12071 0, /* tp_as_number */
12072 0, /* tp_as_sequence */
12073 0, /* tp_as_mapping */
12074 0, /* tp_hash */
12075 0, /* tp_call */
12076 0, /* tp_str */
12077 0, /* tp_getattro */
12078 0, /* tp_setattro */
12079 0, /* tp_as_buffer */
12080 Py_TPFLAGS_DEFAULT, /* tp_flags */
12081 0, /* tp_doc */
12082 0, /* tp_traverse */
12083 0, /* tp_clear */
12084 0, /* tp_richcompare */
12085 0, /* tp_weaklistoffset */
12086 PyObject_SelfIter, /* tp_iter */
12087 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12088};
12089
12090static PyObject *
12091posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12092{
12093 ScandirIterator *iterator;
12094 static char *keywords[] = {"path", NULL};
12095#ifdef MS_WINDOWS
12096 wchar_t *path_strW;
12097#else
12098 char *path;
12099#endif
12100
12101 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12102 if (!iterator)
12103 return NULL;
12104 memset(&iterator->path, 0, sizeof(path_t));
12105 iterator->path.function_name = "scandir";
12106 iterator->path.nullable = 1;
12107
12108#ifdef MS_WINDOWS
12109 iterator->handle = INVALID_HANDLE_VALUE;
12110#else
12111 iterator->dirp = NULL;
12112#endif
12113
12114 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12115 path_converter, &iterator->path))
12116 goto error;
12117
12118 /* path_converter doesn't keep path.object around, so do it
12119 manually for the lifetime of the iterator here (the refcount
12120 is decremented in ScandirIterator_dealloc)
12121 */
12122 Py_XINCREF(iterator->path.object);
12123
12124#ifdef MS_WINDOWS
12125 if (iterator->path.narrow) {
12126 PyErr_SetString(PyExc_TypeError,
12127 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12128 goto error;
12129 }
12130 iterator->first_time = 1;
12131
12132 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12133 if (!path_strW)
12134 goto error;
12135
12136 Py_BEGIN_ALLOW_THREADS
12137 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12138 Py_END_ALLOW_THREADS
12139
12140 PyMem_Free(path_strW);
12141
12142 if (iterator->handle == INVALID_HANDLE_VALUE) {
12143 path_error(&iterator->path);
12144 goto error;
12145 }
12146#else /* POSIX */
12147 if (iterator->path.narrow)
12148 path = iterator->path.narrow;
12149 else
12150 path = ".";
12151
12152 errno = 0;
12153 Py_BEGIN_ALLOW_THREADS
12154 iterator->dirp = opendir(path);
12155 Py_END_ALLOW_THREADS
12156
12157 if (!iterator->dirp) {
12158 path_error(&iterator->path);
12159 goto error;
12160 }
12161#endif
12162
12163 return (PyObject *)iterator;
12164
12165error:
12166 Py_DECREF(iterator);
12167 return NULL;
12168}
12169
12170
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012171#include "clinic/posixmodule.c.h"
12172
Larry Hastings7726ac92014-01-31 22:03:12 -080012173/*[clinic input]
12174dump buffer
12175[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012176/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012177
Larry Hastings31826802013-10-19 00:09:25 -070012178
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012179static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012180
12181 OS_STAT_METHODDEF
12182 OS_ACCESS_METHODDEF
12183 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012184 OS_CHDIR_METHODDEF
12185 OS_CHFLAGS_METHODDEF
12186 OS_CHMOD_METHODDEF
12187 OS_FCHMOD_METHODDEF
12188 OS_LCHMOD_METHODDEF
12189 OS_CHOWN_METHODDEF
12190 OS_FCHOWN_METHODDEF
12191 OS_LCHOWN_METHODDEF
12192 OS_LCHFLAGS_METHODDEF
12193 OS_CHROOT_METHODDEF
12194 OS_CTERMID_METHODDEF
12195 OS_GETCWD_METHODDEF
12196 OS_GETCWDB_METHODDEF
12197 OS_LINK_METHODDEF
12198 OS_LISTDIR_METHODDEF
12199 OS_LSTAT_METHODDEF
12200 OS_MKDIR_METHODDEF
12201 OS_NICE_METHODDEF
12202 OS_GETPRIORITY_METHODDEF
12203 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012204#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012205 {"readlink", (PyCFunction)posix_readlink,
12206 METH_VARARGS | METH_KEYWORDS,
12207 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012208#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012209#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012210 {"readlink", (PyCFunction)win_readlink,
12211 METH_VARARGS | METH_KEYWORDS,
12212 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012213#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012214 OS_RENAME_METHODDEF
12215 OS_REPLACE_METHODDEF
12216 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012217 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012218 OS_SYMLINK_METHODDEF
12219 OS_SYSTEM_METHODDEF
12220 OS_UMASK_METHODDEF
12221 OS_UNAME_METHODDEF
12222 OS_UNLINK_METHODDEF
12223 OS_REMOVE_METHODDEF
12224 OS_UTIME_METHODDEF
12225 OS_TIMES_METHODDEF
12226 OS__EXIT_METHODDEF
12227 OS_EXECV_METHODDEF
12228 OS_EXECVE_METHODDEF
12229 OS_SPAWNV_METHODDEF
12230 OS_SPAWNVE_METHODDEF
12231 OS_FORK1_METHODDEF
12232 OS_FORK_METHODDEF
12233 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12234 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12235 OS_SCHED_GETPARAM_METHODDEF
12236 OS_SCHED_GETSCHEDULER_METHODDEF
12237 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12238 OS_SCHED_SETPARAM_METHODDEF
12239 OS_SCHED_SETSCHEDULER_METHODDEF
12240 OS_SCHED_YIELD_METHODDEF
12241 OS_SCHED_SETAFFINITY_METHODDEF
12242 OS_SCHED_GETAFFINITY_METHODDEF
12243 OS_OPENPTY_METHODDEF
12244 OS_FORKPTY_METHODDEF
12245 OS_GETEGID_METHODDEF
12246 OS_GETEUID_METHODDEF
12247 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012248#ifdef HAVE_GETGROUPLIST
12249 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12250#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012251 OS_GETGROUPS_METHODDEF
12252 OS_GETPID_METHODDEF
12253 OS_GETPGRP_METHODDEF
12254 OS_GETPPID_METHODDEF
12255 OS_GETUID_METHODDEF
12256 OS_GETLOGIN_METHODDEF
12257 OS_KILL_METHODDEF
12258 OS_KILLPG_METHODDEF
12259 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012260#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012261 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012262#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012263 OS_SETUID_METHODDEF
12264 OS_SETEUID_METHODDEF
12265 OS_SETREUID_METHODDEF
12266 OS_SETGID_METHODDEF
12267 OS_SETEGID_METHODDEF
12268 OS_SETREGID_METHODDEF
12269 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012270#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012271 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012272#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012273 OS_GETPGID_METHODDEF
12274 OS_SETPGRP_METHODDEF
12275 OS_WAIT_METHODDEF
12276 OS_WAIT3_METHODDEF
12277 OS_WAIT4_METHODDEF
12278 OS_WAITID_METHODDEF
12279 OS_WAITPID_METHODDEF
12280 OS_GETSID_METHODDEF
12281 OS_SETSID_METHODDEF
12282 OS_SETPGID_METHODDEF
12283 OS_TCGETPGRP_METHODDEF
12284 OS_TCSETPGRP_METHODDEF
12285 OS_OPEN_METHODDEF
12286 OS_CLOSE_METHODDEF
12287 OS_CLOSERANGE_METHODDEF
12288 OS_DEVICE_ENCODING_METHODDEF
12289 OS_DUP_METHODDEF
12290 OS_DUP2_METHODDEF
12291 OS_LOCKF_METHODDEF
12292 OS_LSEEK_METHODDEF
12293 OS_READ_METHODDEF
12294 OS_READV_METHODDEF
12295 OS_PREAD_METHODDEF
12296 OS_WRITE_METHODDEF
12297 OS_WRITEV_METHODDEF
12298 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012299#ifdef HAVE_SENDFILE
12300 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12301 posix_sendfile__doc__},
12302#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012303 OS_FSTAT_METHODDEF
12304 OS_ISATTY_METHODDEF
12305 OS_PIPE_METHODDEF
12306 OS_PIPE2_METHODDEF
12307 OS_MKFIFO_METHODDEF
12308 OS_MKNOD_METHODDEF
12309 OS_MAJOR_METHODDEF
12310 OS_MINOR_METHODDEF
12311 OS_MAKEDEV_METHODDEF
12312 OS_FTRUNCATE_METHODDEF
12313 OS_TRUNCATE_METHODDEF
12314 OS_POSIX_FALLOCATE_METHODDEF
12315 OS_POSIX_FADVISE_METHODDEF
12316 OS_PUTENV_METHODDEF
12317 OS_UNSETENV_METHODDEF
12318 OS_STRERROR_METHODDEF
12319 OS_FCHDIR_METHODDEF
12320 OS_FSYNC_METHODDEF
12321 OS_SYNC_METHODDEF
12322 OS_FDATASYNC_METHODDEF
12323 OS_WCOREDUMP_METHODDEF
12324 OS_WIFCONTINUED_METHODDEF
12325 OS_WIFSTOPPED_METHODDEF
12326 OS_WIFSIGNALED_METHODDEF
12327 OS_WIFEXITED_METHODDEF
12328 OS_WEXITSTATUS_METHODDEF
12329 OS_WTERMSIG_METHODDEF
12330 OS_WSTOPSIG_METHODDEF
12331 OS_FSTATVFS_METHODDEF
12332 OS_STATVFS_METHODDEF
12333 OS_CONFSTR_METHODDEF
12334 OS_SYSCONF_METHODDEF
12335 OS_FPATHCONF_METHODDEF
12336 OS_PATHCONF_METHODDEF
12337 OS_ABORT_METHODDEF
Serhiy Storchakaf0b50152015-05-13 00:52:39 +030012338 OS__GETFULLPATHNAME_METHODDEF
12339 OS__ISDIR_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012340 OS__GETDISKUSAGE_METHODDEF
12341 OS__GETFINALPATHNAME_METHODDEF
12342 OS__GETVOLUMEPATHNAME_METHODDEF
12343 OS_GETLOADAVG_METHODDEF
12344 OS_URANDOM_METHODDEF
12345 OS_SETRESUID_METHODDEF
12346 OS_SETRESGID_METHODDEF
12347 OS_GETRESUID_METHODDEF
12348 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012349
Larry Hastings2f936352014-08-05 14:04:04 +100012350 OS_GETXATTR_METHODDEF
12351 OS_SETXATTR_METHODDEF
12352 OS_REMOVEXATTR_METHODDEF
12353 OS_LISTXATTR_METHODDEF
12354
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012355#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12356 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12357#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012358 OS_CPU_COUNT_METHODDEF
12359 OS_GET_INHERITABLE_METHODDEF
12360 OS_SET_INHERITABLE_METHODDEF
12361 OS_GET_HANDLE_INHERITABLE_METHODDEF
12362 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012363#ifndef MS_WINDOWS
12364 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12365 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12366#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012367 {"scandir", (PyCFunction)posix_scandir,
12368 METH_VARARGS | METH_KEYWORDS,
12369 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012370 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012371};
12372
12373
Brian Curtin52173d42010-12-02 18:29:18 +000012374#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012375static int
Brian Curtin52173d42010-12-02 18:29:18 +000012376enable_symlink()
12377{
12378 HANDLE tok;
12379 TOKEN_PRIVILEGES tok_priv;
12380 LUID luid;
Brian Curtin52173d42010-12-02 18:29:18 +000012381
12382 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012383 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012384
12385 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012386 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012387
12388 tok_priv.PrivilegeCount = 1;
12389 tok_priv.Privileges[0].Luid = luid;
12390 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12391
12392 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12393 sizeof(TOKEN_PRIVILEGES),
12394 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012395 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012396
Brian Curtin3b4499c2010-12-28 14:31:47 +000012397 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12398 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012399}
12400#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12401
Barry Warsaw4a342091996-12-19 23:50:02 +000012402static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012403all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012404{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012405#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012406 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012407#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012408#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012409 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012410#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012411#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012412 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012413#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012414#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012415 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012416#endif
Fred Drakec9680921999-12-13 16:37:25 +000012417#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012418 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012419#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012420#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012421 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012422#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012423#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012424 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012425#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012426#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012427 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012428#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012429#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012430 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012431#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012432#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012433 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012434#endif
12435#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012436 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012437#endif
12438#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012439 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012440#endif
12441#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012442 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012443#endif
12444#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012445 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012446#endif
12447#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012448 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012449#endif
12450#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012451 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012452#endif
12453#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012454 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012455#endif
12456#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012457 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012458#endif
12459#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012460 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012461#endif
12462#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012463 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012464#endif
12465#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012466 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012467#endif
12468#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012469 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012470#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012471#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012472 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012473#endif
12474#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012475 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012476#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012477#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012478 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012479#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012480#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012481 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012482#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012483#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012484 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012485#endif
12486#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012487 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012488#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012489#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012490 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012491#endif
12492#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012493 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012494#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012495#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012497#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012498#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012499 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012500#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012501#ifdef O_TMPFILE
12502 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12503#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012504#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012505 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012506#endif
12507#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012508 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012509#endif
12510#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012512#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012513#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012514 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012515#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012516#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012517 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012518#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012519
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012520
Jesus Cea94363612012-06-22 18:32:07 +020012521#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012522 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012523#endif
12524#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012525 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012526#endif
12527
Tim Peters5aa91602002-01-30 05:46:57 +000012528/* MS Windows */
12529#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012530 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012531 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012532#endif
12533#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012534 /* Optimize for short life (keep in memory). */
12535 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012536 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012537#endif
12538#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012539 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012540 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012541#endif
12542#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012543 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012544 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012545#endif
12546#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012547 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012548 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012549#endif
12550
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012551/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012552#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012553 /* Send a SIGIO signal whenever input or output
12554 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012555 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012556#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012557#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012558 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012559 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012560#endif
12561#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012562 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012563 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012564#endif
12565#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012566 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012567 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012568#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012569#ifdef O_NOLINKS
12570 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012571 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012572#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012573#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012574 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012576#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012577
Victor Stinner8c62be82010-05-06 00:08:46 +000012578 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012579#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012580 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012581#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012582#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012583 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012584#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012585#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012586 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012587#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012588#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012589 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012590#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012591#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012592 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012593#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012594#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012595 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012596#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012597#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012598 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012599#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012600#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012601 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012602#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012603#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012605#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012606#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012608#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012609#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012610 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012611#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012612#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012613 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012614#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012615#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012616 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012617#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012618#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012619 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012620#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012621#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012622 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012623#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012624#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012625 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012626#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012627#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012628 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012629#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012630
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012631 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012632#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012633 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012634#endif /* ST_RDONLY */
12635#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012636 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012637#endif /* ST_NOSUID */
12638
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012639 /* GNU extensions */
12640#ifdef ST_NODEV
12641 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12642#endif /* ST_NODEV */
12643#ifdef ST_NOEXEC
12644 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12645#endif /* ST_NOEXEC */
12646#ifdef ST_SYNCHRONOUS
12647 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12648#endif /* ST_SYNCHRONOUS */
12649#ifdef ST_MANDLOCK
12650 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12651#endif /* ST_MANDLOCK */
12652#ifdef ST_WRITE
12653 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12654#endif /* ST_WRITE */
12655#ifdef ST_APPEND
12656 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12657#endif /* ST_APPEND */
12658#ifdef ST_NOATIME
12659 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12660#endif /* ST_NOATIME */
12661#ifdef ST_NODIRATIME
12662 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12663#endif /* ST_NODIRATIME */
12664#ifdef ST_RELATIME
12665 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12666#endif /* ST_RELATIME */
12667
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012668 /* FreeBSD sendfile() constants */
12669#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012670 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012671#endif
12672#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012673 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012674#endif
12675#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012676 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012677#endif
12678
Ross Lagerwall7807c352011-03-17 20:20:30 +020012679 /* constants for posix_fadvise */
12680#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012681 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012682#endif
12683#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012684 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012685#endif
12686#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012687 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012688#endif
12689#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012690 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012691#endif
12692#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012693 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012694#endif
12695#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012696 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012697#endif
12698
12699 /* constants for waitid */
12700#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012701 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12702 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12703 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012704#endif
12705#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012707#endif
12708#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012710#endif
12711#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012712 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012713#endif
12714#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012715 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012716#endif
12717#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012718 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012719#endif
12720#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012721 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012722#endif
12723#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012724 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012725#endif
12726
12727 /* constants for lockf */
12728#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012729 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012730#endif
12731#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012732 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012733#endif
12734#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012735 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012736#endif
12737#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012738 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012739#endif
12740
Guido van Rossum246bc171999-02-01 23:54:31 +000012741#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012742 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12743 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12744 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12745 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12746 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012747#endif
12748
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012749#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012750 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12751 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12752 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012753#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012754 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012755#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012756#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012758#endif
12759#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012761#endif
12762#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012764#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012765#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012767#endif
12768#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012770#endif
12771#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012773#endif
12774#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012776#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012777#endif
12778
Benjamin Peterson9428d532011-09-14 11:45:52 -040012779#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012780 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12781 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12782 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012783#endif
12784
Victor Stinner8b905bd2011-10-25 13:34:04 +020012785#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012786 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012787#endif
12788#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012789 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012790#endif
12791#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012792 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012793#endif
12794#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012795 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012796#endif
12797#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012798 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012799#endif
12800#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012801 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012802#endif
12803#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012804 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012805#endif
12806
Victor Stinner8c62be82010-05-06 00:08:46 +000012807 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012808}
12809
12810
Martin v. Löwis1a214512008-06-11 05:26:20 +000012811static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012812 PyModuleDef_HEAD_INIT,
12813 MODNAME,
12814 posix__doc__,
12815 -1,
12816 posix_methods,
12817 NULL,
12818 NULL,
12819 NULL,
12820 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012821};
12822
12823
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012824static const char * const have_functions[] = {
Larry Hastings9cf065c2012-06-22 16:30:09 -070012825
12826#ifdef HAVE_FACCESSAT
12827 "HAVE_FACCESSAT",
12828#endif
12829
12830#ifdef HAVE_FCHDIR
12831 "HAVE_FCHDIR",
12832#endif
12833
12834#ifdef HAVE_FCHMOD
12835 "HAVE_FCHMOD",
12836#endif
12837
12838#ifdef HAVE_FCHMODAT
12839 "HAVE_FCHMODAT",
12840#endif
12841
12842#ifdef HAVE_FCHOWN
12843 "HAVE_FCHOWN",
12844#endif
12845
Larry Hastings00964ed2013-08-12 13:49:30 -040012846#ifdef HAVE_FCHOWNAT
12847 "HAVE_FCHOWNAT",
12848#endif
12849
Larry Hastings9cf065c2012-06-22 16:30:09 -070012850#ifdef HAVE_FEXECVE
12851 "HAVE_FEXECVE",
12852#endif
12853
12854#ifdef HAVE_FDOPENDIR
12855 "HAVE_FDOPENDIR",
12856#endif
12857
Georg Brandl306336b2012-06-24 12:55:33 +020012858#ifdef HAVE_FPATHCONF
12859 "HAVE_FPATHCONF",
12860#endif
12861
Larry Hastings9cf065c2012-06-22 16:30:09 -070012862#ifdef HAVE_FSTATAT
12863 "HAVE_FSTATAT",
12864#endif
12865
12866#ifdef HAVE_FSTATVFS
12867 "HAVE_FSTATVFS",
12868#endif
12869
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012870#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012871 "HAVE_FTRUNCATE",
12872#endif
12873
Larry Hastings9cf065c2012-06-22 16:30:09 -070012874#ifdef HAVE_FUTIMENS
12875 "HAVE_FUTIMENS",
12876#endif
12877
12878#ifdef HAVE_FUTIMES
12879 "HAVE_FUTIMES",
12880#endif
12881
12882#ifdef HAVE_FUTIMESAT
12883 "HAVE_FUTIMESAT",
12884#endif
12885
12886#ifdef HAVE_LINKAT
12887 "HAVE_LINKAT",
12888#endif
12889
12890#ifdef HAVE_LCHFLAGS
12891 "HAVE_LCHFLAGS",
12892#endif
12893
12894#ifdef HAVE_LCHMOD
12895 "HAVE_LCHMOD",
12896#endif
12897
12898#ifdef HAVE_LCHOWN
12899 "HAVE_LCHOWN",
12900#endif
12901
12902#ifdef HAVE_LSTAT
12903 "HAVE_LSTAT",
12904#endif
12905
12906#ifdef HAVE_LUTIMES
12907 "HAVE_LUTIMES",
12908#endif
12909
12910#ifdef HAVE_MKDIRAT
12911 "HAVE_MKDIRAT",
12912#endif
12913
12914#ifdef HAVE_MKFIFOAT
12915 "HAVE_MKFIFOAT",
12916#endif
12917
12918#ifdef HAVE_MKNODAT
12919 "HAVE_MKNODAT",
12920#endif
12921
12922#ifdef HAVE_OPENAT
12923 "HAVE_OPENAT",
12924#endif
12925
12926#ifdef HAVE_READLINKAT
12927 "HAVE_READLINKAT",
12928#endif
12929
12930#ifdef HAVE_RENAMEAT
12931 "HAVE_RENAMEAT",
12932#endif
12933
12934#ifdef HAVE_SYMLINKAT
12935 "HAVE_SYMLINKAT",
12936#endif
12937
12938#ifdef HAVE_UNLINKAT
12939 "HAVE_UNLINKAT",
12940#endif
12941
12942#ifdef HAVE_UTIMENSAT
12943 "HAVE_UTIMENSAT",
12944#endif
12945
12946#ifdef MS_WINDOWS
12947 "MS_WINDOWS",
12948#endif
12949
12950 NULL
12951};
12952
12953
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012954PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012955INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012956{
Victor Stinner8c62be82010-05-06 00:08:46 +000012957 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012958 PyObject *list;
Serhiy Storchaka2d06e842015-12-25 19:53:18 +020012959 const char * const *trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012960
Brian Curtin52173d42010-12-02 18:29:18 +000012961#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012962 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012963#endif
12964
Victor Stinner8c62be82010-05-06 00:08:46 +000012965 m = PyModule_Create(&posixmodule);
12966 if (m == NULL)
12967 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012968
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 /* Initialize environ dictionary */
12970 v = convertenviron();
12971 Py_XINCREF(v);
12972 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12973 return NULL;
12974 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012975
Victor Stinner8c62be82010-05-06 00:08:46 +000012976 if (all_ins(m))
12977 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012978
Victor Stinner8c62be82010-05-06 00:08:46 +000012979 if (setup_confname_tables(m))
12980 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012981
Victor Stinner8c62be82010-05-06 00:08:46 +000012982 Py_INCREF(PyExc_OSError);
12983 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012984
Guido van Rossumb3d39562000-01-31 18:41:26 +000012985#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012986 if (posix_putenv_garbage == NULL)
12987 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012988#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012989
Victor Stinner8c62be82010-05-06 00:08:46 +000012990 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012991#if defined(HAVE_WAITID) && !defined(__APPLE__)
12992 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012993 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12994 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012995#endif
12996
Christian Heimes25827622013-10-12 01:27:08 +020012997 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012998 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12999 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
13000 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020013001 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
13002 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013003 structseq_new = StatResultType.tp_new;
13004 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013005
Christian Heimes25827622013-10-12 01:27:08 +020013006 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013007 if (PyStructSequence_InitType2(&StatVFSResultType,
13008 &statvfs_result_desc) < 0)
13009 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013010#ifdef NEED_TICKS_PER_SECOND
13011# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000013012 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013013# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000013014 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013015# else
Victor Stinner8c62be82010-05-06 00:08:46 +000013016 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000013017# endif
13018#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013019
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050013020#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013021 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013022 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
13023 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100013024 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013025#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013026
13027 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020013028 if (PyStructSequence_InitType2(&TerminalSizeType,
13029 &TerminalSize_desc) < 0)
13030 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013031
13032 /* initialize scandir types */
13033 if (PyType_Ready(&ScandirIteratorType) < 0)
13034 return NULL;
13035 if (PyType_Ready(&DirEntryType) < 0)
13036 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013037 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013038#if defined(HAVE_WAITID) && !defined(__APPLE__)
13039 Py_INCREF((PyObject*) &WaitidResultType);
13040 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13041#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013042 Py_INCREF((PyObject*) &StatResultType);
13043 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13044 Py_INCREF((PyObject*) &StatVFSResultType);
13045 PyModule_AddObject(m, "statvfs_result",
13046 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013047
13048#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013049 Py_INCREF(&SchedParamType);
13050 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013051#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013052
Larry Hastings605a62d2012-06-24 04:33:36 -070013053 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013054 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13055 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013056 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13057
13058 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013059 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13060 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013061 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13062
Thomas Wouters477c8d52006-05-27 19:21:47 +000013063#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013064 /*
13065 * Step 2 of weak-linking support on Mac OS X.
13066 *
13067 * The code below removes functions that are not available on the
13068 * currently active platform.
13069 *
13070 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013071 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013072 * OSX 10.4.
13073 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013074#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013075 if (fstatvfs == NULL) {
13076 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13077 return NULL;
13078 }
13079 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013080#endif /* HAVE_FSTATVFS */
13081
13082#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013083 if (statvfs == NULL) {
13084 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13085 return NULL;
13086 }
13087 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013088#endif /* HAVE_STATVFS */
13089
13090# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013091 if (lchown == NULL) {
13092 if (PyObject_DelAttrString(m, "lchown") == -1) {
13093 return NULL;
13094 }
13095 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013096#endif /* HAVE_LCHOWN */
13097
13098
13099#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013100
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013101 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013102 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13103
Larry Hastings6fe20b32012-04-19 15:07:49 -070013104 billion = PyLong_FromLong(1000000000);
13105 if (!billion)
13106 return NULL;
13107
Larry Hastings9cf065c2012-06-22 16:30:09 -070013108 /* suppress "function not used" warnings */
13109 {
13110 int ignored;
13111 fd_specified("", -1);
13112 follow_symlinks_specified("", 1);
13113 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13114 dir_fd_converter(Py_None, &ignored);
13115 dir_fd_unavailable(Py_None, &ignored);
13116 }
13117
13118 /*
13119 * provide list of locally available functions
13120 * so os.py can populate support_* lists
13121 */
13122 list = PyList_New(0);
13123 if (!list)
13124 return NULL;
13125 for (trace = have_functions; *trace; trace++) {
13126 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13127 if (!unicode)
13128 return NULL;
13129 if (PyList_Append(list, unicode))
13130 return NULL;
13131 Py_DECREF(unicode);
13132 }
13133 PyModule_AddObject(m, "_have_functions", list);
13134
13135 initialized = 1;
13136
Victor Stinner8c62be82010-05-06 00:08:46 +000013137 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013138}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013139
13140#ifdef __cplusplus
13141}
13142#endif