blob: 23c006844e17bb2e7530d9504648f7beb3984e0d [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 }
869
870 path->wide = wide;
871 path->narrow = NULL;
872 path->length = length;
873 path->object = o;
874 path->fd = -1;
875 path->cleanup = unicode;
876 return Py_CLEANUP_SUPPORTED;
877#else
878 int converted = PyUnicode_FSConverter(unicode, &bytes);
879 Py_DECREF(unicode);
880 if (!converted)
881 bytes = NULL;
882#endif
883 }
884 else {
885 PyErr_Clear();
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200886 if (PyObject_CheckBuffer(o))
887 bytes = PyBytes_FromObject(o);
888 else
889 bytes = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700890 if (!bytes) {
891 PyErr_Clear();
892 if (path->allow_fd) {
893 int fd;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200894 int result = _fd_converter(o, &fd,
895 "string, bytes or integer");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700896 if (result) {
897 path->wide = NULL;
898 path->narrow = NULL;
899 path->length = 0;
900 path->object = o;
901 path->fd = fd;
902 return result;
903 }
904 }
905 }
906 }
907
908 if (!bytes) {
909 if (!PyErr_Occurred())
910 FORMAT_EXCEPTION(PyExc_TypeError, "illegal type for %s parameter");
911 return 0;
912 }
913
914#ifdef MS_WINDOWS
915 if (win32_warn_bytes_api()) {
916 Py_DECREF(bytes);
917 return 0;
918 }
919#endif
920
921 length = PyBytes_GET_SIZE(bytes);
922#ifdef MS_WINDOWS
Victor Stinner75875072013-11-24 19:23:25 +0100923 if (length > MAX_PATH-1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -0700924 FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
925 Py_DECREF(bytes);
926 return 0;
927 }
928#endif
929
930 narrow = PyBytes_AS_STRING(bytes);
Victor Stinner706768c2014-08-16 01:03:39 +0200931 if ((size_t)length != strlen(narrow)) {
Serhiy Storchakad8a14472014-09-06 20:07:17 +0300932 FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
Larry Hastings9cf065c2012-06-22 16:30:09 -0700933 Py_DECREF(bytes);
934 return 0;
935 }
936
937 path->wide = NULL;
938 path->narrow = narrow;
939 path->length = length;
940 path->object = o;
941 path->fd = -1;
942 path->cleanup = bytes;
943 return Py_CLEANUP_SUPPORTED;
944}
945
946static void
947argument_unavailable_error(char *function_name, char *argument_name) {
948 PyErr_Format(PyExc_NotImplementedError,
949 "%s%s%s unavailable on this platform",
950 (function_name != NULL) ? function_name : "",
951 (function_name != NULL) ? ": ": "",
952 argument_name);
953}
954
955static int
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200956dir_fd_unavailable(PyObject *o, void *p)
957{
958 int dir_fd;
959 if (!dir_fd_converter(o, &dir_fd))
Larry Hastings9cf065c2012-06-22 16:30:09 -0700960 return 0;
Serhiy Storchakaa2ad5c32013-01-07 23:13:46 +0200961 if (dir_fd != DEFAULT_DIR_FD) {
962 argument_unavailable_error(NULL, "dir_fd");
963 return 0;
964 }
965 *(int *)p = dir_fd;
966 return 1;
Larry Hastings9cf065c2012-06-22 16:30:09 -0700967}
968
969static int
970fd_specified(char *function_name, int fd) {
971 if (fd == -1)
972 return 0;
973
974 argument_unavailable_error(function_name, "fd");
975 return 1;
976}
977
978static int
979follow_symlinks_specified(char *function_name, int follow_symlinks) {
980 if (follow_symlinks)
981 return 0;
982
983 argument_unavailable_error(function_name, "follow_symlinks");
984 return 1;
985}
986
987static int
988path_and_dir_fd_invalid(char *function_name, path_t *path, int dir_fd) {
989 if (!path->narrow && !path->wide && (dir_fd != DEFAULT_DIR_FD)) {
990 PyErr_Format(PyExc_ValueError,
991 "%s: can't specify dir_fd without matching path",
992 function_name);
993 return 1;
994 }
995 return 0;
996}
997
998static int
999dir_fd_and_fd_invalid(char *function_name, int dir_fd, int fd) {
1000 if ((dir_fd != DEFAULT_DIR_FD) && (fd != -1)) {
1001 PyErr_Format(PyExc_ValueError,
1002 "%s: can't specify both dir_fd and fd",
1003 function_name);
1004 return 1;
1005 }
1006 return 0;
1007}
1008
1009static int
1010fd_and_follow_symlinks_invalid(char *function_name, int fd,
1011 int follow_symlinks) {
1012 if ((fd > 0) && (!follow_symlinks)) {
1013 PyErr_Format(PyExc_ValueError,
1014 "%s: cannot use fd and follow_symlinks together",
1015 function_name);
1016 return 1;
1017 }
1018 return 0;
1019}
1020
1021static int
1022dir_fd_and_follow_symlinks_invalid(char *function_name, int dir_fd,
1023 int follow_symlinks) {
1024 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
1025 PyErr_Format(PyExc_ValueError,
1026 "%s: cannot use dir_fd and follow_symlinks together",
1027 function_name);
1028 return 1;
1029 }
1030 return 0;
1031}
1032
Larry Hastings2f936352014-08-05 14:04:04 +10001033#ifdef MS_WINDOWS
1034 typedef PY_LONG_LONG Py_off_t;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001035#else
Larry Hastings2f936352014-08-05 14:04:04 +10001036 typedef off_t Py_off_t;
1037#endif
1038
1039static int
1040Py_off_t_converter(PyObject *arg, void *addr)
1041{
1042#ifdef HAVE_LARGEFILE_SUPPORT
1043 *((Py_off_t *)addr) = PyLong_AsLongLong(arg);
1044#else
1045 *((Py_off_t *)addr) = PyLong_AsLong(arg);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001046#endif
1047 if (PyErr_Occurred())
1048 return 0;
1049 return 1;
1050}
Larry Hastings2f936352014-08-05 14:04:04 +10001051
1052static PyObject *
1053PyLong_FromPy_off_t(Py_off_t offset)
1054{
1055#ifdef HAVE_LARGEFILE_SUPPORT
1056 return PyLong_FromLongLong(offset);
1057#else
1058 return PyLong_FromLong(offset);
Ross Lagerwallb1e5d592011-09-19 08:30:43 +02001059#endif
Larry Hastings2f936352014-08-05 14:04:04 +10001060}
1061
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001062
Steve Dowerd81431f2015-03-06 14:47:02 -08001063#if defined _MSC_VER && _MSC_VER >= 1400 && _MSC_VER < 1900
1064/* Legacy implementation of _PyVerify_fd_dup2 while transitioning to
1065 * MSVC 14.0. This should eventually be removed. (issue23524)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001066 */
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001067#define IOINFO_L2E 5
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001068#define IOINFO_ARRAYS 64
Steve Dower65e4cb12014-11-22 12:54:57 -08001069#define IOINFO_ARRAY_ELTS (1 << IOINFO_L2E)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001070#define _NHANDLE_ (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001071#define _NO_CONSOLE_FILENO (intptr_t)-2
1072
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001073/* the special case of checking dup2. The target fd must be in a sensible range */
1074static int
1075_PyVerify_fd_dup2(int fd1, int fd2)
1076{
Victor Stinner8c62be82010-05-06 00:08:46 +00001077 if (!_PyVerify_fd(fd1))
1078 return 0;
1079 if (fd2 == _NO_CONSOLE_FILENO)
1080 return 0;
1081 if ((unsigned)fd2 < _NHANDLE_)
1082 return 1;
1083 else
1084 return 0;
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001085}
1086#else
Steve Dowerd81431f2015-03-06 14:47:02 -08001087#define _PyVerify_fd_dup2(fd1, fd2) (_PyVerify_fd(fd1) && (fd2) >= 0)
Amaury Forgeot d'Arc2fc224f2009-02-19 23:23:47 +00001088#endif
1089
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001090#ifdef MS_WINDOWS
Brian Curtinf5e76d02010-11-24 13:14:05 +00001091
1092static int
Brian Curtind25aef52011-06-13 15:16:04 -05001093win32_get_reparse_tag(HANDLE reparse_point_handle, ULONG *reparse_tag)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001094{
1095 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
1096 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
1097 DWORD n_bytes_returned;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001098
1099 if (0 == DeviceIoControl(
1100 reparse_point_handle,
1101 FSCTL_GET_REPARSE_POINT,
1102 NULL, 0, /* in buffer */
1103 target_buffer, sizeof(target_buffer),
1104 &n_bytes_returned,
1105 NULL)) /* we're not using OVERLAPPED_IO */
Brian Curtind25aef52011-06-13 15:16:04 -05001106 return FALSE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001107
1108 if (reparse_tag)
1109 *reparse_tag = rdb->ReparseTag;
1110
Brian Curtind25aef52011-06-13 15:16:04 -05001111 return TRUE;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001112}
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01001113
Brian Curtinfc1be6d2010-11-24 13:23:18 +00001114#endif /* MS_WINDOWS */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001115
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001116/* Return a dictionary corresponding to the POSIX environment table */
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001117#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Jack Jansenea0c3822002-08-01 21:57:49 +00001118/* On Darwin/MacOSX a shared library or framework has no access to
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001119** environ directly, we must obtain it with _NSGetEnviron(). See also
1120** man environ(7).
Jack Jansenea0c3822002-08-01 21:57:49 +00001121*/
1122#include <crt_externs.h>
1123static char **environ;
1124#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001125extern char **environ;
Guido van Rossuma4916fa1996-05-23 22:58:55 +00001126#endif /* !_MSC_VER */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001127
Barry Warsaw53699e91996-12-10 23:23:01 +00001128static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001129convertenviron(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001130{
Victor Stinner8c62be82010-05-06 00:08:46 +00001131 PyObject *d;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001132#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00001133 wchar_t **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001134#else
Victor Stinner8c62be82010-05-06 00:08:46 +00001135 char **e;
Thomas Hellerf78f12a2007-11-08 19:33:05 +00001136#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +00001137
Victor Stinner8c62be82010-05-06 00:08:46 +00001138 d = PyDict_New();
1139 if (d == NULL)
1140 return NULL;
Ronald Oussoren697e56d2013-01-25 17:57:13 +01001141#if defined(WITH_NEXT_FRAMEWORK) || (defined(__APPLE__) && defined(Py_ENABLE_SHARED))
Victor Stinner8c62be82010-05-06 00:08:46 +00001142 if (environ == NULL)
1143 environ = *_NSGetEnviron();
1144#endif
1145#ifdef MS_WINDOWS
1146 /* _wenviron must be initialized in this way if the program is started
1147 through main() instead of wmain(). */
1148 _wgetenv(L"");
1149 if (_wenviron == NULL)
1150 return d;
1151 /* This part ignores errors */
1152 for (e = _wenviron; *e != NULL; e++) {
1153 PyObject *k;
1154 PyObject *v;
1155 wchar_t *p = wcschr(*e, L'=');
1156 if (p == NULL)
1157 continue;
1158 k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
1159 if (k == NULL) {
1160 PyErr_Clear();
1161 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001162 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001163 v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
1164 if (v == NULL) {
1165 PyErr_Clear();
1166 Py_DECREF(k);
1167 continue;
Guido van Rossumd48f2521997-12-05 22:19:34 +00001168 }
Victor Stinner8c62be82010-05-06 00:08:46 +00001169 if (PyDict_GetItem(d, k) == NULL) {
1170 if (PyDict_SetItem(d, k, v) != 0)
1171 PyErr_Clear();
1172 }
1173 Py_DECREF(k);
1174 Py_DECREF(v);
1175 }
1176#else
1177 if (environ == NULL)
1178 return d;
1179 /* This part ignores errors */
1180 for (e = environ; *e != NULL; e++) {
1181 PyObject *k;
1182 PyObject *v;
1183 char *p = strchr(*e, '=');
1184 if (p == NULL)
1185 continue;
Victor Stinner84ae1182010-05-06 22:05:07 +00001186 k = PyBytes_FromStringAndSize(*e, (int)(p-*e));
Victor Stinner8c62be82010-05-06 00:08:46 +00001187 if (k == NULL) {
1188 PyErr_Clear();
1189 continue;
1190 }
Victor Stinner84ae1182010-05-06 22:05:07 +00001191 v = PyBytes_FromStringAndSize(p+1, strlen(p+1));
Victor Stinner8c62be82010-05-06 00:08:46 +00001192 if (v == NULL) {
1193 PyErr_Clear();
1194 Py_DECREF(k);
1195 continue;
1196 }
1197 if (PyDict_GetItem(d, k) == NULL) {
1198 if (PyDict_SetItem(d, k, v) != 0)
1199 PyErr_Clear();
1200 }
1201 Py_DECREF(k);
1202 Py_DECREF(v);
Guido van Rossumd48f2521997-12-05 22:19:34 +00001203 }
1204#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001205 return d;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001206}
1207
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001208/* Set a POSIX-specific error from errno, and return NULL */
1209
Barry Warsawd58d7641998-07-23 16:14:40 +00001210static PyObject *
Thomas Woutersf3f33dc2000-07-21 06:00:07 +00001211posix_error(void)
Guido van Rossumad0ee831995-03-01 10:34:45 +00001212{
Victor Stinner8c62be82010-05-06 00:08:46 +00001213 return PyErr_SetFromErrno(PyExc_OSError);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001214}
Mark Hammondef8b6542001-05-13 08:04:26 +00001215
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00001216#ifdef MS_WINDOWS
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001217static PyObject *
Brian Curtind40e6f72010-07-08 21:39:08 +00001218win32_error(char* function, const char* filename)
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001219{
Victor Stinner8c62be82010-05-06 00:08:46 +00001220 /* XXX We should pass the function name along in the future.
1221 (winreg.c also wants to pass the function name.)
1222 This would however require an additional param to the
1223 Windows error object, which is non-trivial.
1224 */
1225 errno = GetLastError();
1226 if (filename)
1227 return PyErr_SetFromWindowsErrWithFilename(errno, filename);
1228 else
1229 return PyErr_SetFromWindowsErr(errno);
Fredrik Lundhffb9c772000-07-09 14:49:51 +00001230}
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001231
Mark Hammondc2e85bd2002-10-03 05:10:39 +00001232static PyObject *
Victor Stinnereb5657a2011-09-30 01:44:27 +02001233win32_error_object(char* function, PyObject* filename)
1234{
1235 /* XXX - see win32_error for comments on 'function' */
1236 errno = GetLastError();
1237 if (filename)
1238 return PyErr_SetExcFromWindowsErrWithFilenameObject(
Andrew Svetlov2606a6f2012-12-19 14:33:35 +02001239 PyExc_OSError,
Victor Stinnereb5657a2011-09-30 01:44:27 +02001240 errno,
1241 filename);
1242 else
1243 return PyErr_SetFromWindowsErr(errno);
1244}
1245
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001246#endif /* MS_WINDOWS */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001247
Larry Hastings9cf065c2012-06-22 16:30:09 -07001248static PyObject *
Victor Stinner292c8352012-10-30 02:17:38 +01001249path_error(path_t *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07001250{
1251#ifdef MS_WINDOWS
Victor Stinner292c8352012-10-30 02:17:38 +01001252 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
1253 0, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001254#else
Victor Stinner292c8352012-10-30 02:17:38 +01001255 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings9cf065c2012-06-22 16:30:09 -07001256#endif
1257}
1258
Larry Hastings31826802013-10-19 00:09:25 -07001259
Larry Hastingsb0827312014-02-09 22:05:19 -08001260static PyObject *
1261path_error2(path_t *path, path_t *path2)
1262{
1263#ifdef MS_WINDOWS
1264 return PyErr_SetExcFromWindowsErrWithFilenameObjects(PyExc_OSError,
1265 0, path->object, path2->object);
1266#else
1267 return PyErr_SetFromErrnoWithFilenameObjects(PyExc_OSError,
1268 path->object, path2->object);
1269#endif
1270}
1271
1272
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001273/* POSIX generic methods */
1274
Larry Hastings2f936352014-08-05 14:04:04 +10001275static int
1276fildes_converter(PyObject *o, void *p)
Fred Drake4d1e64b2002-04-15 19:40:07 +00001277{
Victor Stinner8c62be82010-05-06 00:08:46 +00001278 int fd;
Larry Hastings2f936352014-08-05 14:04:04 +10001279 int *pointer = (int *)p;
1280 fd = PyObject_AsFileDescriptor(o);
Victor Stinner8c62be82010-05-06 00:08:46 +00001281 if (fd < 0)
Larry Hastings2f936352014-08-05 14:04:04 +10001282 return 0;
Larry Hastings2f936352014-08-05 14:04:04 +10001283 *pointer = fd;
1284 return 1;
1285}
1286
1287static PyObject *
1288posix_fildes_fd(int fd, int (*func)(int))
1289{
1290 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001291 int async_err = 0;
1292
Steve Dower8fc89802015-04-12 00:26:27 -04001293 if (!_PyVerify_fd(fd))
1294 return posix_error();
1295
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001296 do {
1297 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04001298 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001299 res = (*func)(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04001300 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00001301 Py_END_ALLOW_THREADS
1302 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
1303 if (res != 0)
1304 return (!async_err) ? posix_error() : NULL;
1305 Py_RETURN_NONE;
Fred Drake4d1e64b2002-04-15 19:40:07 +00001306}
Guido van Rossum21142a01999-01-08 21:05:37 +00001307
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00001308
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00001309#ifdef MS_WINDOWS
Thomas Wouters477c8d52006-05-27 19:21:47 +00001310/* This is a reimplementation of the C library's chdir function,
1311 but one that produces Win32 errors instead of DOS error codes.
1312 chdir is essentially a wrapper around SetCurrentDirectory; however,
1313 it also needs to set "magic" environment variables indicating
1314 the per-drive current directory, which are of the form =<drive>: */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001315static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001316win32_chdir(LPCSTR path)
1317{
Victor Stinner75875072013-11-24 19:23:25 +01001318 char new_path[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00001319 int result;
1320 char env[4] = "=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001321
Victor Stinner8c62be82010-05-06 00:08:46 +00001322 if(!SetCurrentDirectoryA(path))
1323 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001324 result = GetCurrentDirectoryA(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001325 if (!result)
1326 return FALSE;
1327 /* In the ANSI API, there should not be any paths longer
Victor Stinner75875072013-11-24 19:23:25 +01001328 than MAX_PATH-1 (not including the final null character). */
1329 assert(result < Py_ARRAY_LENGTH(new_path));
Victor Stinner8c62be82010-05-06 00:08:46 +00001330 if (strncmp(new_path, "\\\\", 2) == 0 ||
1331 strncmp(new_path, "//", 2) == 0)
1332 /* UNC path, nothing to do. */
1333 return TRUE;
1334 env[1] = new_path[0];
1335 return SetEnvironmentVariableA(env, new_path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00001336}
1337
1338/* The Unicode version differs from the ANSI version
1339 since the current directory might exceed MAX_PATH characters */
Benjamin Peterson206e3072008-10-19 14:07:49 +00001340static BOOL __stdcall
Thomas Wouters477c8d52006-05-27 19:21:47 +00001341win32_wchdir(LPCWSTR path)
1342{
Victor Stinner75875072013-11-24 19:23:25 +01001343 wchar_t _new_path[MAX_PATH], *new_path = _new_path;
Victor Stinner8c62be82010-05-06 00:08:46 +00001344 int result;
1345 wchar_t env[4] = L"=x:";
Thomas Wouters477c8d52006-05-27 19:21:47 +00001346
Victor Stinner8c62be82010-05-06 00:08:46 +00001347 if(!SetCurrentDirectoryW(path))
1348 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001349 result = GetCurrentDirectoryW(Py_ARRAY_LENGTH(new_path), new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001350 if (!result)
1351 return FALSE;
Victor Stinner75875072013-11-24 19:23:25 +01001352 if (result > Py_ARRAY_LENGTH(new_path)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001353 new_path = PyMem_RawMalloc(result * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00001354 if (!new_path) {
1355 SetLastError(ERROR_OUTOFMEMORY);
1356 return FALSE;
1357 }
1358 result = GetCurrentDirectoryW(result, new_path);
1359 if (!result) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001360 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001361 return FALSE;
1362 }
1363 }
1364 if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
1365 wcsncmp(new_path, L"//", 2) == 0)
1366 /* UNC path, nothing to do. */
1367 return TRUE;
1368 env[1] = new_path[0];
1369 result = SetEnvironmentVariableW(env, new_path);
1370 if (new_path != _new_path)
Victor Stinnerb6404912013-07-07 16:21:41 +02001371 PyMem_RawFree(new_path);
Victor Stinner8c62be82010-05-06 00:08:46 +00001372 return result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00001373}
1374#endif
1375
Martin v. Löwis14694662006-02-03 12:54:16 +00001376#ifdef MS_WINDOWS
1377/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
1378 - time stamps are restricted to second resolution
1379 - file modification times suffer from forth-and-back conversions between
1380 UTC and local time
1381 Therefore, we implement our own stat, based on the Win32 API directly.
1382*/
Victor Stinner8c62be82010-05-06 00:08:46 +00001383#define HAVE_STAT_NSEC 1
Zachary Ware63f277b2014-06-19 09:46:37 -05001384#define HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES 1
Martin v. Löwis14694662006-02-03 12:54:16 +00001385
Guido van Rossumd8faa362007-04-27 19:54:29 +00001386static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001387attributes_from_dir(LPCSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001388{
Victor Stinner8c62be82010-05-06 00:08:46 +00001389 HANDLE hFindFile;
1390 WIN32_FIND_DATAA FileData;
1391 hFindFile = FindFirstFileA(pszFile, &FileData);
1392 if (hFindFile == INVALID_HANDLE_VALUE)
1393 return FALSE;
1394 FindClose(hFindFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001395 memset(info, 0, sizeof(*info));
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001396 *reparse_tag = 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001397 info->dwFileAttributes = FileData.dwFileAttributes;
1398 info->ftCreationTime = FileData.ftCreationTime;
1399 info->ftLastAccessTime = FileData.ftLastAccessTime;
1400 info->ftLastWriteTime = FileData.ftLastWriteTime;
1401 info->nFileSizeHigh = FileData.nFileSizeHigh;
1402 info->nFileSizeLow = FileData.nFileSizeLow;
1403/* info->nNumberOfLinks = 1; */
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001404 if (FileData.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1405 *reparse_tag = FileData.dwReserved0;
Victor Stinner8c62be82010-05-06 00:08:46 +00001406 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001407}
1408
Victor Stinner6036e442015-03-08 01:58:04 +01001409static void
1410find_data_to_file_info_w(WIN32_FIND_DATAW *pFileData,
1411 BY_HANDLE_FILE_INFORMATION *info,
1412 ULONG *reparse_tag)
1413{
1414 memset(info, 0, sizeof(*info));
1415 info->dwFileAttributes = pFileData->dwFileAttributes;
1416 info->ftCreationTime = pFileData->ftCreationTime;
1417 info->ftLastAccessTime = pFileData->ftLastAccessTime;
1418 info->ftLastWriteTime = pFileData->ftLastWriteTime;
1419 info->nFileSizeHigh = pFileData->nFileSizeHigh;
1420 info->nFileSizeLow = pFileData->nFileSizeLow;
1421/* info->nNumberOfLinks = 1; */
1422 if (pFileData->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
1423 *reparse_tag = pFileData->dwReserved0;
1424 else
1425 *reparse_tag = 0;
1426}
1427
Guido van Rossumd8faa362007-04-27 19:54:29 +00001428static BOOL
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001429attributes_from_dir_w(LPCWSTR pszFile, BY_HANDLE_FILE_INFORMATION *info, ULONG *reparse_tag)
Guido van Rossumd8faa362007-04-27 19:54:29 +00001430{
Victor Stinner8c62be82010-05-06 00:08:46 +00001431 HANDLE hFindFile;
1432 WIN32_FIND_DATAW FileData;
1433 hFindFile = FindFirstFileW(pszFile, &FileData);
1434 if (hFindFile == INVALID_HANDLE_VALUE)
1435 return FALSE;
1436 FindClose(hFindFile);
Victor Stinner6036e442015-03-08 01:58:04 +01001437 find_data_to_file_info_w(&FileData, info, reparse_tag);
Victor Stinner8c62be82010-05-06 00:08:46 +00001438 return TRUE;
Guido van Rossumd8faa362007-04-27 19:54:29 +00001439}
1440
Brian Curtind25aef52011-06-13 15:16:04 -05001441static BOOL
1442get_target_path(HANDLE hdl, wchar_t **target_path)
1443{
1444 int buf_size, result_length;
1445 wchar_t *buf;
1446
1447 /* We have a good handle to the target, use it to determine
1448 the target path name (then we'll call lstat on it). */
Steve Dower2ea51c92015-03-20 21:49:12 -07001449 buf_size = GetFinalPathNameByHandleW(hdl, 0, 0,
1450 VOLUME_NAME_DOS);
Brian Curtind25aef52011-06-13 15:16:04 -05001451 if(!buf_size)
1452 return FALSE;
1453
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02001454 buf = PyMem_New(wchar_t, buf_size+1);
Brian Curtinc8be8402011-06-14 09:52:50 -05001455 if (!buf) {
1456 SetLastError(ERROR_OUTOFMEMORY);
1457 return FALSE;
1458 }
1459
Steve Dower2ea51c92015-03-20 21:49:12 -07001460 result_length = GetFinalPathNameByHandleW(hdl,
Brian Curtind25aef52011-06-13 15:16:04 -05001461 buf, buf_size, VOLUME_NAME_DOS);
1462
1463 if(!result_length) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001464 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001465 return FALSE;
1466 }
1467
1468 if(!CloseHandle(hdl)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02001469 PyMem_Free(buf);
Brian Curtind25aef52011-06-13 15:16:04 -05001470 return FALSE;
1471 }
1472
1473 buf[result_length] = 0;
1474
1475 *target_path = buf;
1476 return TRUE;
1477}
1478
1479static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001480win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001481 BOOL traverse);
1482static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001483win32_xstat_impl(const char *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001484 BOOL traverse)
1485{
Victor Stinner26de69d2011-06-17 15:15:38 +02001486 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001487 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001488 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001489 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001490 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001491 const char *dot;
1492
1493 hFile = CreateFileA(
1494 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001495 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001496 0, /* share mode */
1497 NULL, /* security attributes */
1498 OPEN_EXISTING,
1499 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001500 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1501 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001502 the symlink path again and not the actual final path. */
Brian Curtind25aef52011-06-13 15:16:04 -05001503 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
1504 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001505 NULL);
1506
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001507 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001508 /* Either the target doesn't exist, or we don't have access to
1509 get a handle to it. If the former, we need to return an error.
1510 If the latter, we can use attributes_from_dir. */
1511 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001512 return -1;
1513 /* Could not get attributes on open file. Fall back to
1514 reading the directory. */
1515 if (!attributes_from_dir(path, &info, &reparse_tag))
1516 /* Very strange. This should not fail now */
1517 return -1;
1518 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1519 if (traverse) {
1520 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001521 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001522 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001523 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001524 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001525 } else {
1526 if (!GetFileInformationByHandle(hFile, &info)) {
1527 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001528 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001529 }
1530 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001531 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1532 return -1;
1533
1534 /* Close the outer open file handle now that we're about to
1535 reopen it with different flags. */
1536 if (!CloseHandle(hFile))
1537 return -1;
1538
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001539 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001540 /* In order to call GetFinalPathNameByHandle we need to open
1541 the file without the reparse handling flag set. */
1542 hFile2 = CreateFileA(
1543 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1544 NULL, OPEN_EXISTING,
1545 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1546 NULL);
1547 if (hFile2 == INVALID_HANDLE_VALUE)
1548 return -1;
1549
1550 if (!get_target_path(hFile2, &target_path))
1551 return -1;
1552
1553 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001554 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001555 return code;
1556 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001557 } else
1558 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001559 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001560 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001561
1562 /* Set S_IEXEC if it is an .exe, .bat, ... */
1563 dot = strrchr(path, '.');
1564 if (dot) {
1565 if (stricmp(dot, ".bat") == 0 || stricmp(dot, ".cmd") == 0 ||
1566 stricmp(dot, ".exe") == 0 || stricmp(dot, ".com") == 0)
1567 result->st_mode |= 0111;
1568 }
1569 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001570}
1571
1572static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001573win32_xstat_impl_w(const wchar_t *path, struct _Py_stat_struct *result,
Brian Curtind25aef52011-06-13 15:16:04 -05001574 BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001575{
1576 int code;
Brian Curtind25aef52011-06-13 15:16:04 -05001577 HANDLE hFile, hFile2;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001578 BY_HANDLE_FILE_INFORMATION info;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001579 ULONG reparse_tag = 0;
Victor Stinner26de69d2011-06-17 15:15:38 +02001580 wchar_t *target_path;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001581 const wchar_t *dot;
1582
1583 hFile = CreateFileW(
1584 path,
Brian Curtind25aef52011-06-13 15:16:04 -05001585 FILE_READ_ATTRIBUTES, /* desired access */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001586 0, /* share mode */
1587 NULL, /* security attributes */
1588 OPEN_EXISTING,
1589 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
Brian Curtind25aef52011-06-13 15:16:04 -05001590 /* FILE_FLAG_OPEN_REPARSE_POINT does not follow the symlink.
1591 Because of this, calls like GetFinalPathNameByHandle will return
R David Murrayfc069992013-12-13 20:52:19 -05001592 the symlink path again and not the actual final path. */
Victor Stinner26de69d2011-06-17 15:15:38 +02001593 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS|
Brian Curtind25aef52011-06-13 15:16:04 -05001594 FILE_FLAG_OPEN_REPARSE_POINT,
Brian Curtinf5e76d02010-11-24 13:14:05 +00001595 NULL);
1596
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001597 if (hFile == INVALID_HANDLE_VALUE) {
Brian Curtinf5e76d02010-11-24 13:14:05 +00001598 /* Either the target doesn't exist, or we don't have access to
1599 get a handle to it. If the former, we need to return an error.
1600 If the latter, we can use attributes_from_dir. */
1601 if (GetLastError() != ERROR_SHARING_VIOLATION)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001602 return -1;
1603 /* Could not get attributes on open file. Fall back to
1604 reading the directory. */
1605 if (!attributes_from_dir_w(path, &info, &reparse_tag))
1606 /* Very strange. This should not fail now */
1607 return -1;
1608 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
1609 if (traverse) {
1610 /* Should traverse, but could not open reparse point handle */
Brian Curtinf5e76d02010-11-24 13:14:05 +00001611 SetLastError(ERROR_SHARING_VIOLATION);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001612 return -1;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001613 }
Brian Curtinf5e76d02010-11-24 13:14:05 +00001614 }
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001615 } else {
1616 if (!GetFileInformationByHandle(hFile, &info)) {
1617 CloseHandle(hFile);
Brian Curtind25aef52011-06-13 15:16:04 -05001618 return -1;
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001619 }
1620 if (info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
Brian Curtind25aef52011-06-13 15:16:04 -05001621 if (!win32_get_reparse_tag(hFile, &reparse_tag))
1622 return -1;
1623
1624 /* Close the outer open file handle now that we're about to
1625 reopen it with different flags. */
1626 if (!CloseHandle(hFile))
1627 return -1;
1628
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001629 if (traverse) {
Brian Curtind25aef52011-06-13 15:16:04 -05001630 /* In order to call GetFinalPathNameByHandle we need to open
1631 the file without the reparse handling flag set. */
1632 hFile2 = CreateFileW(
1633 path, FILE_READ_ATTRIBUTES, FILE_SHARE_READ,
1634 NULL, OPEN_EXISTING,
1635 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_BACKUP_SEMANTICS,
1636 NULL);
1637 if (hFile2 == INVALID_HANDLE_VALUE)
1638 return -1;
1639
1640 if (!get_target_path(hFile2, &target_path))
1641 return -1;
1642
1643 code = win32_xstat_impl_w(target_path, result, FALSE);
Victor Stinnerb6404912013-07-07 16:21:41 +02001644 PyMem_Free(target_path);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001645 return code;
1646 }
Hirokazu Yamamoto7ed117a2010-12-07 10:24:37 +00001647 } else
1648 CloseHandle(hFile);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001649 }
Steve Dowera2af1a52015-02-21 10:04:10 -08001650 _Py_attribute_data_to_stat(&info, reparse_tag, result);
Brian Curtinf5e76d02010-11-24 13:14:05 +00001651
1652 /* Set S_IEXEC if it is an .exe, .bat, ... */
1653 dot = wcsrchr(path, '.');
1654 if (dot) {
1655 if (_wcsicmp(dot, L".bat") == 0 || _wcsicmp(dot, L".cmd") == 0 ||
1656 _wcsicmp(dot, L".exe") == 0 || _wcsicmp(dot, L".com") == 0)
1657 result->st_mode |= 0111;
1658 }
1659 return 0;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001660}
1661
1662static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001663win32_xstat(const char *path, struct _Py_stat_struct *result, BOOL traverse)
Brian Curtinf5e76d02010-11-24 13:14:05 +00001664{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001665 /* Protocol violation: we explicitly clear errno, instead of
1666 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001667 int code = win32_xstat_impl(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001668 errno = 0;
1669 return code;
1670}
Brian Curtinf5e76d02010-11-24 13:14:05 +00001671
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001672static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001673win32_xstat_w(const wchar_t *path, struct _Py_stat_struct *result, BOOL traverse)
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001674{
1675 /* Protocol violation: we explicitly clear errno, instead of
1676 setting it to a POSIX error. Callers should use GetLastError. */
Brian Curtind25aef52011-06-13 15:16:04 -05001677 int code = win32_xstat_impl_w(path, result, traverse);
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001678 errno = 0;
1679 return code;
Brian Curtinf5e76d02010-11-24 13:14:05 +00001680}
Brian Curtind25aef52011-06-13 15:16:04 -05001681/* About the following functions: win32_lstat_w, win32_stat, win32_stat_w
Brian Curtind40e6f72010-07-08 21:39:08 +00001682
1683 In Posix, stat automatically traverses symlinks and returns the stat
1684 structure for the target. In Windows, the equivalent GetFileAttributes by
1685 default does not traverse symlinks and instead returns attributes for
1686 the symlink.
1687
1688 Therefore, win32_lstat will get the attributes traditionally, and
1689 win32_stat will first explicitly resolve the symlink target and then will
1690 call win32_lstat on that result.
1691
Ezio Melotti4969f702011-03-15 05:59:46 +02001692 The _w represent Unicode equivalents of the aforementioned ANSI functions. */
Brian Curtind40e6f72010-07-08 21:39:08 +00001693
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001694static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001695win32_lstat(const char* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001696{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001697 return win32_xstat(path, result, FALSE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001698}
1699
Victor Stinner8c62be82010-05-06 00:08:46 +00001700static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001701win32_lstat_w(const wchar_t* path, struct _Py_stat_struct *result)
Martin v. Löwis14694662006-02-03 12:54:16 +00001702{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001703 return win32_xstat_w(path, result, FALSE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001704}
1705
1706static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001707win32_stat(const char* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001708{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001709 return win32_xstat(path, result, TRUE);
Brian Curtind40e6f72010-07-08 21:39:08 +00001710}
1711
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00001712static int
Steve Dowerf2f373f2015-02-21 08:44:05 -08001713win32_stat_w(const wchar_t* path, struct _Py_stat_struct *result)
Brian Curtind40e6f72010-07-08 21:39:08 +00001714{
Hirokazu Yamamoto427d3142010-12-04 10:16:05 +00001715 return win32_xstat_w(path, result, TRUE);
Martin v. Löwis14694662006-02-03 12:54:16 +00001716}
1717
Martin v. Löwis14694662006-02-03 12:54:16 +00001718#endif /* MS_WINDOWS */
1719
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001720PyDoc_STRVAR(stat_result__doc__,
Larry Hastings9cf065c2012-06-22 16:30:09 -07001721"stat_result: Result from stat, fstat, or lstat.\n\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001722This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001723 (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001724or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
1725\n\
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001726Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
1727or st_flags, they are available as attributes only.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001728\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001729See os.stat for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001730
1731static PyStructSequence_Field stat_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001732 {"st_mode", "protection bits"},
1733 {"st_ino", "inode"},
1734 {"st_dev", "device"},
1735 {"st_nlink", "number of hard links"},
1736 {"st_uid", "user ID of owner"},
1737 {"st_gid", "group ID of owner"},
1738 {"st_size", "total size, in bytes"},
1739 /* The NULL is replaced with PyStructSequence_UnnamedField later. */
1740 {NULL, "integer time of last access"},
1741 {NULL, "integer time of last modification"},
1742 {NULL, "integer time of last change"},
1743 {"st_atime", "time of last access"},
1744 {"st_mtime", "time of last modification"},
1745 {"st_ctime", "time of last change"},
Larry Hastings6fe20b32012-04-19 15:07:49 -07001746 {"st_atime_ns", "time of last access in nanoseconds"},
1747 {"st_mtime_ns", "time of last modification in nanoseconds"},
1748 {"st_ctime_ns", "time of last change in nanoseconds"},
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001749#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00001750 {"st_blksize", "blocksize for filesystem I/O"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001751#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001752#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00001753 {"st_blocks", "number of blocks allocated"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001754#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001755#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00001756 {"st_rdev", "device type (if inode device)"},
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001757#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001758#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00001759 {"st_flags", "user defined flags for file"},
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001760#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001761#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00001762 {"st_gen", "generation number"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001763#endif
1764#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00001765 {"st_birthtime", "time of creation"},
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001766#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05001767#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1768 {"st_file_attributes", "Windows file attribute bits"},
1769#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00001770 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001771};
1772
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001773#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Larry Hastings6fe20b32012-04-19 15:07:49 -07001774#define ST_BLKSIZE_IDX 16
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001775#else
Larry Hastings6fe20b32012-04-19 15:07:49 -07001776#define ST_BLKSIZE_IDX 15
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001777#endif
1778
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001779#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001780#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
1781#else
1782#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
1783#endif
1784
Martin v. Löwis60a5d722002-10-16 20:28:25 +00001785#ifdef HAVE_STRUCT_STAT_ST_RDEV
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001786#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
1787#else
1788#define ST_RDEV_IDX ST_BLOCKS_IDX
1789#endif
1790
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00001791#ifdef HAVE_STRUCT_STAT_ST_FLAGS
1792#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
1793#else
1794#define ST_FLAGS_IDX ST_RDEV_IDX
1795#endif
1796
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001797#ifdef HAVE_STRUCT_STAT_ST_GEN
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001798#define ST_GEN_IDX (ST_FLAGS_IDX+1)
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001799#else
Martin v. Löwisf09582e2005-08-14 21:42:34 +00001800#define ST_GEN_IDX ST_FLAGS_IDX
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00001801#endif
1802
1803#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
1804#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
1805#else
1806#define ST_BIRTHTIME_IDX ST_GEN_IDX
1807#endif
1808
Zachary Ware63f277b2014-06-19 09:46:37 -05001809#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
1810#define ST_FILE_ATTRIBUTES_IDX (ST_BIRTHTIME_IDX+1)
1811#else
1812#define ST_FILE_ATTRIBUTES_IDX ST_BIRTHTIME_IDX
1813#endif
1814
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001815static PyStructSequence_Desc stat_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001816 "stat_result", /* name */
1817 stat_result__doc__, /* doc */
1818 stat_result_fields,
1819 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001820};
1821
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001822PyDoc_STRVAR(statvfs_result__doc__,
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001823"statvfs_result: Result from statvfs or fstatvfs.\n\n\
1824This object may be accessed either as a tuple of\n\
Fred Drakef7ce04d2002-06-20 18:31:21 +00001825 (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
Guido van Rossuma4dc73e2001-10-18 20:53:15 +00001826or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001827\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00001828See os.statvfs for more information.");
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001829
1830static PyStructSequence_Field statvfs_result_fields[] = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001831 {"f_bsize", },
1832 {"f_frsize", },
1833 {"f_blocks", },
1834 {"f_bfree", },
1835 {"f_bavail", },
1836 {"f_files", },
1837 {"f_ffree", },
1838 {"f_favail", },
1839 {"f_flag", },
1840 {"f_namemax",},
1841 {0}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001842};
1843
1844static PyStructSequence_Desc statvfs_result_desc = {
Victor Stinner8c62be82010-05-06 00:08:46 +00001845 "statvfs_result", /* name */
1846 statvfs_result__doc__, /* doc */
1847 statvfs_result_fields,
1848 10
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001849};
1850
Ross Lagerwall7807c352011-03-17 20:20:30 +02001851#if defined(HAVE_WAITID) && !defined(__APPLE__)
1852PyDoc_STRVAR(waitid_result__doc__,
1853"waitid_result: Result from waitid.\n\n\
1854This object may be accessed either as a tuple of\n\
1855 (si_pid, si_uid, si_signo, si_status, si_code),\n\
1856or via the attributes si_pid, si_uid, and so on.\n\
1857\n\
1858See os.waitid for more information.");
1859
1860static PyStructSequence_Field waitid_result_fields[] = {
1861 {"si_pid", },
1862 {"si_uid", },
1863 {"si_signo", },
1864 {"si_status", },
1865 {"si_code", },
1866 {0}
1867};
1868
1869static PyStructSequence_Desc waitid_result_desc = {
1870 "waitid_result", /* name */
1871 waitid_result__doc__, /* doc */
1872 waitid_result_fields,
1873 5
1874};
1875static PyTypeObject WaitidResultType;
1876#endif
1877
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00001878static int initialized;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001879static PyTypeObject StatResultType;
1880static PyTypeObject StatVFSResultType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001881#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05001882static PyTypeObject SchedParamType;
Benjamin Petersonbad9c2f2011-08-02 18:42:14 -05001883#endif
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001884static newfunc structseq_new;
1885
1886static PyObject *
1887statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1888{
Victor Stinner8c62be82010-05-06 00:08:46 +00001889 PyStructSequence *result;
1890 int i;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001891
Victor Stinner8c62be82010-05-06 00:08:46 +00001892 result = (PyStructSequence*)structseq_new(type, args, kwds);
1893 if (!result)
1894 return NULL;
1895 /* If we have been initialized from a tuple,
1896 st_?time might be set to None. Initialize it
1897 from the int slots. */
1898 for (i = 7; i <= 9; i++) {
1899 if (result->ob_item[i+3] == Py_None) {
1900 Py_DECREF(Py_None);
1901 Py_INCREF(result->ob_item[i]);
1902 result->ob_item[i+3] = result->ob_item[i];
1903 }
1904 }
1905 return (PyObject*)result;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001906}
1907
1908
1909
1910/* If true, st_?time is float. */
Martin v. Löwisfe33d0b2005-01-16 08:57:39 +00001911static int _stat_float_times = 1;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001912
1913PyDoc_STRVAR(stat_float_times__doc__,
1914"stat_float_times([newval]) -> oldval\n\n\
1915Determine whether os.[lf]stat represents time stamps as float objects.\n\
Larry Hastings2f936352014-08-05 14:04:04 +10001916\n\
1917If value is True, future calls to stat() return floats; if it is False,\n\
1918future calls return ints.\n\
1919If value is omitted, return the current setting.\n");
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001920
Larry Hastings2f936352014-08-05 14:04:04 +10001921/* AC 3.5: the public default value should be None, not ready for that yet */
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001922static PyObject*
1923stat_float_times(PyObject* self, PyObject *args)
1924{
Victor Stinner8c62be82010-05-06 00:08:46 +00001925 int newval = -1;
1926 if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
1927 return NULL;
Victor Stinner034d0aa2012-06-05 01:22:15 +02001928 if (PyErr_WarnEx(PyExc_DeprecationWarning,
1929 "stat_float_times() is deprecated",
1930 1))
1931 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00001932 if (newval == -1)
1933 /* Return old value */
1934 return PyBool_FromLong(_stat_float_times);
1935 _stat_float_times = newval;
1936 Py_INCREF(Py_None);
1937 return Py_None;
Martin v. Löwisf607bda2002-10-16 18:27:39 +00001938}
Guido van Rossum98bf58f2001-10-18 20:34:25 +00001939
Larry Hastings6fe20b32012-04-19 15:07:49 -07001940static PyObject *billion = NULL;
1941
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001942static void
Victor Stinner4195b5c2012-02-08 23:03:19 +01001943fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001944{
Larry Hastings6fe20b32012-04-19 15:07:49 -07001945 PyObject *s = _PyLong_FromTime_t(sec);
1946 PyObject *ns_fractional = PyLong_FromUnsignedLong(nsec);
1947 PyObject *s_in_ns = NULL;
1948 PyObject *ns_total = NULL;
1949 PyObject *float_s = NULL;
1950
1951 if (!(s && ns_fractional))
1952 goto exit;
1953
1954 s_in_ns = PyNumber_Multiply(s, billion);
1955 if (!s_in_ns)
1956 goto exit;
1957
1958 ns_total = PyNumber_Add(s_in_ns, ns_fractional);
1959 if (!ns_total)
1960 goto exit;
1961
Victor Stinner4195b5c2012-02-08 23:03:19 +01001962 if (_stat_float_times) {
Larry Hastings6fe20b32012-04-19 15:07:49 -07001963 float_s = PyFloat_FromDouble(sec + 1e-9*nsec);
1964 if (!float_s)
1965 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00001966 }
Larry Hastings6fe20b32012-04-19 15:07:49 -07001967 else {
1968 float_s = s;
1969 Py_INCREF(float_s);
1970 }
1971
1972 PyStructSequence_SET_ITEM(v, index, s);
1973 PyStructSequence_SET_ITEM(v, index+3, float_s);
1974 PyStructSequence_SET_ITEM(v, index+6, ns_total);
1975 s = NULL;
1976 float_s = NULL;
1977 ns_total = NULL;
1978exit:
1979 Py_XDECREF(s);
1980 Py_XDECREF(ns_fractional);
1981 Py_XDECREF(s_in_ns);
1982 Py_XDECREF(ns_total);
1983 Py_XDECREF(float_s);
Martin v. Löwis94717ed2002-09-09 14:24:16 +00001984}
1985
Tim Peters5aa91602002-01-30 05:46:57 +00001986/* pack a system stat C structure into the Python stat tuple
Fred Drake699f3522000-06-29 21:12:41 +00001987 (used by posix_stat() and posix_fstat()) */
1988static PyObject*
Victor Stinner4195b5c2012-02-08 23:03:19 +01001989_pystat_fromstructstat(STRUCT_STAT *st)
Fred Drake699f3522000-06-29 21:12:41 +00001990{
Victor Stinner8c62be82010-05-06 00:08:46 +00001991 unsigned long ansec, mnsec, cnsec;
1992 PyObject *v = PyStructSequence_New(&StatResultType);
1993 if (v == NULL)
1994 return NULL;
Fred Drake699f3522000-06-29 21:12:41 +00001995
Victor Stinner8c62be82010-05-06 00:08:46 +00001996 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
Fred Drake699f3522000-06-29 21:12:41 +00001997#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00001998 PyStructSequence_SET_ITEM(v, 1,
1999 PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002000#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002001 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
Fred Drake699f3522000-06-29 21:12:41 +00002002#endif
Serhiy Storchaka404fa922013-01-02 18:22:23 +02002003#ifdef MS_WINDOWS
2004 PyStructSequence_SET_ITEM(v, 2, PyLong_FromUnsignedLong(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002005#else
Serhiy Storchakab2653b32015-01-18 11:12:11 +02002006 PyStructSequence_SET_ITEM(v, 2, _PyLong_FromDev(st->st_dev));
Fred Drake699f3522000-06-29 21:12:41 +00002007#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002008 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02002009#if defined(MS_WINDOWS)
2010 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong(0));
2011 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong(0));
2012#else
2013 PyStructSequence_SET_ITEM(v, 4, _PyLong_FromUid(st->st_uid));
2014 PyStructSequence_SET_ITEM(v, 5, _PyLong_FromGid(st->st_gid));
2015#endif
Fred Drake699f3522000-06-29 21:12:41 +00002016#ifdef HAVE_LARGEFILE_SUPPORT
Victor Stinner8c62be82010-05-06 00:08:46 +00002017 PyStructSequence_SET_ITEM(v, 6,
2018 PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002019#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002020 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
Fred Drake699f3522000-06-29 21:12:41 +00002021#endif
Martin v. Löwis94717ed2002-09-09 14:24:16 +00002022
Martin v. Löwis14694662006-02-03 12:54:16 +00002023#if defined(HAVE_STAT_TV_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002024 ansec = st->st_atim.tv_nsec;
2025 mnsec = st->st_mtim.tv_nsec;
2026 cnsec = st->st_ctim.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002027#elif defined(HAVE_STAT_TV_NSEC2)
Victor Stinner8c62be82010-05-06 00:08:46 +00002028 ansec = st->st_atimespec.tv_nsec;
2029 mnsec = st->st_mtimespec.tv_nsec;
2030 cnsec = st->st_ctimespec.tv_nsec;
Martin v. Löwis14694662006-02-03 12:54:16 +00002031#elif defined(HAVE_STAT_NSEC)
Victor Stinner8c62be82010-05-06 00:08:46 +00002032 ansec = st->st_atime_nsec;
2033 mnsec = st->st_mtime_nsec;
2034 cnsec = st->st_ctime_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002035#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002036 ansec = mnsec = cnsec = 0;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002037#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002038 fill_time(v, 7, st->st_atime, ansec);
2039 fill_time(v, 8, st->st_mtime, mnsec);
2040 fill_time(v, 9, st->st_ctime, cnsec);
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002041
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002042#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +00002043 PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
2044 PyLong_FromLong((long)st->st_blksize));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002045#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002046#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
Victor Stinner8c62be82010-05-06 00:08:46 +00002047 PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
2048 PyLong_FromLong((long)st->st_blocks));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00002049#endif
Martin v. Löwis60a5d722002-10-16 20:28:25 +00002050#ifdef HAVE_STRUCT_STAT_ST_RDEV
Victor Stinner8c62be82010-05-06 00:08:46 +00002051 PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
2052 PyLong_FromLong((long)st->st_rdev));
Fred Drake699f3522000-06-29 21:12:41 +00002053#endif
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002054#ifdef HAVE_STRUCT_STAT_ST_GEN
Victor Stinner8c62be82010-05-06 00:08:46 +00002055 PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
2056 PyLong_FromLong((long)st->st_gen));
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002057#endif
2058#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
Victor Stinner8c62be82010-05-06 00:08:46 +00002059 {
Victor Stinner4195b5c2012-02-08 23:03:19 +01002060 PyObject *val;
2061 unsigned long bsec,bnsec;
2062 bsec = (long)st->st_birthtime;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002063#ifdef HAVE_STAT_TV_NSEC2
Victor Stinner4195b5c2012-02-08 23:03:19 +01002064 bnsec = st->st_birthtimespec.tv_nsec;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002065#else
Victor Stinner4195b5c2012-02-08 23:03:19 +01002066 bnsec = 0;
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002067#endif
Victor Stinner4195b5c2012-02-08 23:03:19 +01002068 if (_stat_float_times) {
2069 val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
2070 } else {
2071 val = PyLong_FromLong((long)bsec);
2072 }
2073 PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
2074 val);
Victor Stinner8c62be82010-05-06 00:08:46 +00002075 }
Martin v. Löwisebd9d5b2005-08-09 15:00:59 +00002076#endif
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002077#ifdef HAVE_STRUCT_STAT_ST_FLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00002078 PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
2079 PyLong_FromLong((long)st->st_flags));
Hye-Shik Chang5f937a72005-06-02 13:09:30 +00002080#endif
Zachary Ware63f277b2014-06-19 09:46:37 -05002081#ifdef HAVE_STRUCT_STAT_ST_FILE_ATTRIBUTES
2082 PyStructSequence_SET_ITEM(v, ST_FILE_ATTRIBUTES_IDX,
2083 PyLong_FromUnsignedLong(st->st_file_attributes));
2084#endif
Fred Drake699f3522000-06-29 21:12:41 +00002085
Victor Stinner8c62be82010-05-06 00:08:46 +00002086 if (PyErr_Occurred()) {
2087 Py_DECREF(v);
2088 return NULL;
2089 }
Fred Drake699f3522000-06-29 21:12:41 +00002090
Victor Stinner8c62be82010-05-06 00:08:46 +00002091 return v;
Fred Drake699f3522000-06-29 21:12:41 +00002092}
2093
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002094/* POSIX methods */
2095
Guido van Rossum94f6f721999-01-06 18:42:14 +00002096
2097static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07002098posix_do_stat(char *function_name, path_t *path,
2099 int dir_fd, int follow_symlinks)
Guido van Rossum94f6f721999-01-06 18:42:14 +00002100{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002101 STRUCT_STAT st;
2102 int result;
2103
2104#if !defined(MS_WINDOWS) && !defined(HAVE_FSTATAT) && !defined(HAVE_LSTAT)
2105 if (follow_symlinks_specified(function_name, follow_symlinks))
2106 return NULL;
2107#endif
2108
2109 if (path_and_dir_fd_invalid("stat", path, dir_fd) ||
2110 dir_fd_and_fd_invalid("stat", dir_fd, path->fd) ||
2111 fd_and_follow_symlinks_invalid("stat", path->fd, follow_symlinks))
2112 return NULL;
2113
2114 Py_BEGIN_ALLOW_THREADS
2115 if (path->fd != -1)
2116 result = FSTAT(path->fd, &st);
2117 else
2118#ifdef MS_WINDOWS
2119 if (path->wide) {
2120 if (follow_symlinks)
2121 result = win32_stat_w(path->wide, &st);
2122 else
2123 result = win32_lstat_w(path->wide, &st);
2124 }
2125 else
2126#endif
2127#if defined(HAVE_LSTAT) || defined(MS_WINDOWS)
2128 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
2129 result = LSTAT(path->narrow, &st);
2130 else
2131#endif
2132#ifdef HAVE_FSTATAT
2133 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks)
2134 result = fstatat(dir_fd, path->narrow, &st,
2135 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2136 else
2137#endif
2138 result = STAT(path->narrow, &st);
2139 Py_END_ALLOW_THREADS
2140
Victor Stinner292c8352012-10-30 02:17:38 +01002141 if (result != 0) {
2142 return path_error(path);
2143 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07002144
2145 return _pystat_fromstructstat(&st);
2146}
2147
Larry Hastings2f936352014-08-05 14:04:04 +10002148/*[python input]
2149
2150for s in """
2151
2152FACCESSAT
2153FCHMODAT
2154FCHOWNAT
2155FSTATAT
2156LINKAT
2157MKDIRAT
2158MKFIFOAT
2159MKNODAT
2160OPENAT
2161READLINKAT
2162SYMLINKAT
2163UNLINKAT
2164
2165""".strip().split():
2166 s = s.strip()
2167 print("""
2168#ifdef HAVE_{s}
2169 #define {s}_DIR_FD_CONVERTER dir_fd_converter
Larry Hastings31826802013-10-19 00:09:25 -07002170#else
Larry Hastings2f936352014-08-05 14:04:04 +10002171 #define {s}_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings31826802013-10-19 00:09:25 -07002172#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002173""".rstrip().format(s=s))
2174
2175for s in """
2176
2177FCHDIR
2178FCHMOD
2179FCHOWN
2180FDOPENDIR
2181FEXECVE
2182FPATHCONF
2183FSTATVFS
2184FTRUNCATE
2185
2186""".strip().split():
2187 s = s.strip()
2188 print("""
2189#ifdef HAVE_{s}
2190 #define PATH_HAVE_{s} 1
2191#else
2192 #define PATH_HAVE_{s} 0
2193#endif
2194
2195""".rstrip().format(s=s))
2196[python start generated code]*/
2197
2198#ifdef HAVE_FACCESSAT
2199 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_converter
2200#else
2201 #define FACCESSAT_DIR_FD_CONVERTER dir_fd_unavailable
2202#endif
2203
2204#ifdef HAVE_FCHMODAT
2205 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_converter
2206#else
2207 #define FCHMODAT_DIR_FD_CONVERTER dir_fd_unavailable
2208#endif
2209
2210#ifdef HAVE_FCHOWNAT
2211 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_converter
2212#else
2213 #define FCHOWNAT_DIR_FD_CONVERTER dir_fd_unavailable
2214#endif
2215
2216#ifdef HAVE_FSTATAT
2217 #define FSTATAT_DIR_FD_CONVERTER dir_fd_converter
2218#else
2219 #define FSTATAT_DIR_FD_CONVERTER dir_fd_unavailable
2220#endif
2221
2222#ifdef HAVE_LINKAT
2223 #define LINKAT_DIR_FD_CONVERTER dir_fd_converter
2224#else
2225 #define LINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2226#endif
2227
2228#ifdef HAVE_MKDIRAT
2229 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_converter
2230#else
2231 #define MKDIRAT_DIR_FD_CONVERTER dir_fd_unavailable
2232#endif
2233
2234#ifdef HAVE_MKFIFOAT
2235 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_converter
2236#else
2237 #define MKFIFOAT_DIR_FD_CONVERTER dir_fd_unavailable
2238#endif
2239
2240#ifdef HAVE_MKNODAT
2241 #define MKNODAT_DIR_FD_CONVERTER dir_fd_converter
2242#else
2243 #define MKNODAT_DIR_FD_CONVERTER dir_fd_unavailable
2244#endif
2245
2246#ifdef HAVE_OPENAT
2247 #define OPENAT_DIR_FD_CONVERTER dir_fd_converter
2248#else
2249 #define OPENAT_DIR_FD_CONVERTER dir_fd_unavailable
2250#endif
2251
2252#ifdef HAVE_READLINKAT
2253 #define READLINKAT_DIR_FD_CONVERTER dir_fd_converter
2254#else
2255 #define READLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2256#endif
2257
2258#ifdef HAVE_SYMLINKAT
2259 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_converter
2260#else
2261 #define SYMLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2262#endif
2263
2264#ifdef HAVE_UNLINKAT
2265 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_converter
2266#else
2267 #define UNLINKAT_DIR_FD_CONVERTER dir_fd_unavailable
2268#endif
2269
2270#ifdef HAVE_FCHDIR
2271 #define PATH_HAVE_FCHDIR 1
2272#else
2273 #define PATH_HAVE_FCHDIR 0
2274#endif
2275
2276#ifdef HAVE_FCHMOD
2277 #define PATH_HAVE_FCHMOD 1
2278#else
2279 #define PATH_HAVE_FCHMOD 0
2280#endif
2281
2282#ifdef HAVE_FCHOWN
2283 #define PATH_HAVE_FCHOWN 1
2284#else
2285 #define PATH_HAVE_FCHOWN 0
2286#endif
2287
2288#ifdef HAVE_FDOPENDIR
2289 #define PATH_HAVE_FDOPENDIR 1
2290#else
2291 #define PATH_HAVE_FDOPENDIR 0
2292#endif
2293
2294#ifdef HAVE_FEXECVE
2295 #define PATH_HAVE_FEXECVE 1
2296#else
2297 #define PATH_HAVE_FEXECVE 0
2298#endif
2299
2300#ifdef HAVE_FPATHCONF
2301 #define PATH_HAVE_FPATHCONF 1
2302#else
2303 #define PATH_HAVE_FPATHCONF 0
2304#endif
2305
2306#ifdef HAVE_FSTATVFS
2307 #define PATH_HAVE_FSTATVFS 1
2308#else
2309 #define PATH_HAVE_FSTATVFS 0
2310#endif
2311
2312#ifdef HAVE_FTRUNCATE
2313 #define PATH_HAVE_FTRUNCATE 1
2314#else
2315 #define PATH_HAVE_FTRUNCATE 0
2316#endif
2317/*[python end generated code: output=4bd4f6f7d41267f1 input=80b4c890b6774ea5]*/
Larry Hastings31826802013-10-19 00:09:25 -07002318
Steve Dowerfe0a41a2015-03-20 19:50:46 -07002319#ifdef MS_WINDOWS
2320 #undef PATH_HAVE_FTRUNCATE
2321 #define PATH_HAVE_FTRUNCATE 1
2322#endif
Larry Hastings31826802013-10-19 00:09:25 -07002323
Larry Hastings61272b72014-01-07 12:41:53 -08002324/*[python input]
Larry Hastings31826802013-10-19 00:09:25 -07002325
2326class path_t_converter(CConverter):
2327
2328 type = "path_t"
2329 impl_by_reference = True
2330 parse_by_reference = True
2331
2332 converter = 'path_converter'
2333
2334 def converter_init(self, *, allow_fd=False, nullable=False):
Larry Hastings31826802013-10-19 00:09:25 -07002335 # right now path_t doesn't support default values.
2336 # to support a default value, you'll need to override initialize().
Larry Hastings2f936352014-08-05 14:04:04 +10002337 if self.default not in (unspecified, None):
Larry Hastings7726ac92014-01-31 22:03:12 -08002338 fail("Can't specify a default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002339
Larry Hastings2f936352014-08-05 14:04:04 +10002340 if self.c_default not in (None, 'Py_None'):
2341 raise RuntimeError("Can't specify a c_default to the path_t converter!")
Larry Hastings31826802013-10-19 00:09:25 -07002342
2343 self.nullable = nullable
2344 self.allow_fd = allow_fd
2345
Larry Hastings7726ac92014-01-31 22:03:12 -08002346 def pre_render(self):
2347 def strify(value):
Larry Hastings2f936352014-08-05 14:04:04 +10002348 if isinstance(value, str):
2349 return value
Larry Hastings7726ac92014-01-31 22:03:12 -08002350 return str(int(bool(value)))
2351
2352 # add self.py_name here when merging with posixmodule conversion
Larry Hastings2f936352014-08-05 14:04:04 +10002353 self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
Larry Hastings31826802013-10-19 00:09:25 -07002354 self.function.name,
Larry Hastings2f936352014-08-05 14:04:04 +10002355 self.name,
Larry Hastings7726ac92014-01-31 22:03:12 -08002356 strify(self.nullable),
2357 strify(self.allow_fd),
Larry Hastings31826802013-10-19 00:09:25 -07002358 )
2359
2360 def cleanup(self):
2361 return "path_cleanup(&" + self.name + ");\n"
2362
2363
2364class dir_fd_converter(CConverter):
2365 type = 'int'
Larry Hastings31826802013-10-19 00:09:25 -07002366
Larry Hastings2f936352014-08-05 14:04:04 +10002367 def converter_init(self, requires=None):
Larry Hastings31826802013-10-19 00:09:25 -07002368 if self.default in (unspecified, None):
2369 self.c_default = 'DEFAULT_DIR_FD'
Larry Hastings2f936352014-08-05 14:04:04 +10002370 if isinstance(requires, str):
2371 self.converter = requires.upper() + '_DIR_FD_CONVERTER'
2372 else:
2373 self.converter = 'dir_fd_converter'
Larry Hastings31826802013-10-19 00:09:25 -07002374
Larry Hastings2f936352014-08-05 14:04:04 +10002375class fildes_converter(CConverter):
2376 type = 'int'
2377 converter = 'fildes_converter'
2378
2379class uid_t_converter(CConverter):
2380 type = "uid_t"
2381 converter = '_Py_Uid_Converter'
2382
2383class gid_t_converter(CConverter):
2384 type = "gid_t"
2385 converter = '_Py_Gid_Converter'
2386
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002387class dev_t_converter(CConverter):
2388 type = 'dev_t'
2389 converter = '_Py_Dev_Converter'
2390
2391class dev_t_return_converter(unsigned_long_return_converter):
2392 type = 'dev_t'
2393 conversion_fn = '_PyLong_FromDev'
2394 unsigned_cast = '(dev_t)'
2395
Larry Hastings2f936352014-08-05 14:04:04 +10002396class FSConverter_converter(CConverter):
2397 type = 'PyObject *'
2398 converter = 'PyUnicode_FSConverter'
2399 def converter_init(self):
2400 if self.default is not unspecified:
2401 fail("FSConverter_converter does not support default values")
2402 self.c_default = 'NULL'
2403
2404 def cleanup(self):
2405 return "Py_XDECREF(" + self.name + ");\n"
2406
2407class pid_t_converter(CConverter):
2408 type = 'pid_t'
2409 format_unit = '" _Py_PARSE_PID "'
2410
2411class idtype_t_converter(int_converter):
2412 type = 'idtype_t'
2413
2414class id_t_converter(CConverter):
2415 type = 'id_t'
2416 format_unit = '" _Py_PARSE_PID "'
2417
2418class Py_intptr_t_converter(CConverter):
2419 type = 'Py_intptr_t'
2420 format_unit = '" _Py_PARSE_INTPTR "'
2421
2422class Py_off_t_converter(CConverter):
2423 type = 'Py_off_t'
2424 converter = 'Py_off_t_converter'
2425
2426class Py_off_t_return_converter(long_return_converter):
2427 type = 'Py_off_t'
2428 conversion_fn = 'PyLong_FromPy_off_t'
2429
2430class path_confname_converter(CConverter):
2431 type="int"
2432 converter="conv_path_confname"
2433
2434class confstr_confname_converter(path_confname_converter):
2435 converter='conv_confstr_confname'
2436
2437class sysconf_confname_converter(path_confname_converter):
2438 converter="conv_sysconf_confname"
2439
2440class sched_param_converter(CConverter):
2441 type = 'struct sched_param'
2442 converter = 'convert_sched_param'
2443 impl_by_reference = True;
Larry Hastings31826802013-10-19 00:09:25 -07002444
Larry Hastings61272b72014-01-07 12:41:53 -08002445[python start generated code]*/
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02002446/*[python end generated code: output=da39a3ee5e6b4b0d input=affe68316f160401]*/
Larry Hastings31826802013-10-19 00:09:25 -07002447
Larry Hastings61272b72014-01-07 12:41:53 -08002448/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002449
Larry Hastings2a727912014-01-16 11:32:01 -08002450os.stat
Larry Hastings31826802013-10-19 00:09:25 -07002451
2452 path : path_t(allow_fd=True)
2453 Path to be examined; can be string, bytes, or open-file-descriptor int.
2454
2455 *
2456
Larry Hastings2f936352014-08-05 14:04:04 +10002457 dir_fd : dir_fd(requires='fstatat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002458 If not None, it should be a file descriptor open to a directory,
2459 and path should be a relative string; path will then be relative to
2460 that directory.
2461
2462 follow_symlinks: bool = True
2463 If False, and the last element of the path is a symbolic link,
2464 stat will examine the symbolic link itself instead of the file
2465 the link points to.
2466
2467Perform a stat system call on the given path.
2468
2469dir_fd and follow_symlinks may not be implemented
2470 on your platform. If they are unavailable, using them will raise a
2471 NotImplementedError.
2472
2473It's an error to use dir_fd or follow_symlinks when specifying path as
2474 an open file descriptor.
2475
Larry Hastings61272b72014-01-07 12:41:53 -08002476[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002477
Larry Hastings31826802013-10-19 00:09:25 -07002478static PyObject *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002479os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002480/*[clinic end generated code: output=708c225f94fcfc8e input=099d356c306fa24a]*/
Larry Hastings31826802013-10-19 00:09:25 -07002481{
2482 return posix_do_stat("stat", path, dir_fd, follow_symlinks);
2483}
2484
Larry Hastings2f936352014-08-05 14:04:04 +10002485
2486/*[clinic input]
2487os.lstat
2488
2489 path : path_t
2490
2491 *
2492
2493 dir_fd : dir_fd(requires='fstatat') = None
2494
2495Perform a stat system call on the given path, without following symbolic links.
2496
2497Like stat(), but do not follow symbolic links.
2498Equivalent to stat(path, follow_symlinks=False).
2499[clinic start generated code]*/
2500
Larry Hastings2f936352014-08-05 14:04:04 +10002501static PyObject *
2502os_lstat_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002503/*[clinic end generated code: output=7a748e333fcb39bd input=0b7474765927b925]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002504{
2505 int follow_symlinks = 0;
2506 return posix_do_stat("lstat", path, dir_fd, follow_symlinks);
2507}
Larry Hastings31826802013-10-19 00:09:25 -07002508
Larry Hastings2f936352014-08-05 14:04:04 +10002509
Larry Hastings61272b72014-01-07 12:41:53 -08002510/*[clinic input]
Larry Hastings2f936352014-08-05 14:04:04 +10002511os.access -> bool
Larry Hastings31826802013-10-19 00:09:25 -07002512
2513 path: path_t(allow_fd=True)
2514 Path to be tested; can be string, bytes, or open-file-descriptor int.
2515
2516 mode: int
2517 Operating-system mode bitfield. Can be F_OK to test existence,
2518 or the inclusive-OR of R_OK, W_OK, and X_OK.
2519
2520 *
2521
Larry Hastings2f936352014-08-05 14:04:04 +10002522 dir_fd : dir_fd(requires='faccessat') = None
Larry Hastings31826802013-10-19 00:09:25 -07002523 If not None, it should be a file descriptor open to a directory,
2524 and path should be relative; path will then be relative to that
2525 directory.
2526
2527 effective_ids: bool = False
2528 If True, access will use the effective uid/gid instead of
2529 the real uid/gid.
2530
2531 follow_symlinks: bool = True
2532 If False, and the last element of the path is a symbolic link,
2533 access will examine the symbolic link itself instead of the file
2534 the link points to.
2535
2536Use the real uid/gid to test for access to a path.
2537
2538{parameters}
2539dir_fd, effective_ids, and follow_symlinks may not be implemented
2540 on your platform. If they are unavailable, using them will raise a
2541 NotImplementedError.
2542
2543Note that most operations will use the effective uid/gid, therefore this
2544 routine can be used in a suid/sgid environment to test if the invoking user
2545 has the specified access to the path.
2546
Larry Hastings61272b72014-01-07 12:41:53 -08002547[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002548
Larry Hastings2f936352014-08-05 14:04:04 +10002549static int
Larry Hastingsebdcb502013-11-23 14:54:00 -08002550os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002551/*[clinic end generated code: output=f9e734db3d88b767 input=b75a756797af45ec]*/
Larry Hastings31826802013-10-19 00:09:25 -07002552{
Larry Hastings2f936352014-08-05 14:04:04 +10002553 int return_value;
Victor Stinner8c62be82010-05-06 00:08:46 +00002554
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002555#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002556 DWORD attr;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002557#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07002558 int result;
Thomas Wouters477c8d52006-05-27 19:21:47 +00002559#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07002560
Larry Hastings9cf065c2012-06-22 16:30:09 -07002561#ifndef HAVE_FACCESSAT
2562 if (follow_symlinks_specified("access", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002563 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002564
2565 if (effective_ids) {
2566 argument_unavailable_error("access", "effective_ids");
Larry Hastings2f936352014-08-05 14:04:04 +10002567 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002568 }
2569#endif
2570
2571#ifdef MS_WINDOWS
2572 Py_BEGIN_ALLOW_THREADS
Christian Heimesebe83f92013-10-19 22:36:17 +02002573 if (path->wide != NULL)
2574 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002575 else
Christian Heimesebe83f92013-10-19 22:36:17 +02002576 attr = GetFileAttributesA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002577 Py_END_ALLOW_THREADS
2578
2579 /*
Georg Brandlf7875592012-06-24 13:58:31 +02002580 * Access is possible if
Larry Hastings9cf065c2012-06-22 16:30:09 -07002581 * * we didn't get a -1, and
2582 * * write access wasn't requested,
2583 * * or the file isn't read-only,
2584 * * or it's a directory.
2585 * (Directories cannot be read-only on Windows.)
2586 */
Larry Hastings2f936352014-08-05 14:04:04 +10002587 return_value = (attr != INVALID_FILE_ATTRIBUTES) &&
Georg Brandl5bb7aa92012-06-23 12:48:40 +02002588 (!(mode & 2) ||
Larry Hastings9cf065c2012-06-22 16:30:09 -07002589 !(attr & FILE_ATTRIBUTE_READONLY) ||
Larry Hastings2f936352014-08-05 14:04:04 +10002590 (attr & FILE_ATTRIBUTE_DIRECTORY));
Larry Hastings9cf065c2012-06-22 16:30:09 -07002591#else
2592
2593 Py_BEGIN_ALLOW_THREADS
2594#ifdef HAVE_FACCESSAT
2595 if ((dir_fd != DEFAULT_DIR_FD) ||
2596 effective_ids ||
2597 !follow_symlinks) {
2598 int flags = 0;
2599 if (!follow_symlinks)
2600 flags |= AT_SYMLINK_NOFOLLOW;
2601 if (effective_ids)
2602 flags |= AT_EACCESS;
Larry Hastings31826802013-10-19 00:09:25 -07002603 result = faccessat(dir_fd, path->narrow, mode, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002604 }
2605 else
2606#endif
Larry Hastings31826802013-10-19 00:09:25 -07002607 result = access(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002608 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002609 return_value = !result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002610#endif
2611
Larry Hastings9cf065c2012-06-22 16:30:09 -07002612 return return_value;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002613}
2614
Guido van Rossumd371ff11999-01-25 16:12:23 +00002615#ifndef F_OK
2616#define F_OK 0
2617#endif
2618#ifndef R_OK
2619#define R_OK 4
2620#endif
2621#ifndef W_OK
2622#define W_OK 2
2623#endif
2624#ifndef X_OK
2625#define X_OK 1
2626#endif
2627
Larry Hastings31826802013-10-19 00:09:25 -07002628
Guido van Rossumd371ff11999-01-25 16:12:23 +00002629#ifdef HAVE_TTYNAME
Larry Hastings61272b72014-01-07 12:41:53 -08002630/*[clinic input]
Larry Hastings31826802013-10-19 00:09:25 -07002631os.ttyname -> DecodeFSDefault
2632
2633 fd: int
2634 Integer file descriptor handle.
2635
2636 /
2637
2638Return the name of the terminal device connected to 'fd'.
Larry Hastings61272b72014-01-07 12:41:53 -08002639[clinic start generated code]*/
Larry Hastings31826802013-10-19 00:09:25 -07002640
Larry Hastings31826802013-10-19 00:09:25 -07002641static char *
Larry Hastingsebdcb502013-11-23 14:54:00 -08002642os_ttyname_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002643/*[clinic end generated code: output=03ad3d5ccaef75c3 input=5f72ca83e76b3b45]*/
Larry Hastings31826802013-10-19 00:09:25 -07002644{
2645 char *ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002646
Larry Hastings31826802013-10-19 00:09:25 -07002647 ret = ttyname(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00002648 if (ret == NULL)
Larry Hastings31826802013-10-19 00:09:25 -07002649 posix_error();
2650 return ret;
Guido van Rossum94f6f721999-01-06 18:42:14 +00002651}
Guido van Rossumd371ff11999-01-25 16:12:23 +00002652#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00002653
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002654#ifdef HAVE_CTERMID
Larry Hastings2f936352014-08-05 14:04:04 +10002655/*[clinic input]
2656os.ctermid
2657
2658Return the name of the controlling terminal for this process.
2659[clinic start generated code]*/
2660
Larry Hastings2f936352014-08-05 14:04:04 +10002661static PyObject *
2662os_ctermid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002663/*[clinic end generated code: output=1b73788201e0aebd input=3b87fdd52556382d]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002664{
Victor Stinner8c62be82010-05-06 00:08:46 +00002665 char *ret;
2666 char buffer[L_ctermid];
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002667
Greg Wardb48bc172000-03-01 21:51:56 +00002668#ifdef USE_CTERMID_R
Victor Stinner8c62be82010-05-06 00:08:46 +00002669 ret = ctermid_r(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002670#else
Victor Stinner8c62be82010-05-06 00:08:46 +00002671 ret = ctermid(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002672#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00002673 if (ret == NULL)
2674 return posix_error();
Victor Stinner5fe6de82010-08-15 09:12:51 +00002675 return PyUnicode_DecodeFSDefault(buffer);
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002676}
Larry Hastings2f936352014-08-05 14:04:04 +10002677#endif /* HAVE_CTERMID */
Fred Drake5ab8eaf1999-12-09 21:13:07 +00002678
Larry Hastings2f936352014-08-05 14:04:04 +10002679
2680/*[clinic input]
2681os.chdir
2682
2683 path: path_t(allow_fd='PATH_HAVE_FCHDIR')
2684
2685Change the current working directory to the specified path.
2686
2687path may always be specified as a string.
2688On some platforms, path may also be specified as an open file descriptor.
2689 If this functionality is unavailable, using it raises an exception.
2690[clinic start generated code]*/
2691
Larry Hastings2f936352014-08-05 14:04:04 +10002692static PyObject *
2693os_chdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002694/*[clinic end generated code: output=7358e3a20fb5aa93 input=1a4a15b4d12cb15d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002695{
2696 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002697
2698 Py_BEGIN_ALLOW_THREADS
2699#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10002700 if (path->wide)
2701 result = win32_wchdir(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002702 else
Larry Hastings2f936352014-08-05 14:04:04 +10002703 result = win32_chdir(path->narrow);
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03002704 result = !result; /* on unix, success = 0, on windows, success = !0 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07002705#else
2706#ifdef HAVE_FCHDIR
Larry Hastings2f936352014-08-05 14:04:04 +10002707 if (path->fd != -1)
2708 result = fchdir(path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002709 else
2710#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002711 result = chdir(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002712#endif
2713 Py_END_ALLOW_THREADS
2714
2715 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002716 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002717 }
2718
Larry Hastings2f936352014-08-05 14:04:04 +10002719 Py_RETURN_NONE;
2720}
2721
2722
2723#ifdef HAVE_FCHDIR
2724/*[clinic input]
2725os.fchdir
2726
2727 fd: fildes
2728
2729Change to the directory of the given file descriptor.
2730
2731fd must be opened on a directory, not a file.
2732Equivalent to os.chdir(fd).
2733
2734[clinic start generated code]*/
2735
Fred Drake4d1e64b2002-04-15 19:40:07 +00002736static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10002737os_fchdir_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002738/*[clinic end generated code: output=361d30df6b2d3418 input=18e816479a2fa985]*/
Fred Drake4d1e64b2002-04-15 19:40:07 +00002739{
Larry Hastings2f936352014-08-05 14:04:04 +10002740 return posix_fildes_fd(fd, fchdir);
Fred Drake4d1e64b2002-04-15 19:40:07 +00002741}
2742#endif /* HAVE_FCHDIR */
2743
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002744
Larry Hastings2f936352014-08-05 14:04:04 +10002745/*[clinic input]
2746os.chmod
2747
2748 path: path_t(allow_fd='PATH_HAVE_FCHMOD')
2749 Path to be modified. May always be specified as a str or bytes.
2750 On some platforms, path may also be specified as an open file descriptor.
2751 If this functionality is unavailable, using it raises an exception.
2752
2753 mode: int
2754 Operating-system mode bitfield.
2755
2756 *
2757
2758 dir_fd : dir_fd(requires='fchmodat') = None
2759 If not None, it should be a file descriptor open to a directory,
2760 and path should be relative; path will then be relative to that
2761 directory.
2762
2763 follow_symlinks: bool = True
2764 If False, and the last element of the path is a symbolic link,
2765 chmod will modify the symbolic link itself instead of the file
2766 the link points to.
2767
2768Change the access permissions of a file.
2769
2770It is an error to use dir_fd or follow_symlinks when specifying path as
2771 an open file descriptor.
2772dir_fd and follow_symlinks may not be implemented on your platform.
2773 If they are unavailable, using them will raise a NotImplementedError.
2774
2775[clinic start generated code]*/
2776
Larry Hastings2f936352014-08-05 14:04:04 +10002777static PyObject *
2778os_chmod_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002779/*[clinic end generated code: output=96063c976f23106a input=7f1618e5e15cc196]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002780{
Larry Hastings9cf065c2012-06-22 16:30:09 -07002781 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002782
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00002783#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002784 DWORD attr;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002785#endif
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00002786
Larry Hastings9cf065c2012-06-22 16:30:09 -07002787#ifdef HAVE_FCHMODAT
2788 int fchmodat_nofollow_unsupported = 0;
2789#endif
2790
Larry Hastings9cf065c2012-06-22 16:30:09 -07002791#if !(defined(HAVE_FCHMODAT) || defined(HAVE_LCHMOD))
2792 if (follow_symlinks_specified("chmod", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002793 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002794#endif
2795
2796#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00002797 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10002798 if (path->wide)
2799 attr = GetFileAttributesW(path->wide);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002800 else
Larry Hastings2f936352014-08-05 14:04:04 +10002801 attr = GetFileAttributesA(path->narrow);
Tim Golden23005082013-10-25 11:22:37 +01002802 if (attr == INVALID_FILE_ATTRIBUTES)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002803 result = 0;
2804 else {
2805 if (mode & _S_IWRITE)
Victor Stinner8c62be82010-05-06 00:08:46 +00002806 attr &= ~FILE_ATTRIBUTE_READONLY;
2807 else
2808 attr |= FILE_ATTRIBUTE_READONLY;
Larry Hastings2f936352014-08-05 14:04:04 +10002809 if (path->wide)
2810 result = SetFileAttributesW(path->wide, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002811 else
Larry Hastings2f936352014-08-05 14:04:04 +10002812 result = SetFileAttributesA(path->narrow, attr);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002813 }
2814 Py_END_ALLOW_THREADS
2815
2816 if (!result) {
Larry Hastings2f936352014-08-05 14:04:04 +10002817 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002818 }
2819#else /* MS_WINDOWS */
2820 Py_BEGIN_ALLOW_THREADS
2821#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002822 if (path->fd != -1)
2823 result = fchmod(path->fd, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002824 else
2825#endif
2826#ifdef HAVE_LCHMOD
2827 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10002828 result = lchmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002829 else
2830#endif
2831#ifdef HAVE_FCHMODAT
2832 if ((dir_fd != DEFAULT_DIR_FD) || !follow_symlinks) {
2833 /*
2834 * fchmodat() doesn't currently support AT_SYMLINK_NOFOLLOW!
2835 * The documentation specifically shows how to use it,
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002836 * and then says it isn't implemented yet.
2837 * (true on linux with glibc 2.15, and openindiana 3.x)
Larry Hastings9cf065c2012-06-22 16:30:09 -07002838 *
2839 * Once it is supported, os.chmod will automatically
2840 * support dir_fd and follow_symlinks=False. (Hopefully.)
2841 * Until then, we need to be careful what exception we raise.
2842 */
Larry Hastings2f936352014-08-05 14:04:04 +10002843 result = fchmodat(dir_fd, path->narrow, mode,
Larry Hastings9cf065c2012-06-22 16:30:09 -07002844 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
2845 /*
2846 * But wait! We can't throw the exception without allowing threads,
2847 * and we can't do that in this nested scope. (Macro trickery, sigh.)
2848 */
2849 fchmodat_nofollow_unsupported =
Larry Hastingsdbbc0c82012-06-22 19:50:21 -07002850 result &&
2851 ((errno == ENOTSUP) || (errno == EOPNOTSUPP)) &&
2852 !follow_symlinks;
Victor Stinner8c62be82010-05-06 00:08:46 +00002853 }
2854 else
Thomas Wouters477c8d52006-05-27 19:21:47 +00002855#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002856 result = chmod(path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002857 Py_END_ALLOW_THREADS
2858
2859 if (result) {
2860#ifdef HAVE_FCHMODAT
2861 if (fchmodat_nofollow_unsupported) {
2862 if (dir_fd != DEFAULT_DIR_FD)
2863 dir_fd_and_follow_symlinks_invalid("chmod",
2864 dir_fd, follow_symlinks);
2865 else
2866 follow_symlinks_specified("chmod", follow_symlinks);
2867 }
2868 else
2869#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002870 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002871 }
2872#endif
2873
Larry Hastings2f936352014-08-05 14:04:04 +10002874 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00002875}
2876
Larry Hastings9cf065c2012-06-22 16:30:09 -07002877
Christian Heimes4e30a842007-11-30 22:12:06 +00002878#ifdef HAVE_FCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002879/*[clinic input]
2880os.fchmod
2881
2882 fd: int
2883 mode: int
2884
2885Change the access permissions of the file given by file descriptor fd.
2886
2887Equivalent to os.chmod(fd, mode).
2888[clinic start generated code]*/
2889
Larry Hastings2f936352014-08-05 14:04:04 +10002890static PyObject *
2891os_fchmod_impl(PyModuleDef *module, int fd, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002892/*[clinic end generated code: output=2ee31ca226d1ed33 input=8ab11975ca01ee5b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002893{
2894 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00002895 int async_err = 0;
2896
2897 do {
2898 Py_BEGIN_ALLOW_THREADS
2899 res = fchmod(fd, mode);
2900 Py_END_ALLOW_THREADS
2901 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
2902 if (res != 0)
2903 return (!async_err) ? posix_error() : NULL;
2904
Victor Stinner8c62be82010-05-06 00:08:46 +00002905 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002906}
2907#endif /* HAVE_FCHMOD */
2908
Larry Hastings2f936352014-08-05 14:04:04 +10002909
Christian Heimes4e30a842007-11-30 22:12:06 +00002910#ifdef HAVE_LCHMOD
Larry Hastings2f936352014-08-05 14:04:04 +10002911/*[clinic input]
2912os.lchmod
2913
2914 path: path_t
2915 mode: int
2916
2917Change the access permissions of a file, without following symbolic links.
2918
2919If path is a symlink, this affects the link itself rather than the target.
2920Equivalent to chmod(path, mode, follow_symlinks=False)."
2921[clinic start generated code]*/
2922
Larry Hastings2f936352014-08-05 14:04:04 +10002923static PyObject *
2924os_lchmod_impl(PyModuleDef *module, path_t *path, int mode)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002925/*[clinic end generated code: output=7c0cc46588d89e46 input=90c5663c7465d24f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002926{
Victor Stinner8c62be82010-05-06 00:08:46 +00002927 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00002928 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10002929 res = lchmod(path->narrow, mode);
Victor Stinner8c62be82010-05-06 00:08:46 +00002930 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01002931 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10002932 path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01002933 return NULL;
2934 }
Victor Stinner8c62be82010-05-06 00:08:46 +00002935 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00002936}
2937#endif /* HAVE_LCHMOD */
2938
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00002939
Thomas Wouterscf297e42007-02-23 15:07:44 +00002940#ifdef HAVE_CHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002941/*[clinic input]
2942os.chflags
2943
2944 path: path_t
2945 flags: unsigned_long(bitwise=True)
2946 follow_symlinks: bool=True
2947
2948Set file flags.
2949
2950If follow_symlinks is False, and the last element of the path is a symbolic
2951 link, chflags will change flags on the symbolic link itself instead of the
2952 file the link points to.
2953follow_symlinks may not be implemented on your platform. If it is
2954unavailable, using it will raise a NotImplementedError.
2955
2956[clinic start generated code]*/
2957
Larry Hastings2f936352014-08-05 14:04:04 +10002958static PyObject *
2959os_chflags_impl(PyModuleDef *module, path_t *path, unsigned long flags, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03002960/*[clinic end generated code: output=9e5f9417afc20c4b input=0327e29feb876236]*/
Larry Hastings2f936352014-08-05 14:04:04 +10002961{
2962 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002963
2964#ifndef HAVE_LCHFLAGS
2965 if (follow_symlinks_specified("chflags", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10002966 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07002967#endif
2968
Victor Stinner8c62be82010-05-06 00:08:46 +00002969 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002970#ifdef HAVE_LCHFLAGS
2971 if (!follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +10002972 result = lchflags(path->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002973 else
2974#endif
Larry Hastings2f936352014-08-05 14:04:04 +10002975 result = chflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00002976 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07002977
Larry Hastings2f936352014-08-05 14:04:04 +10002978 if (result)
2979 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07002980
Larry Hastings2f936352014-08-05 14:04:04 +10002981 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00002982}
2983#endif /* HAVE_CHFLAGS */
2984
Larry Hastings2f936352014-08-05 14:04:04 +10002985
Thomas Wouterscf297e42007-02-23 15:07:44 +00002986#ifdef HAVE_LCHFLAGS
Larry Hastings2f936352014-08-05 14:04:04 +10002987/*[clinic input]
2988os.lchflags
2989
2990 path: path_t
2991 flags: unsigned_long(bitwise=True)
2992
2993Set file flags.
2994
2995This function will not follow symbolic links.
2996Equivalent to chflags(path, flags, follow_symlinks=False).
2997[clinic start generated code]*/
2998
Larry Hastings2f936352014-08-05 14:04:04 +10002999static PyObject *
3000os_lchflags_impl(PyModuleDef *module, path_t *path, unsigned long flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003001/*[clinic end generated code: output=6741322fb949661b input=f9f82ea8b585ca9d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003002{
Victor Stinner8c62be82010-05-06 00:08:46 +00003003 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003004 Py_BEGIN_ALLOW_THREADS
Larry Hastingsb1dc1122014-08-05 16:06:16 +10003005 res = lchflags(path->narrow, flags);
Victor Stinner8c62be82010-05-06 00:08:46 +00003006 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003007 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003008 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003009 }
Victor Stinner292c8352012-10-30 02:17:38 +01003010 Py_RETURN_NONE;
Thomas Wouterscf297e42007-02-23 15:07:44 +00003011}
3012#endif /* HAVE_LCHFLAGS */
3013
Larry Hastings2f936352014-08-05 14:04:04 +10003014
Martin v. Löwis244edc82001-10-04 22:44:26 +00003015#ifdef HAVE_CHROOT
Larry Hastings2f936352014-08-05 14:04:04 +10003016/*[clinic input]
3017os.chroot
3018 path: path_t
3019
3020Change root directory to path.
3021
3022[clinic start generated code]*/
3023
Larry Hastings2f936352014-08-05 14:04:04 +10003024static PyObject *
3025os_chroot_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003026/*[clinic end generated code: output=b6dbfabe74ecaa9d input=14822965652c3dc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003027{
3028 int res;
3029 Py_BEGIN_ALLOW_THREADS
3030 res = chroot(path->narrow);
3031 Py_END_ALLOW_THREADS
3032 if (res < 0)
3033 return path_error(path);
3034 Py_RETURN_NONE;
3035}
3036#endif /* HAVE_CHROOT */
3037
Martin v. Löwis244edc82001-10-04 22:44:26 +00003038
Guido van Rossum21142a01999-01-08 21:05:37 +00003039#ifdef HAVE_FSYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003040/*[clinic input]
3041os.fsync
3042
3043 fd: fildes
3044
3045Force write of fd to disk.
3046[clinic start generated code]*/
3047
Larry Hastings2f936352014-08-05 14:04:04 +10003048static PyObject *
3049os_fsync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003050/*[clinic end generated code: output=83a350851064aea7 input=21c3645c056967f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003051{
3052 return posix_fildes_fd(fd, fsync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003053}
3054#endif /* HAVE_FSYNC */
3055
Larry Hastings2f936352014-08-05 14:04:04 +10003056
Ross Lagerwall7807c352011-03-17 20:20:30 +02003057#ifdef HAVE_SYNC
Larry Hastings2f936352014-08-05 14:04:04 +10003058/*[clinic input]
3059os.sync
3060
3061Force write of everything to disk.
3062[clinic start generated code]*/
3063
Larry Hastings2f936352014-08-05 14:04:04 +10003064static PyObject *
3065os_sync_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003066/*[clinic end generated code: output=ba524f656c201c40 input=84749fe5e9b404ff]*/
Ross Lagerwall7807c352011-03-17 20:20:30 +02003067{
3068 Py_BEGIN_ALLOW_THREADS
3069 sync();
3070 Py_END_ALLOW_THREADS
3071 Py_RETURN_NONE;
3072}
Larry Hastings2f936352014-08-05 14:04:04 +10003073#endif /* HAVE_SYNC */
3074
Ross Lagerwall7807c352011-03-17 20:20:30 +02003075
Guido van Rossum21142a01999-01-08 21:05:37 +00003076#ifdef HAVE_FDATASYNC
Guido van Rossum7f58e2e2000-09-22 17:26:14 +00003077#ifdef __hpux
Guido van Rossumecc23b02000-09-22 16:01:05 +00003078extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
3079#endif
3080
Larry Hastings2f936352014-08-05 14:04:04 +10003081/*[clinic input]
3082os.fdatasync
3083
3084 fd: fildes
3085
3086Force write of fd to disk without forcing update of metadata.
3087[clinic start generated code]*/
3088
Larry Hastings2f936352014-08-05 14:04:04 +10003089static PyObject *
3090os_fdatasync_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003091/*[clinic end generated code: output=e0f04a3aff515b75 input=bc74791ee54dd291]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003092{
3093 return posix_fildes_fd(fd, fdatasync);
Guido van Rossum21142a01999-01-08 21:05:37 +00003094}
3095#endif /* HAVE_FDATASYNC */
3096
3097
Fredrik Lundh10723342000-07-10 16:38:09 +00003098#ifdef HAVE_CHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003099/*[clinic input]
3100os.chown
3101
3102 path : path_t(allow_fd='PATH_HAVE_FCHOWN')
3103 Path to be examined; can be string, bytes, or open-file-descriptor int.
3104
3105 uid: uid_t
3106
3107 gid: gid_t
3108
3109 *
3110
3111 dir_fd : dir_fd(requires='fchownat') = None
3112 If not None, it should be a file descriptor open to a directory,
3113 and path should be relative; path will then be relative to that
3114 directory.
3115
3116 follow_symlinks: bool = True
3117 If False, and the last element of the path is a symbolic link,
3118 stat will examine the symbolic link itself instead of the file
3119 the link points to.
3120
3121Change the owner and group id of path to the numeric uid and gid.\
3122
3123path may always be specified as a string.
3124On some platforms, path may also be specified as an open file descriptor.
3125 If this functionality is unavailable, using it raises an exception.
3126If dir_fd is not None, it should be a file descriptor open to a directory,
3127 and path should be relative; path will then be relative to that directory.
3128If follow_symlinks is False, and the last element of the path is a symbolic
3129 link, chown will modify the symbolic link itself instead of the file the
3130 link points to.
3131It is an error to use dir_fd or follow_symlinks when specifying path as
3132 an open file descriptor.
3133dir_fd and follow_symlinks may not be implemented on your platform.
3134 If they are unavailable, using them will raise a NotImplementedError.
3135
3136[clinic start generated code]*/
3137
Larry Hastings2f936352014-08-05 14:04:04 +10003138static PyObject *
3139os_chown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003140/*[clinic end generated code: output=59a8db91897fb46c input=a61cc35574814d5d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003141{
3142 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003143
3144#if !(defined(HAVE_LCHOWN) || defined(HAVE_FCHOWNAT))
3145 if (follow_symlinks_specified("chown", follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003146 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003147#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003148 if (dir_fd_and_fd_invalid("chown", dir_fd, path->fd) ||
3149 fd_and_follow_symlinks_invalid("chown", path->fd, follow_symlinks))
3150 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003151
3152#ifdef __APPLE__
3153 /*
3154 * This is for Mac OS X 10.3, which doesn't have lchown.
3155 * (But we still have an lchown symbol because of weak-linking.)
3156 * It doesn't have fchownat either. So there's no possibility
3157 * of a graceful failover.
Georg Brandlf7875592012-06-24 13:58:31 +02003158 */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003159 if ((!follow_symlinks) && (lchown == NULL)) {
3160 follow_symlinks_specified("chown", follow_symlinks);
Larry Hastings2f936352014-08-05 14:04:04 +10003161 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003162 }
3163#endif
3164
Victor Stinner8c62be82010-05-06 00:08:46 +00003165 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003166#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003167 if (path->fd != -1)
3168 result = fchown(path->fd, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003169 else
3170#endif
3171#ifdef HAVE_LCHOWN
3172 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10003173 result = lchown(path->narrow, uid, gid);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003174 else
3175#endif
3176#ifdef HAVE_FCHOWNAT
3177 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003178 result = fchownat(dir_fd, path->narrow, uid, gid,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003179 follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW);
3180 else
3181#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003182 result = chown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003183 Py_END_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003184
Larry Hastings2f936352014-08-05 14:04:04 +10003185 if (result)
3186 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003187
Larry Hastings2f936352014-08-05 14:04:04 +10003188 Py_RETURN_NONE;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003189}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003190#endif /* HAVE_CHOWN */
Guido van Rossumb6775db1994-08-01 11:34:53 +00003191
Larry Hastings2f936352014-08-05 14:04:04 +10003192
Christian Heimes4e30a842007-11-30 22:12:06 +00003193#ifdef HAVE_FCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003194/*[clinic input]
3195os.fchown
3196
3197 fd: int
3198 uid: uid_t
3199 gid: gid_t
3200
3201Change the owner and group id of the file specified by file descriptor.
3202
3203Equivalent to os.chown(fd, uid, gid).
3204
3205[clinic start generated code]*/
3206
Larry Hastings2f936352014-08-05 14:04:04 +10003207static PyObject *
3208os_fchown_impl(PyModuleDef *module, int fd, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003209/*[clinic end generated code: output=7545abf8f6086d76 input=3af544ba1b13a0d7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003210{
Victor Stinner8c62be82010-05-06 00:08:46 +00003211 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00003212 int async_err = 0;
3213
3214 do {
3215 Py_BEGIN_ALLOW_THREADS
3216 res = fchown(fd, uid, gid);
3217 Py_END_ALLOW_THREADS
3218 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
3219 if (res != 0)
3220 return (!async_err) ? posix_error() : NULL;
3221
Victor Stinner8c62be82010-05-06 00:08:46 +00003222 Py_RETURN_NONE;
Christian Heimes4e30a842007-11-30 22:12:06 +00003223}
3224#endif /* HAVE_FCHOWN */
3225
Larry Hastings2f936352014-08-05 14:04:04 +10003226
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003227#ifdef HAVE_LCHOWN
Larry Hastings2f936352014-08-05 14:04:04 +10003228/*[clinic input]
3229os.lchown
3230
3231 path : path_t
3232 uid: uid_t
3233 gid: gid_t
3234
3235Change the owner and group id of path to the numeric uid and gid.
3236
3237This function will not follow symbolic links.
3238Equivalent to os.chown(path, uid, gid, follow_symlinks=False).
3239[clinic start generated code]*/
3240
Larry Hastings2f936352014-08-05 14:04:04 +10003241static PyObject *
3242os_lchown_impl(PyModuleDef *module, path_t *path, uid_t uid, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003243/*[clinic end generated code: output=bb0d2da1579ac275 input=b1c6014d563a7161]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003244{
Victor Stinner8c62be82010-05-06 00:08:46 +00003245 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00003246 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003247 res = lchown(path->narrow, uid, gid);
Victor Stinner8c62be82010-05-06 00:08:46 +00003248 Py_END_ALLOW_THREADS
Victor Stinner292c8352012-10-30 02:17:38 +01003249 if (res < 0) {
Larry Hastings2f936352014-08-05 14:04:04 +10003250 return path_error(path);
Victor Stinner292c8352012-10-30 02:17:38 +01003251 }
Larry Hastings2f936352014-08-05 14:04:04 +10003252 Py_RETURN_NONE;
Martin v. Löwis0cec0ff2002-07-28 16:33:45 +00003253}
3254#endif /* HAVE_LCHOWN */
3255
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003256
Barry Warsaw53699e91996-12-10 23:23:01 +00003257static PyObject *
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003258posix_getcwd(int use_bytes)
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003259{
Victor Stinner8c62be82010-05-06 00:08:46 +00003260 char buf[1026];
3261 char *res;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003262
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003263#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003264 if (!use_bytes) {
3265 wchar_t wbuf[1026];
3266 wchar_t *wbuf2 = wbuf;
3267 PyObject *resobj;
3268 DWORD len;
3269 Py_BEGIN_ALLOW_THREADS
Victor Stinner75875072013-11-24 19:23:25 +01003270 len = GetCurrentDirectoryW(Py_ARRAY_LENGTH(wbuf), wbuf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003271 /* If the buffer is large enough, len does not include the
3272 terminating \0. If the buffer is too small, len includes
3273 the space needed for the terminator. */
Victor Stinner75875072013-11-24 19:23:25 +01003274 if (len >= Py_ARRAY_LENGTH(wbuf)) {
Victor Stinnerb6404912013-07-07 16:21:41 +02003275 wbuf2 = PyMem_RawMalloc(len * sizeof(wchar_t));
Victor Stinner8c62be82010-05-06 00:08:46 +00003276 if (wbuf2)
3277 len = GetCurrentDirectoryW(len, wbuf2);
3278 }
3279 Py_END_ALLOW_THREADS
3280 if (!wbuf2) {
3281 PyErr_NoMemory();
3282 return NULL;
3283 }
3284 if (!len) {
Victor Stinnerb024e842012-10-31 22:24:06 +01003285 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003286 PyMem_RawFree(wbuf2);
Victor Stinnerb024e842012-10-31 22:24:06 +01003287 return PyErr_SetFromWindowsErr(0);
Victor Stinner8c62be82010-05-06 00:08:46 +00003288 }
3289 resobj = PyUnicode_FromWideChar(wbuf2, len);
Victor Stinnerb024e842012-10-31 22:24:06 +01003290 if (wbuf2 != wbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003291 PyMem_RawFree(wbuf2);
Victor Stinner8c62be82010-05-06 00:08:46 +00003292 return resobj;
3293 }
Victor Stinnerf7c5ae22011-11-16 23:43:07 +01003294
3295 if (win32_warn_bytes_api())
3296 return NULL;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003297#endif
3298
Victor Stinner8c62be82010-05-06 00:08:46 +00003299 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003300 res = getcwd(buf, sizeof buf);
Victor Stinner8c62be82010-05-06 00:08:46 +00003301 Py_END_ALLOW_THREADS
3302 if (res == NULL)
3303 return posix_error();
3304 if (use_bytes)
3305 return PyBytes_FromStringAndSize(buf, strlen(buf));
Victor Stinner97c18ab2010-05-07 16:34:53 +00003306 return PyUnicode_DecodeFSDefault(buf);
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003307}
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003308
Larry Hastings2f936352014-08-05 14:04:04 +10003309
3310/*[clinic input]
3311os.getcwd
3312
3313Return a unicode string representing the current working directory.
3314[clinic start generated code]*/
3315
Larry Hastings2f936352014-08-05 14:04:04 +10003316static PyObject *
3317os_getcwd_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003318/*[clinic end generated code: output=efe3a8c0121525ea input=f069211bb70e3d39]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003319{
3320 return posix_getcwd(0);
3321}
3322
Larry Hastings2f936352014-08-05 14:04:04 +10003323
3324/*[clinic input]
3325os.getcwdb
3326
3327Return a bytes string representing the current working directory.
3328[clinic start generated code]*/
3329
Larry Hastings2f936352014-08-05 14:04:04 +10003330static PyObject *
3331os_getcwdb_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003332/*[clinic end generated code: output=7fce42ee4b2a296a input=f6f6a378dad3d9cb]*/
Guido van Rossumf0af3e32008-10-02 18:55:37 +00003333{
3334 return posix_getcwd(1);
3335}
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003336
Larry Hastings2f936352014-08-05 14:04:04 +10003337
Larry Hastings9cf065c2012-06-22 16:30:09 -07003338#if ((!defined(HAVE_LINK)) && defined(MS_WINDOWS))
3339#define HAVE_LINK 1
3340#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003341
Guido van Rossumb6775db1994-08-01 11:34:53 +00003342#ifdef HAVE_LINK
Larry Hastings2f936352014-08-05 14:04:04 +10003343/*[clinic input]
3344
3345os.link
3346
3347 src : path_t
3348 dst : path_t
3349 *
3350 src_dir_fd : dir_fd = None
3351 dst_dir_fd : dir_fd = None
3352 follow_symlinks: bool = True
3353
3354Create a hard link to a file.
3355
3356If either src_dir_fd or dst_dir_fd is not None, it should be a file
3357 descriptor open to a directory, and the respective path string (src or dst)
3358 should be relative; the path will then be relative to that directory.
3359If follow_symlinks is False, and the last element of src is a symbolic
3360 link, link will create a link to the symbolic link itself instead of the
3361 file the link points to.
3362src_dir_fd, dst_dir_fd, and follow_symlinks may not be implemented on your
3363 platform. If they are unavailable, using them will raise a
3364 NotImplementedError.
3365[clinic start generated code]*/
3366
Larry Hastings2f936352014-08-05 14:04:04 +10003367static PyObject *
3368os_link_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003369/*[clinic end generated code: output=c0a9ded8111d2a79 input=b0095ebbcbaa7e04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003370{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003371#ifdef MS_WINDOWS
3372 BOOL result;
3373#else
3374 int result;
3375#endif
3376
Larry Hastings9cf065c2012-06-22 16:30:09 -07003377#ifndef HAVE_LINKAT
3378 if ((src_dir_fd != DEFAULT_DIR_FD) || (dst_dir_fd != DEFAULT_DIR_FD)) {
3379 argument_unavailable_error("link", "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10003380 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003381 }
3382#endif
3383
Larry Hastings2f936352014-08-05 14:04:04 +10003384 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003385 PyErr_SetString(PyExc_NotImplementedError,
3386 "link: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10003387 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003388 }
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003389
Brian Curtin1b9df392010-11-24 20:24:31 +00003390#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003391 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003392 if (src->wide)
3393 result = CreateHardLinkW(dst->wide, src->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003394 else
Larry Hastings2f936352014-08-05 14:04:04 +10003395 result = CreateHardLinkA(dst->narrow, src->narrow, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003396 Py_END_ALLOW_THREADS
Brian Curtin1b9df392010-11-24 20:24:31 +00003397
Larry Hastings2f936352014-08-05 14:04:04 +10003398 if (!result)
3399 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003400#else
3401 Py_BEGIN_ALLOW_THREADS
Larry Hastings67cbf7b2012-06-22 17:06:48 -07003402#ifdef HAVE_LINKAT
Larry Hastings9cf065c2012-06-22 16:30:09 -07003403 if ((src_dir_fd != DEFAULT_DIR_FD) ||
3404 (dst_dir_fd != DEFAULT_DIR_FD) ||
3405 (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10003406 result = linkat(src_dir_fd, src->narrow,
3407 dst_dir_fd, dst->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07003408 follow_symlinks ? AT_SYMLINK_FOLLOW : 0);
3409 else
3410#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003411 result = link(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003412 Py_END_ALLOW_THREADS
Brian Curtinfc889c42010-11-28 23:59:46 +00003413
Larry Hastings2f936352014-08-05 14:04:04 +10003414 if (result)
3415 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003416#endif
3417
Larry Hastings2f936352014-08-05 14:04:04 +10003418 Py_RETURN_NONE;
Brian Curtin1b9df392010-11-24 20:24:31 +00003419}
Larry Hastings9cf065c2012-06-22 16:30:09 -07003420#endif
3421
Brian Curtin1b9df392010-11-24 20:24:31 +00003422
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003423#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
Barry Warsaw53699e91996-12-10 23:23:01 +00003424static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003425_listdir_windows_no_opendir(path_t *path, PyObject *list)
Guido van Rossumb6775db1994-08-01 11:34:53 +00003426{
Larry Hastings9cf065c2012-06-22 16:30:09 -07003427 PyObject *v;
3428 HANDLE hFindFile = INVALID_HANDLE_VALUE;
3429 BOOL result;
3430 WIN32_FIND_DATA FileData;
Victor Stinner75875072013-11-24 19:23:25 +01003431 char namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
Larry Hastings9cf065c2012-06-22 16:30:09 -07003432 char *bufptr = namebuf;
3433 /* only claim to have space for MAX_PATH */
Victor Stinner75875072013-11-24 19:23:25 +01003434 Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003435 PyObject *po = NULL;
3436 wchar_t *wnamebuf = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003437
Gregory P. Smith40a21602013-03-20 20:52:50 -07003438 if (!path->narrow) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003439 WIN32_FIND_DATAW wFileData;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003440 wchar_t *po_wchars;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003441
Gregory P. Smith40a21602013-03-20 20:52:50 -07003442 if (!path->wide) { /* Default arg: "." */
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003443 po_wchars = L".";
3444 len = 1;
3445 } else {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003446 po_wchars = path->wide;
3447 len = wcslen(path->wide);
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003448 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003449 /* The +5 is so we can append "\\*.*\0" */
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003450 wnamebuf = PyMem_New(wchar_t, len + 5);
Victor Stinner8c62be82010-05-06 00:08:46 +00003451 if (!wnamebuf) {
3452 PyErr_NoMemory();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003453 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003454 }
Martin v. Löwisc9e1c7d2010-07-23 12:16:41 +00003455 wcscpy(wnamebuf, po_wchars);
Victor Stinner8c62be82010-05-06 00:08:46 +00003456 if (len > 0) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003457 wchar_t wch = wnamebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003458 if (wch != SEP && wch != ALTSEP && wch != L':')
3459 wnamebuf[len++] = SEP;
Victor Stinner8c62be82010-05-06 00:08:46 +00003460 wcscpy(wnamebuf + len, L"*.*");
3461 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003462 if ((list = PyList_New(0)) == NULL) {
3463 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003464 }
Antoine Pitroub73caab2010-08-09 23:39:31 +00003465 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003466 hFindFile = FindFirstFileW(wnamebuf, &wFileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003467 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003468 if (hFindFile == INVALID_HANDLE_VALUE) {
3469 int error = GetLastError();
Larry Hastings9cf065c2012-06-22 16:30:09 -07003470 if (error == ERROR_FILE_NOT_FOUND)
3471 goto exit;
3472 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003473 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003474 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003475 }
3476 do {
3477 /* Skip over . and .. */
3478 if (wcscmp(wFileData.cFileName, L".") != 0 &&
3479 wcscmp(wFileData.cFileName, L"..") != 0) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003480 v = PyUnicode_FromWideChar(wFileData.cFileName,
3481 wcslen(wFileData.cFileName));
Victor Stinner8c62be82010-05-06 00:08:46 +00003482 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003483 Py_DECREF(list);
3484 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003485 break;
3486 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003487 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003488 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003489 Py_DECREF(list);
3490 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003491 break;
3492 }
3493 Py_DECREF(v);
3494 }
3495 Py_BEGIN_ALLOW_THREADS
3496 result = FindNextFileW(hFindFile, &wFileData);
3497 Py_END_ALLOW_THREADS
3498 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3499 it got to the end of the directory. */
3500 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003501 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 } while (result == TRUE);
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +00003506
Larry Hastings9cf065c2012-06-22 16:30:09 -07003507 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003508 }
Gregory P. Smith40a21602013-03-20 20:52:50 -07003509 strcpy(namebuf, path->narrow);
3510 len = path->length;
Victor Stinner8c62be82010-05-06 00:08:46 +00003511 if (len > 0) {
3512 char ch = namebuf[len-1];
Tim Golden781bbeb2013-10-25 20:24:06 +01003513 if (ch != '\\' && ch != '/' && ch != ':')
3514 namebuf[len++] = '\\';
Victor Stinner8c62be82010-05-06 00:08:46 +00003515 strcpy(namebuf + len, "*.*");
3516 }
Guido van Rossumb6775db1994-08-01 11:34:53 +00003517
Larry Hastings9cf065c2012-06-22 16:30:09 -07003518 if ((list = PyList_New(0)) == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +00003519 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +00003520
Antoine Pitroub73caab2010-08-09 23:39:31 +00003521 Py_BEGIN_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003522 hFindFile = FindFirstFile(namebuf, &FileData);
Antoine Pitroub73caab2010-08-09 23:39:31 +00003523 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00003524 if (hFindFile == INVALID_HANDLE_VALUE) {
3525 int error = GetLastError();
3526 if (error == ERROR_FILE_NOT_FOUND)
Larry Hastings9cf065c2012-06-22 16:30:09 -07003527 goto exit;
3528 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003529 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003530 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003531 }
3532 do {
3533 /* Skip over . and .. */
3534 if (strcmp(FileData.cFileName, ".") != 0 &&
3535 strcmp(FileData.cFileName, "..") != 0) {
3536 v = PyBytes_FromString(FileData.cFileName);
3537 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003538 Py_DECREF(list);
3539 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003540 break;
3541 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003542 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003543 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003544 Py_DECREF(list);
3545 list = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003546 break;
3547 }
3548 Py_DECREF(v);
3549 }
3550 Py_BEGIN_ALLOW_THREADS
3551 result = FindNextFile(hFindFile, &FileData);
3552 Py_END_ALLOW_THREADS
3553 /* FindNextFile sets error to ERROR_NO_MORE_FILES if
3554 it got to the end of the directory. */
3555 if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003556 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003557 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003558 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003559 }
3560 } while (result == TRUE);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003561
Larry Hastings9cf065c2012-06-22 16:30:09 -07003562exit:
3563 if (hFindFile != INVALID_HANDLE_VALUE) {
3564 if (FindClose(hFindFile) == FALSE) {
3565 if (list != NULL) {
3566 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003567 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003568 }
3569 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003570 }
Victor Stinnerb6404912013-07-07 16:21:41 +02003571 PyMem_Free(wnamebuf);
Guido van Rossumb6775db1994-08-01 11:34:53 +00003572
Larry Hastings9cf065c2012-06-22 16:30:09 -07003573 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003574} /* end of _listdir_windows_no_opendir */
3575
3576#else /* thus POSIX, ie: not (MS_WINDOWS and not HAVE_OPENDIR) */
3577
3578static PyObject *
Gregory P. Smith40a21602013-03-20 20:52:50 -07003579_posix_listdir(path_t *path, PyObject *list)
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003580{
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003581 PyObject *v;
3582 DIR *dirp = NULL;
3583 struct dirent *ep;
3584 int return_str; /* if false, return bytes */
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003585#ifdef HAVE_FDOPENDIR
3586 int fd = -1;
3587#endif
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003588
Victor Stinner8c62be82010-05-06 00:08:46 +00003589 errno = 0;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003590#ifdef HAVE_FDOPENDIR
Gregory P. Smith40a21602013-03-20 20:52:50 -07003591 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003592 /* closedir() closes the FD, so we duplicate it */
Victor Stinnerdaf45552013-08-28 00:53:59 +02003593 fd = _Py_dup(path->fd);
Victor Stinnerf3266652013-12-19 13:24:49 +01003594 if (fd == -1)
3595 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07003596
Larry Hastingsfdaea062012-06-25 04:42:23 -07003597 return_str = 1;
3598
Larry Hastings9cf065c2012-06-22 16:30:09 -07003599 Py_BEGIN_ALLOW_THREADS
3600 dirp = fdopendir(fd);
3601 Py_END_ALLOW_THREADS
3602 }
3603 else
3604#endif
3605 {
Larry Hastingsfdaea062012-06-25 04:42:23 -07003606 char *name;
Gregory P. Smith40a21602013-03-20 20:52:50 -07003607 if (path->narrow) {
3608 name = path->narrow;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003609 /* only return bytes if they specified a bytes object */
Gregory P. Smith40a21602013-03-20 20:52:50 -07003610 return_str = !(PyBytes_Check(path->object));
Larry Hastingsfdaea062012-06-25 04:42:23 -07003611 }
3612 else {
3613 name = ".";
3614 return_str = 1;
3615 }
3616
Larry Hastings9cf065c2012-06-22 16:30:09 -07003617 Py_BEGIN_ALLOW_THREADS
3618 dirp = opendir(name);
3619 Py_END_ALLOW_THREADS
3620 }
3621
3622 if (dirp == NULL) {
Gregory P. Smith40a21602013-03-20 20:52:50 -07003623 list = path_error(path);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003624#ifdef HAVE_FDOPENDIR
3625 if (fd != -1) {
3626 Py_BEGIN_ALLOW_THREADS
3627 close(fd);
3628 Py_END_ALLOW_THREADS
3629 }
3630#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003631 goto exit;
3632 }
3633 if ((list = PyList_New(0)) == NULL) {
3634 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003635 }
3636 for (;;) {
3637 errno = 0;
3638 Py_BEGIN_ALLOW_THREADS
3639 ep = readdir(dirp);
3640 Py_END_ALLOW_THREADS
3641 if (ep == NULL) {
3642 if (errno == 0) {
3643 break;
3644 } else {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003645 Py_DECREF(list);
Gregory P. Smith40a21602013-03-20 20:52:50 -07003646 list = path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003647 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00003648 }
3649 }
3650 if (ep->d_name[0] == '.' &&
3651 (NAMLEN(ep) == 1 ||
3652 (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
3653 continue;
Larry Hastingsfdaea062012-06-25 04:42:23 -07003654 if (return_str)
Victor Stinnera45598a2010-05-14 16:35:39 +00003655 v = PyUnicode_DecodeFSDefaultAndSize(ep->d_name, NAMLEN(ep));
3656 else
3657 v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
Victor Stinner8c62be82010-05-06 00:08:46 +00003658 if (v == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07003659 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003660 break;
3661 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07003662 if (PyList_Append(list, v) != 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00003663 Py_DECREF(v);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003664 Py_CLEAR(list);
Victor Stinner8c62be82010-05-06 00:08:46 +00003665 break;
3666 }
3667 Py_DECREF(v);
3668 }
Guido van Rossum0ee42cd1991-04-08 21:01:03 +00003669
Larry Hastings9cf065c2012-06-22 16:30:09 -07003670exit:
3671 if (dirp != NULL) {
3672 Py_BEGIN_ALLOW_THREADS
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003673#ifdef HAVE_FDOPENDIR
Larry Hastings9cf065c2012-06-22 16:30:09 -07003674 if (fd > -1)
3675 rewinddir(dirp);
Larry Hastings4dbc95e2013-08-01 18:18:56 -07003676#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07003677 closedir(dirp);
3678 Py_END_ALLOW_THREADS
3679 }
3680
Larry Hastings9cf065c2012-06-22 16:30:09 -07003681 return list;
Gregory P. Smith16ea14a2013-03-20 18:51:33 -07003682} /* end of _posix_listdir */
3683#endif /* which OS */
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00003684
Larry Hastings2f936352014-08-05 14:04:04 +10003685
3686/*[clinic input]
3687os.listdir
3688
3689 path : path_t(nullable=True, allow_fd='PATH_HAVE_FDOPENDIR') = None
3690
3691Return a list containing the names of the files in the directory.
3692
3693path can be specified as either str or bytes. If path is bytes,
3694 the filenames returned will also be bytes; in all other circumstances
3695 the filenames returned will be str.
3696If path is None, uses the path='.'.
3697On some platforms, path may also be specified as an open file descriptor;\
3698 the file descriptor must refer to a directory.
3699 If this functionality is unavailable, using it raises NotImplementedError.
3700
3701The list is in arbitrary order. It does not include the special
3702entries '.' and '..' even if they are present in the directory.
3703
3704
3705[clinic start generated code]*/
3706
Larry Hastings2f936352014-08-05 14:04:04 +10003707static PyObject *
3708os_listdir_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003709/*[clinic end generated code: output=1fbe67c1f780c8b7 input=09e300416e3cd729]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003710{
3711#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
3712 return _listdir_windows_no_opendir(path, NULL);
3713#else
3714 return _posix_listdir(path, NULL);
3715#endif
3716}
3717
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003718#ifdef MS_WINDOWS
Mark Hammondef8b6542001-05-13 08:04:26 +00003719/* A helper function for abspath on win32 */
Larry Hastings2f936352014-08-05 14:04:04 +10003720/* AC 3.5: probably just convert to using path converter */
Mark Hammondef8b6542001-05-13 08:04:26 +00003721static PyObject *
3722posix__getfullpathname(PyObject *self, PyObject *args)
3723{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003724 const char *path;
Victor Stinner75875072013-11-24 19:23:25 +01003725 char outbuf[MAX_PATH];
Victor Stinner8c62be82010-05-06 00:08:46 +00003726 char *temp;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003727 PyObject *po;
3728
3729 if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po))
3730 {
3731 wchar_t *wpath;
Victor Stinner75875072013-11-24 19:23:25 +01003732 wchar_t woutbuf[MAX_PATH], *woutbufp = woutbuf;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003733 wchar_t *wtemp;
Victor Stinner8c62be82010-05-06 00:08:46 +00003734 DWORD result;
3735 PyObject *v;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003736
3737 wpath = PyUnicode_AsUnicode(po);
3738 if (wpath == NULL)
3739 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00003740 result = GetFullPathNameW(wpath,
Victor Stinner63941882011-09-29 00:42:28 +02003741 Py_ARRAY_LENGTH(woutbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003742 woutbuf, &wtemp);
Victor Stinner63941882011-09-29 00:42:28 +02003743 if (result > Py_ARRAY_LENGTH(woutbuf)) {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003744 woutbufp = PyMem_New(wchar_t, result);
Victor Stinner8c62be82010-05-06 00:08:46 +00003745 if (!woutbufp)
3746 return PyErr_NoMemory();
3747 result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
3748 }
3749 if (result)
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003750 v = PyUnicode_FromWideChar(woutbufp, wcslen(woutbufp));
Victor Stinner8c62be82010-05-06 00:08:46 +00003751 else
Victor Stinnereb5657a2011-09-30 01:44:27 +02003752 v = win32_error_object("GetFullPathNameW", po);
Victor Stinner8c62be82010-05-06 00:08:46 +00003753 if (woutbufp != woutbuf)
Victor Stinnerb6404912013-07-07 16:21:41 +02003754 PyMem_Free(woutbufp);
Victor Stinner8c62be82010-05-06 00:08:46 +00003755 return v;
3756 }
3757 /* Drop the argument parsing error as narrow strings
3758 are also valid. */
3759 PyErr_Clear();
Victor Stinnereb5657a2011-09-30 01:44:27 +02003760
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003761 if (!PyArg_ParseTuple (args, "y:_getfullpathname",
3762 &path))
Victor Stinner8c62be82010-05-06 00:08:46 +00003763 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003764 if (win32_warn_bytes_api())
3765 return NULL;
Victor Stinner63941882011-09-29 00:42:28 +02003766 if (!GetFullPathName(path, Py_ARRAY_LENGTH(outbuf),
Victor Stinner8c62be82010-05-06 00:08:46 +00003767 outbuf, &temp)) {
3768 win32_error("GetFullPathName", path);
Victor Stinner8c62be82010-05-06 00:08:46 +00003769 return NULL;
3770 }
Victor Stinner8c62be82010-05-06 00:08:46 +00003771 if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
3772 return PyUnicode_Decode(outbuf, strlen(outbuf),
3773 Py_FileSystemDefaultEncoding, NULL);
3774 }
3775 return PyBytes_FromString(outbuf);
Larry Hastings2f936352014-08-05 14:04:04 +10003776}
Brian Curtind40e6f72010-07-08 21:39:08 +00003777
Brian Curtind25aef52011-06-13 15:16:04 -05003778
Larry Hastings2f936352014-08-05 14:04:04 +10003779/*[clinic input]
3780os._getfinalpathname
Brian Curtinf5e76d02010-11-24 13:14:05 +00003781
Larry Hastings2f936352014-08-05 14:04:04 +10003782 path: unicode
3783 /
3784
3785A helper function for samepath on windows.
3786[clinic start generated code]*/
3787
Larry Hastings2f936352014-08-05 14:04:04 +10003788static PyObject *
3789os__getfinalpathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003790/*[clinic end generated code: output=8be81a5f51a34bcf input=71d5e89334891bf4]*/
Brian Curtind40e6f72010-07-08 21:39:08 +00003791{
3792 HANDLE hFile;
3793 int buf_size;
3794 wchar_t *target_path;
3795 int result_length;
Larry Hastings2f936352014-08-05 14:04:04 +10003796 PyObject *result;
3797 wchar_t *path_wchar;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003798
Larry Hastings2f936352014-08-05 14:04:04 +10003799 path_wchar = PyUnicode_AsUnicode(path);
3800 if (path_wchar == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02003801 return NULL;
Brian Curtind40e6f72010-07-08 21:39:08 +00003802
Brian Curtind40e6f72010-07-08 21:39:08 +00003803 hFile = CreateFileW(
Larry Hastings2f936352014-08-05 14:04:04 +10003804 path_wchar,
Brian Curtind40e6f72010-07-08 21:39:08 +00003805 0, /* desired access */
3806 0, /* share mode */
3807 NULL, /* security attributes */
3808 OPEN_EXISTING,
3809 /* FILE_FLAG_BACKUP_SEMANTICS is required to open a directory */
3810 FILE_FLAG_BACKUP_SEMANTICS,
3811 NULL);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00003812
Victor Stinnereb5657a2011-09-30 01:44:27 +02003813 if(hFile == INVALID_HANDLE_VALUE)
Larry Hastings2f936352014-08-05 14:04:04 +10003814 return win32_error_object("CreateFileW", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003815
3816 /* We have a good handle to the target, use it to determine the
3817 target path name. */
Steve Dower2ea51c92015-03-20 21:49:12 -07003818 buf_size = GetFinalPathNameByHandleW(hFile, 0, 0, VOLUME_NAME_NT);
Brian Curtind40e6f72010-07-08 21:39:08 +00003819
3820 if(!buf_size)
Larry Hastings2f936352014-08-05 14:04:04 +10003821 return win32_error_object("GetFinalPathNameByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003822
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003823 target_path = PyMem_New(wchar_t, buf_size+1);
Brian Curtind40e6f72010-07-08 21:39:08 +00003824 if(!target_path)
3825 return PyErr_NoMemory();
3826
Steve Dower2ea51c92015-03-20 21:49:12 -07003827 result_length = GetFinalPathNameByHandleW(hFile, target_path,
3828 buf_size, VOLUME_NAME_DOS);
Brian Curtind40e6f72010-07-08 21:39:08 +00003829 if(!result_length)
Larry Hastings2f936352014-08-05 14:04:04 +10003830 return win32_error_object("GetFinalPathNamyByHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003831
3832 if(!CloseHandle(hFile))
Larry Hastings2f936352014-08-05 14:04:04 +10003833 return win32_error_object("CloseHandle", path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003834
3835 target_path[result_length] = 0;
Victor Stinner9d3b93b2011-11-22 02:27:30 +01003836 result = PyUnicode_FromWideChar(target_path, result_length);
Victor Stinnerb6404912013-07-07 16:21:41 +02003837 PyMem_Free(target_path);
Brian Curtind40e6f72010-07-08 21:39:08 +00003838 return result;
Larry Hastings2f936352014-08-05 14:04:04 +10003839}
Brian Curtin62857742010-09-06 17:07:27 +00003840
Brian Curtin95d028f2011-06-09 09:10:38 -05003841PyDoc_STRVAR(posix__isdir__doc__,
3842"Return true if the pathname refers to an existing directory.");
3843
Larry Hastings2f936352014-08-05 14:04:04 +10003844/* AC 3.5: convert using path converter */
Brian Curtin9c669cc2011-06-08 18:17:18 -05003845static PyObject *
3846posix__isdir(PyObject *self, PyObject *args)
3847{
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003848 const char *path;
Victor Stinnereb5657a2011-09-30 01:44:27 +02003849 PyObject *po;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003850 DWORD attributes;
3851
3852 if (PyArg_ParseTuple(args, "U|:_isdir", &po)) {
Victor Stinnereb5657a2011-09-30 01:44:27 +02003853 wchar_t *wpath = PyUnicode_AsUnicode(po);
3854 if (wpath == NULL)
3855 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003856
3857 attributes = GetFileAttributesW(wpath);
3858 if (attributes == INVALID_FILE_ATTRIBUTES)
3859 Py_RETURN_FALSE;
3860 goto check;
3861 }
3862 /* Drop the argument parsing error as narrow strings
3863 are also valid. */
3864 PyErr_Clear();
3865
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003866 if (!PyArg_ParseTuple(args, "y:_isdir", &path))
Brian Curtin9c669cc2011-06-08 18:17:18 -05003867 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +01003868 if (win32_warn_bytes_api())
3869 return NULL;
Brian Curtin9c669cc2011-06-08 18:17:18 -05003870 attributes = GetFileAttributesA(path);
3871 if (attributes == INVALID_FILE_ATTRIBUTES)
3872 Py_RETURN_FALSE;
3873
3874check:
3875 if (attributes & FILE_ATTRIBUTE_DIRECTORY)
3876 Py_RETURN_TRUE;
3877 else
3878 Py_RETURN_FALSE;
3879}
Tim Golden6b528062013-08-01 12:44:00 +01003880
Tim Golden6b528062013-08-01 12:44:00 +01003881
Larry Hastings2f936352014-08-05 14:04:04 +10003882/*[clinic input]
3883os._getvolumepathname
3884
3885 path: unicode
3886
3887A helper function for ismount on Win32.
3888[clinic start generated code]*/
3889
Larry Hastings2f936352014-08-05 14:04:04 +10003890static PyObject *
3891os__getvolumepathname_impl(PyModuleDef *module, PyObject *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003892/*[clinic end generated code: output=79a0ba729f956dbe input=7eacadc40acbda6b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003893{
3894 PyObject *result;
3895 wchar_t *path_wchar, *mountpath=NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003896 size_t buflen;
Tim Golden6b528062013-08-01 12:44:00 +01003897 BOOL ret;
3898
Larry Hastings2f936352014-08-05 14:04:04 +10003899 path_wchar = PyUnicode_AsUnicodeAndSize(path, &buflen);
3900 if (path_wchar == NULL)
Tim Golden6b528062013-08-01 12:44:00 +01003901 return NULL;
Victor Stinner6edddfa2013-11-24 19:22:57 +01003902 buflen += 1;
Tim Golden6b528062013-08-01 12:44:00 +01003903
3904 /* Volume path should be shorter than entire path */
Victor Stinner6edddfa2013-11-24 19:22:57 +01003905 buflen = Py_MAX(buflen, MAX_PATH);
3906
3907 if (buflen > DWORD_MAX) {
3908 PyErr_SetString(PyExc_OverflowError, "path too long");
3909 return NULL;
3910 }
3911
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02003912 mountpath = PyMem_New(wchar_t, buflen);
Tim Golden6b528062013-08-01 12:44:00 +01003913 if (mountpath == NULL)
3914 return PyErr_NoMemory();
3915
3916 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003917 ret = GetVolumePathNameW(path_wchar, mountpath,
Victor Stinner6edddfa2013-11-24 19:22:57 +01003918 Py_SAFE_DOWNCAST(buflen, size_t, DWORD));
Tim Golden6b528062013-08-01 12:44:00 +01003919 Py_END_ALLOW_THREADS
3920
3921 if (!ret) {
Larry Hastings2f936352014-08-05 14:04:04 +10003922 result = win32_error_object("_getvolumepathname", path);
Tim Golden6b528062013-08-01 12:44:00 +01003923 goto exit;
3924 }
3925 result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
3926
3927exit:
3928 PyMem_Free(mountpath);
3929 return result;
3930}
Tim Golden6b528062013-08-01 12:44:00 +01003931
Martin v. Löwis6238d2b2002-06-30 15:26:10 +00003932#endif /* MS_WINDOWS */
Mark Hammondef8b6542001-05-13 08:04:26 +00003933
Larry Hastings2f936352014-08-05 14:04:04 +10003934
3935/*[clinic input]
3936os.mkdir
3937
3938 path : path_t
3939
3940 mode: int = 0o777
3941
3942 *
3943
3944 dir_fd : dir_fd(requires='mkdirat') = None
3945
3946# "mkdir(path, mode=0o777, *, dir_fd=None)\n\n\
3947
3948Create a directory.
3949
3950If dir_fd is not None, it should be a file descriptor open to a directory,
3951 and path should be relative; path will then be relative to that directory.
3952dir_fd may not be implemented on your platform.
3953 If it is unavailable, using it will raise a NotImplementedError.
3954
3955The mode argument is ignored on Windows.
3956[clinic start generated code]*/
3957
Larry Hastings2f936352014-08-05 14:04:04 +10003958static PyObject *
3959os_mkdir_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03003960/*[clinic end generated code: output=8bf1f738873ef2c5 input=e965f68377e9b1ce]*/
Larry Hastings2f936352014-08-05 14:04:04 +10003961{
3962 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003963
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00003964#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00003965 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003966 if (path->wide)
3967 result = CreateDirectoryW(path->wide, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003968 else
Larry Hastings2f936352014-08-05 14:04:04 +10003969 result = CreateDirectoryA(path->narrow, NULL);
Victor Stinner8c62be82010-05-06 00:08:46 +00003970 Py_END_ALLOW_THREADS
Mark Hammondc2e85bd2002-10-03 05:10:39 +00003971
Larry Hastings2f936352014-08-05 14:04:04 +10003972 if (!result)
3973 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003974#else
Victor Stinner8c62be82010-05-06 00:08:46 +00003975 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07003976#if HAVE_MKDIRAT
3977 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10003978 result = mkdirat(dir_fd, path->narrow, mode);
Larry Hastings9cf065c2012-06-22 16:30:09 -07003979 else
3980#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +00003981#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
Larry Hastings2f936352014-08-05 14:04:04 +10003982 result = mkdir(path->narrow);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003983#else
Larry Hastings2f936352014-08-05 14:04:04 +10003984 result = mkdir(path->narrow, mode);
Guido van Rossuma4916fa1996-05-23 22:58:55 +00003985#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00003986 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10003987 if (result < 0)
3988 return path_error(path);
Thomas Wouters477c8d52006-05-27 19:21:47 +00003989#endif
Larry Hastings2f936352014-08-05 14:04:04 +10003990 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00003991}
3992
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00003993
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003994/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
3995#if defined(HAVE_SYS_RESOURCE_H)
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003996#include <sys/resource.h>
3997#endif
Thomas Wouterse38b2f12001-07-11 22:35:31 +00003998
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00003999
4000#ifdef HAVE_NICE
Larry Hastings2f936352014-08-05 14:04:04 +10004001/*[clinic input]
4002os.nice
4003
4004 increment: int
4005 /
4006
4007Add increment to the priority of process and return the new priority.
4008[clinic start generated code]*/
4009
Larry Hastings2f936352014-08-05 14:04:04 +10004010static PyObject *
4011os_nice_impl(PyModuleDef *module, int increment)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004012/*[clinic end generated code: output=8870418a3fc07b51 input=864be2d402a21da2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004013{
4014 int value;
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004015
Victor Stinner8c62be82010-05-06 00:08:46 +00004016 /* There are two flavours of 'nice': one that returns the new
4017 priority (as required by almost all standards out there) and the
4018 Linux/FreeBSD/BSDI one, which returns '0' on success and advices
4019 the use of getpriority() to get the new priority.
Tim Peters5aa91602002-01-30 05:46:57 +00004020
Victor Stinner8c62be82010-05-06 00:08:46 +00004021 If we are of the nice family that returns the new priority, we
4022 need to clear errno before the call, and check if errno is filled
4023 before calling posix_error() on a returnvalue of -1, because the
4024 -1 may be the actual new priority! */
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004025
Victor Stinner8c62be82010-05-06 00:08:46 +00004026 errno = 0;
4027 value = nice(increment);
Thomas Wouterse38b2f12001-07-11 22:35:31 +00004028#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
Victor Stinner8c62be82010-05-06 00:08:46 +00004029 if (value == 0)
4030 value = getpriority(PRIO_PROCESS, 0);
Thomas Woutersc2c12dc2001-07-11 14:45:34 +00004031#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00004032 if (value == -1 && errno != 0)
4033 /* either nice() or getpriority() returned an error */
4034 return posix_error();
4035 return PyLong_FromLong((long) value);
Guido van Rossum775f4da1993-01-09 17:18:52 +00004036}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004037#endif /* HAVE_NICE */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004038
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004039
4040#ifdef HAVE_GETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004041/*[clinic input]
4042os.getpriority
4043
4044 which: int
4045 who: int
4046
4047Return program scheduling priority.
4048[clinic start generated code]*/
4049
Larry Hastings2f936352014-08-05 14:04:04 +10004050static PyObject *
4051os_getpriority_impl(PyModuleDef *module, int which, int who)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004052/*[clinic end generated code: output=4759937aa5b67ed6 input=9be615d40e2544ef]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004053{
4054 int retval;
4055
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004056 errno = 0;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004057 retval = getpriority(which, who);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004058 if (errno != 0)
4059 return posix_error();
4060 return PyLong_FromLong((long)retval);
4061}
4062#endif /* HAVE_GETPRIORITY */
4063
4064
4065#ifdef HAVE_SETPRIORITY
Larry Hastings2f936352014-08-05 14:04:04 +10004066/*[clinic input]
4067os.setpriority
4068
4069 which: int
4070 who: int
4071 priority: int
4072
4073Set program scheduling priority.
4074[clinic start generated code]*/
4075
Larry Hastings2f936352014-08-05 14:04:04 +10004076static PyObject *
4077os_setpriority_impl(PyModuleDef *module, int which, int who, int priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004078/*[clinic end generated code: output=6497d3301547e7d5 input=710ccbf65b9dc513]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004079{
4080 int retval;
4081
4082 retval = setpriority(which, who, priority);
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +00004083 if (retval == -1)
4084 return posix_error();
4085 Py_RETURN_NONE;
4086}
4087#endif /* HAVE_SETPRIORITY */
4088
4089
Barry Warsaw53699e91996-12-10 23:23:01 +00004090static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004091internal_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 +00004092{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004093 char *function_name = is_replace ? "replace" : "rename";
Larry Hastings9cf065c2012-06-22 16:30:09 -07004094 int dir_fd_specified;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004095
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004096#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00004097 BOOL result;
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004098 int flags = is_replace ? MOVEFILE_REPLACE_EXISTING : 0;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004099#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004100 int result;
Mark Hammondc2e85bd2002-10-03 05:10:39 +00004101#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004102
Larry Hastings9cf065c2012-06-22 16:30:09 -07004103 dir_fd_specified = (src_dir_fd != DEFAULT_DIR_FD) ||
4104 (dst_dir_fd != DEFAULT_DIR_FD);
4105#ifndef HAVE_RENAMEAT
4106 if (dir_fd_specified) {
4107 argument_unavailable_error(function_name, "src_dir_fd and dst_dir_fd");
Larry Hastings2f936352014-08-05 14:04:04 +10004108 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004109 }
4110#endif
4111
Larry Hastings2f936352014-08-05 14:04:04 +10004112 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004113 PyErr_Format(PyExc_ValueError,
4114 "%s: src and dst must be the same type", function_name);
Larry Hastings2f936352014-08-05 14:04:04 +10004115 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004116 }
4117
4118#ifdef MS_WINDOWS
4119 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004120 if (src->wide)
4121 result = MoveFileExW(src->wide, dst->wide, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004122 else
Larry Hastings2f936352014-08-05 14:04:04 +10004123 result = MoveFileExA(src->narrow, dst->narrow, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004124 Py_END_ALLOW_THREADS
4125
Larry Hastings2f936352014-08-05 14:04:04 +10004126 if (!result)
4127 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004128
4129#else
4130 Py_BEGIN_ALLOW_THREADS
4131#ifdef HAVE_RENAMEAT
4132 if (dir_fd_specified)
Larry Hastings2f936352014-08-05 14:04:04 +10004133 result = renameat(src_dir_fd, src->narrow, dst_dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004134 else
4135#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004136 result = rename(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004137 Py_END_ALLOW_THREADS
4138
Larry Hastings2f936352014-08-05 14:04:04 +10004139 if (result)
4140 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004141#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004142 Py_RETURN_NONE;
4143}
Larry Hastings9cf065c2012-06-22 16:30:09 -07004144
Larry Hastings2f936352014-08-05 14:04:04 +10004145
4146/*[clinic input]
4147os.rename
4148
4149 src : path_t
4150 dst : path_t
4151 *
4152 src_dir_fd : dir_fd = None
4153 dst_dir_fd : dir_fd = None
4154
4155Rename a file or directory.
4156
4157If either src_dir_fd or dst_dir_fd is not None, it should be a file
4158 descriptor open to a directory, and the respective path string (src or dst)
4159 should be relative; the path will then be relative to that directory.
4160src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4161 If they are unavailable, using them will raise a NotImplementedError.
4162[clinic start generated code]*/
4163
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004164static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10004165os_rename_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004166/*[clinic end generated code: output=1bb520bf2fad186d input=faa61c847912c850]*/
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004167{
Larry Hastings2f936352014-08-05 14:04:04 +10004168 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 0);
Antoine Pitrouf3b2d882012-01-30 22:08:52 +01004169}
4170
Larry Hastings2f936352014-08-05 14:04:04 +10004171
4172/*[clinic input]
4173os.replace = os.rename
4174
4175Rename a file or directory, overwriting the destination.
4176
4177If either src_dir_fd or dst_dir_fd is not None, it should be a file
4178 descriptor open to a directory, and the respective path string (src or dst)
4179 should be relative; the path will then be relative to that directory.
4180src_dir_fd and dst_dir_fd, may not be implemented on your platform.
4181 If they are unavailable, using them will raise a NotImplementedError."
4182[clinic start generated code]*/
4183
Larry Hastings2f936352014-08-05 14:04:04 +10004184static PyObject *
4185os_replace_impl(PyModuleDef *module, path_t *src, path_t *dst, int src_dir_fd, int dst_dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004186/*[clinic end generated code: output=aa9ddad55fdef8e3 input=25515dfb107c8421]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004187{
4188 return internal_rename(src, dst, src_dir_fd, dst_dir_fd, 1);
4189}
4190
4191
4192/*[clinic input]
4193os.rmdir
4194
4195 path: path_t
4196 *
4197 dir_fd: dir_fd(requires='unlinkat') = None
4198
4199Remove a directory.
4200
4201If dir_fd is not None, it should be a file descriptor open to a directory,
4202 and path should be relative; path will then be relative to that directory.
4203dir_fd may not be implemented on your platform.
4204 If it is unavailable, using it will raise a NotImplementedError.
4205[clinic start generated code]*/
4206
Larry Hastings2f936352014-08-05 14:04:04 +10004207static PyObject *
4208os_rmdir_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004209/*[clinic end generated code: output=cabadec80d5a77c7 input=38c8b375ca34a7e2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004210{
4211 int result;
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004212
4213 Py_BEGIN_ALLOW_THREADS
4214#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004215 if (path->wide)
4216 result = RemoveDirectoryW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004217 else
Larry Hastings2f936352014-08-05 14:04:04 +10004218 result = RemoveDirectoryA(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004219 result = !result; /* Windows, success=1, UNIX, success=0 */
4220#else
4221#ifdef HAVE_UNLINKAT
4222 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004223 result = unlinkat(dir_fd, path->narrow, AT_REMOVEDIR);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004224 else
4225#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004226 result = rmdir(path->narrow);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004227#endif
4228 Py_END_ALLOW_THREADS
4229
Larry Hastings2f936352014-08-05 14:04:04 +10004230 if (result)
4231 return path_error(path);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004232
Larry Hastings2f936352014-08-05 14:04:04 +10004233 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004234}
4235
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004236
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004237#ifdef HAVE_SYSTEM
Larry Hastings2f936352014-08-05 14:04:04 +10004238#ifdef MS_WINDOWS
4239/*[clinic input]
4240os.system -> long
4241
4242 command: Py_UNICODE
4243
4244Execute the command in a subshell.
4245[clinic start generated code]*/
4246
Larry Hastings2f936352014-08-05 14:04:04 +10004247static long
4248os_system_impl(PyModuleDef *module, Py_UNICODE *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004249/*[clinic end generated code: output=4c3bd5abcd9c29e7 input=303f5ce97df606b0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004250{
4251 long result;
Victor Stinner8c62be82010-05-06 00:08:46 +00004252 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004253 result = _wsystem(command);
Victor Stinner8c62be82010-05-06 00:08:46 +00004254 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004255 return result;
4256}
4257#else /* MS_WINDOWS */
4258/*[clinic input]
4259os.system -> long
4260
4261 command: FSConverter
4262
4263Execute the command in a subshell.
4264[clinic start generated code]*/
4265
Larry Hastings2f936352014-08-05 14:04:04 +10004266static long
4267os_system_impl(PyModuleDef *module, PyObject *command)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004268/*[clinic end generated code: output=800f775e10b7be55 input=86a58554ba6094af]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004269{
4270 long result;
4271 char *bytes = PyBytes_AsString(command);
4272 Py_BEGIN_ALLOW_THREADS
4273 result = system(bytes);
4274 Py_END_ALLOW_THREADS
4275 return result;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004276}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00004277#endif
Larry Hastings2f936352014-08-05 14:04:04 +10004278#endif /* HAVE_SYSTEM */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004279
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004280
Larry Hastings2f936352014-08-05 14:04:04 +10004281/*[clinic input]
4282os.umask
4283
4284 mask: int
4285 /
4286
4287Set the current numeric umask and return the previous umask.
4288[clinic start generated code]*/
4289
Larry Hastings2f936352014-08-05 14:04:04 +10004290static PyObject *
4291os_umask_impl(PyModuleDef *module, int mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004292/*[clinic end generated code: output=9e1fe3c9f14d6a05 input=ab6bfd9b24d8a7e8]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004293{
4294 int i = (int)umask(mask);
Victor Stinner8c62be82010-05-06 00:08:46 +00004295 if (i < 0)
4296 return posix_error();
4297 return PyLong_FromLong((long)i);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004298}
4299
Brian Curtind40e6f72010-07-08 21:39:08 +00004300#ifdef MS_WINDOWS
4301
4302/* override the default DeleteFileW behavior so that directory
4303symlinks can be removed with this function, the same as with
4304Unix symlinks */
4305BOOL WINAPI Py_DeleteFileW(LPCWSTR lpFileName)
4306{
4307 WIN32_FILE_ATTRIBUTE_DATA info;
4308 WIN32_FIND_DATAW find_data;
4309 HANDLE find_data_handle;
4310 int is_directory = 0;
4311 int is_link = 0;
4312
4313 if (GetFileAttributesExW(lpFileName, GetFileExInfoStandard, &info)) {
4314 is_directory = info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00004315
Brian Curtind40e6f72010-07-08 21:39:08 +00004316 /* Get WIN32_FIND_DATA structure for the path to determine if
4317 it is a symlink */
4318 if(is_directory &&
4319 info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
4320 find_data_handle = FindFirstFileW(lpFileName, &find_data);
4321
4322 if(find_data_handle != INVALID_HANDLE_VALUE) {
Tim Golden0321cf22014-05-05 19:46:17 +01004323 /* IO_REPARSE_TAG_SYMLINK if it is a symlink and
4324 IO_REPARSE_TAG_MOUNT_POINT if it is a junction point. */
4325 is_link = find_data.dwReserved0 == IO_REPARSE_TAG_SYMLINK ||
4326 find_data.dwReserved0 == IO_REPARSE_TAG_MOUNT_POINT;
Brian Curtind40e6f72010-07-08 21:39:08 +00004327 FindClose(find_data_handle);
4328 }
4329 }
4330 }
4331
4332 if (is_directory && is_link)
4333 return RemoveDirectoryW(lpFileName);
4334
4335 return DeleteFileW(lpFileName);
4336}
4337#endif /* MS_WINDOWS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004338
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004339
Larry Hastings2f936352014-08-05 14:04:04 +10004340/*[clinic input]
4341os.unlink
4342
4343 path: path_t
4344 *
4345 dir_fd: dir_fd(requires='unlinkat')=None
4346
4347Remove a file (same as remove()).
4348
4349If dir_fd is not None, it should be a file descriptor open to a directory,
4350 and path should be relative; path will then be relative to that directory.
4351dir_fd may not be implemented on your platform.
4352 If it is unavailable, using it will raise a NotImplementedError.
4353
4354[clinic start generated code]*/
4355
Larry Hastings2f936352014-08-05 14:04:04 +10004356static PyObject *
4357os_unlink_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004358/*[clinic end generated code: output=474afd5cd09b237e input=d7bcde2b1b2a2552]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004359{
4360 int result;
Larry Hastings9cf065c2012-06-22 16:30:09 -07004361
4362 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04004363 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004364#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10004365 if (path->wide)
4366 result = Py_DeleteFileW(path->wide);
Larry Hastingsb698d8e2012-06-23 16:55:07 -07004367 else
Larry Hastings2f936352014-08-05 14:04:04 +10004368 result = DeleteFileA(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004369 result = !result; /* Windows, success=1, UNIX, success=0 */
4370#else
Larry Hastings9cf065c2012-06-22 16:30:09 -07004371#ifdef HAVE_UNLINKAT
4372 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10004373 result = unlinkat(dir_fd, path->narrow, 0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004374 else
4375#endif /* HAVE_UNLINKAT */
Larry Hastings2f936352014-08-05 14:04:04 +10004376 result = unlink(path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004377#endif
Steve Dower8fc89802015-04-12 00:26:27 -04004378 _Py_END_SUPPRESS_IPH
Larry Hastings9cf065c2012-06-22 16:30:09 -07004379 Py_END_ALLOW_THREADS
4380
Larry Hastings2f936352014-08-05 14:04:04 +10004381 if (result)
4382 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004383
Larry Hastings2f936352014-08-05 14:04:04 +10004384 Py_RETURN_NONE;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004385}
4386
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004387
Larry Hastings2f936352014-08-05 14:04:04 +10004388/*[clinic input]
4389os.remove = os.unlink
4390
4391Remove a file (same as unlink()).
4392
4393If dir_fd is not None, it should be a file descriptor open to a directory,
4394 and path should be relative; path will then be relative to that directory.
4395dir_fd may not be implemented on your platform.
4396 If it is unavailable, using it will raise a NotImplementedError.
4397[clinic start generated code]*/
4398
Larry Hastings2f936352014-08-05 14:04:04 +10004399static PyObject *
4400os_remove_impl(PyModuleDef *module, path_t *path, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004401/*[clinic end generated code: output=d0d5149e64832b9e input=e05c5ab55cd30983]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004402{
4403 return os_unlink_impl(module, path, dir_fd);
4404}
4405
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004406
Larry Hastings605a62d2012-06-24 04:33:36 -07004407static PyStructSequence_Field uname_result_fields[] = {
4408 {"sysname", "operating system name"},
4409 {"nodename", "name of machine on network (implementation-defined)"},
4410 {"release", "operating system release"},
4411 {"version", "operating system version"},
4412 {"machine", "hardware identifier"},
4413 {NULL}
4414};
4415
4416PyDoc_STRVAR(uname_result__doc__,
4417"uname_result: Result from os.uname().\n\n\
4418This object may be accessed either as a tuple of\n\
4419 (sysname, nodename, release, version, machine),\n\
4420or via the attributes sysname, nodename, release, version, and machine.\n\
4421\n\
4422See os.uname for more information.");
4423
4424static PyStructSequence_Desc uname_result_desc = {
4425 "uname_result", /* name */
4426 uname_result__doc__, /* doc */
4427 uname_result_fields,
4428 5
4429};
4430
4431static PyTypeObject UnameResultType;
4432
4433
4434#ifdef HAVE_UNAME
Larry Hastings2f936352014-08-05 14:04:04 +10004435/*[clinic input]
4436os.uname
4437
4438Return an object identifying the current operating system.
4439
4440The object behaves like a named tuple with the following fields:
4441 (sysname, nodename, release, version, machine)
4442
4443[clinic start generated code]*/
4444
Larry Hastings2f936352014-08-05 14:04:04 +10004445static PyObject *
4446os_uname_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004447/*[clinic end generated code: output=01e1421b757e753f input=e68bd246db3043ed]*/
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004448{
Victor Stinner8c62be82010-05-06 00:08:46 +00004449 struct utsname u;
4450 int res;
Larry Hastings605a62d2012-06-24 04:33:36 -07004451 PyObject *value;
Neal Norwitze241ce82003-02-17 18:17:05 +00004452
Victor Stinner8c62be82010-05-06 00:08:46 +00004453 Py_BEGIN_ALLOW_THREADS
4454 res = uname(&u);
4455 Py_END_ALLOW_THREADS
4456 if (res < 0)
4457 return posix_error();
Larry Hastings605a62d2012-06-24 04:33:36 -07004458
4459 value = PyStructSequence_New(&UnameResultType);
4460 if (value == NULL)
4461 return NULL;
4462
4463#define SET(i, field) \
4464 { \
Victor Stinnera534fc42013-06-03 22:07:27 +02004465 PyObject *o = PyUnicode_DecodeFSDefault(field); \
Larry Hastings605a62d2012-06-24 04:33:36 -07004466 if (!o) { \
4467 Py_DECREF(value); \
4468 return NULL; \
4469 } \
4470 PyStructSequence_SET_ITEM(value, i, o); \
4471 } \
4472
4473 SET(0, u.sysname);
4474 SET(1, u.nodename);
4475 SET(2, u.release);
4476 SET(3, u.version);
4477 SET(4, u.machine);
4478
4479#undef SET
4480
4481 return value;
Guido van Rossumc39de5f1992-02-05 11:15:54 +00004482}
Guido van Rossumb6775db1994-08-01 11:34:53 +00004483#endif /* HAVE_UNAME */
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004484
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004485
Larry Hastings9cf065c2012-06-22 16:30:09 -07004486
4487typedef struct {
4488 int now;
4489 time_t atime_s;
4490 long atime_ns;
4491 time_t mtime_s;
4492 long mtime_ns;
4493} utime_t;
4494
4495/*
Victor Stinner484df002014-10-09 13:52:31 +02004496 * these macros assume that "ut" is a pointer to a utime_t
Larry Hastings9cf065c2012-06-22 16:30:09 -07004497 * they also intentionally leak the declaration of a pointer named "time"
4498 */
4499#define UTIME_TO_TIMESPEC \
4500 struct timespec ts[2]; \
4501 struct timespec *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004502 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004503 time = NULL; \
4504 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004505 ts[0].tv_sec = ut->atime_s; \
4506 ts[0].tv_nsec = ut->atime_ns; \
4507 ts[1].tv_sec = ut->mtime_s; \
4508 ts[1].tv_nsec = ut->mtime_ns; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004509 time = ts; \
4510 } \
4511
4512#define UTIME_TO_TIMEVAL \
4513 struct timeval tv[2]; \
4514 struct timeval *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 tv[0].tv_sec = ut->atime_s; \
4519 tv[0].tv_usec = ut->atime_ns / 1000; \
4520 tv[1].tv_sec = ut->mtime_s; \
4521 tv[1].tv_usec = ut->mtime_ns / 1000; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004522 time = tv; \
4523 } \
4524
4525#define UTIME_TO_UTIMBUF \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004526 struct utimbuf u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004527 struct utimbuf *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004528 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004529 time = NULL; \
4530 else { \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004531 u.actime = ut->atime_s; \
4532 u.modtime = ut->mtime_s; \
4533 time = &u; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004534 }
4535
4536#define UTIME_TO_TIME_T \
4537 time_t timet[2]; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004538 time_t *time; \
Victor Stinner484df002014-10-09 13:52:31 +02004539 if (ut->now) \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004540 time = NULL; \
4541 else { \
Victor Stinner484df002014-10-09 13:52:31 +02004542 timet[0] = ut->atime_s; \
4543 timet[1] = ut->mtime_s; \
Georg Brandle1a7d9d2014-10-12 08:45:15 +02004544 time = timet; \
Larry Hastings9cf065c2012-06-22 16:30:09 -07004545 } \
4546
4547
4548#define UTIME_HAVE_DIR_FD (defined(HAVE_FUTIMESAT) || defined(HAVE_UTIMENSAT))
4549
4550#if UTIME_HAVE_DIR_FD
4551
4552static int
Victor Stinner484df002014-10-09 13:52:31 +02004553utime_dir_fd(utime_t *ut, int dir_fd, char *path, int follow_symlinks)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004554{
4555#ifdef HAVE_UTIMENSAT
4556 int flags = follow_symlinks ? 0 : AT_SYMLINK_NOFOLLOW;
4557 UTIME_TO_TIMESPEC;
4558 return utimensat(dir_fd, path, time, flags);
4559#elif defined(HAVE_FUTIMESAT)
4560 UTIME_TO_TIMEVAL;
4561 /*
4562 * follow_symlinks will never be false here;
4563 * we only allow !follow_symlinks and dir_fd together
4564 * if we have utimensat()
4565 */
4566 assert(follow_symlinks);
4567 return futimesat(dir_fd, path, time);
4568#endif
4569}
4570
Larry Hastings2f936352014-08-05 14:04:04 +10004571 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_converter
4572#else
4573 #define FUTIMENSAT_DIR_FD_CONVERTER dir_fd_unavailable
Larry Hastings9cf065c2012-06-22 16:30:09 -07004574#endif
4575
4576#define UTIME_HAVE_FD (defined(HAVE_FUTIMES) || defined(HAVE_FUTIMENS))
4577
4578#if UTIME_HAVE_FD
4579
4580static int
Victor Stinner484df002014-10-09 13:52:31 +02004581utime_fd(utime_t *ut, int fd)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004582{
4583#ifdef HAVE_FUTIMENS
4584 UTIME_TO_TIMESPEC;
4585 return futimens(fd, time);
4586#else
4587 UTIME_TO_TIMEVAL;
4588 return futimes(fd, time);
4589#endif
4590}
4591
Larry Hastings2f936352014-08-05 14:04:04 +10004592 #define PATH_UTIME_HAVE_FD 1
4593#else
4594 #define PATH_UTIME_HAVE_FD 0
Larry Hastings9cf065c2012-06-22 16:30:09 -07004595#endif
4596
4597
4598#define UTIME_HAVE_NOFOLLOW_SYMLINKS \
4599 (defined(HAVE_UTIMENSAT) || defined(HAVE_LUTIMES))
4600
4601#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4602
4603static int
Victor Stinner484df002014-10-09 13:52:31 +02004604utime_nofollow_symlinks(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004605{
4606#ifdef HAVE_UTIMENSAT
4607 UTIME_TO_TIMESPEC;
4608 return utimensat(DEFAULT_DIR_FD, path, time, AT_SYMLINK_NOFOLLOW);
4609#else
4610 UTIME_TO_TIMEVAL;
4611 return lutimes(path, time);
4612#endif
4613}
4614
4615#endif
4616
4617#ifndef MS_WINDOWS
4618
4619static int
Victor Stinner484df002014-10-09 13:52:31 +02004620utime_default(utime_t *ut, char *path)
Larry Hastings9cf065c2012-06-22 16:30:09 -07004621{
4622#ifdef HAVE_UTIMENSAT
4623 UTIME_TO_TIMESPEC;
4624 return utimensat(DEFAULT_DIR_FD, path, time, 0);
4625#elif defined(HAVE_UTIMES)
4626 UTIME_TO_TIMEVAL;
4627 return utimes(path, time);
4628#elif defined(HAVE_UTIME_H)
4629 UTIME_TO_UTIMBUF;
4630 return utime(path, time);
4631#else
4632 UTIME_TO_TIME_T;
4633 return utime(path, time);
4634#endif
4635}
4636
4637#endif
4638
Larry Hastings76ad59b2012-05-03 00:30:07 -07004639static int
4640split_py_long_to_s_and_ns(PyObject *py_long, time_t *s, long *ns)
4641{
4642 int result = 0;
Benjamin Petersonfbd85a02012-05-04 11:06:09 -04004643 PyObject *divmod;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004644 divmod = PyNumber_Divmod(py_long, billion);
4645 if (!divmod)
4646 goto exit;
4647 *s = _PyLong_AsTime_t(PyTuple_GET_ITEM(divmod, 0));
4648 if ((*s == -1) && PyErr_Occurred())
4649 goto exit;
4650 *ns = PyLong_AsLong(PyTuple_GET_ITEM(divmod, 1));
Benjamin Peterson35a8f0d2012-05-04 01:10:59 -04004651 if ((*ns == -1) && PyErr_Occurred())
Larry Hastings76ad59b2012-05-03 00:30:07 -07004652 goto exit;
4653
4654 result = 1;
4655exit:
4656 Py_XDECREF(divmod);
4657 return result;
4658}
4659
Larry Hastings2f936352014-08-05 14:04:04 +10004660
4661/*[clinic input]
4662os.utime
4663
4664 path: path_t(allow_fd='PATH_UTIME_HAVE_FD')
4665 times: object = NULL
4666 *
4667 ns: object = NULL
4668 dir_fd: dir_fd(requires='futimensat') = None
4669 follow_symlinks: bool=True
4670
4671# "utime(path, times=None, *, ns=None, dir_fd=None, follow_symlinks=True)\n\
4672
4673Set the access and modified time of path.
4674
4675path may always be specified as a string.
4676On some platforms, path may also be specified as an open file descriptor.
4677 If this functionality is unavailable, using it raises an exception.
4678
4679If times is not None, it must be a tuple (atime, mtime);
4680 atime and mtime should be expressed as float seconds since the epoch.
4681If ns is not None, it must be a tuple (atime_ns, mtime_ns);
4682 atime_ns and mtime_ns should be expressed as integer nanoseconds
4683 since the epoch.
4684If both times and ns are None, utime uses the current time.
4685Specifying tuples for both times and ns is an error.
4686
4687If dir_fd is not None, it should be a file descriptor open to a directory,
4688 and path should be relative; path will then be relative to that directory.
4689If follow_symlinks is False, and the last element of the path is a symbolic
4690 link, utime will modify the symbolic link itself instead of the file the
4691 link points to.
4692It is an error to use dir_fd or follow_symlinks when specifying path
4693 as an open file descriptor.
4694dir_fd and follow_symlinks may not be available on your platform.
4695 If they are unavailable, using them will raise a NotImplementedError.
4696
4697[clinic start generated code]*/
4698
Larry Hastings2f936352014-08-05 14:04:04 +10004699static PyObject *
4700os_utime_impl(PyModuleDef *module, path_t *path, PyObject *times, PyObject *ns, int dir_fd, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004701/*[clinic end generated code: output=c52d8fd0d1067f0b input=1f18c17d5941aa82]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004702{
Larry Hastings9cf065c2012-06-22 16:30:09 -07004703#ifdef MS_WINDOWS
4704 HANDLE hFile;
4705 FILETIME atime, mtime;
4706#else
4707 int result;
4708#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004709
Larry Hastings9cf065c2012-06-22 16:30:09 -07004710 PyObject *return_value = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10004711 utime_t utime;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004712
Christian Heimesb3c87242013-08-01 00:08:16 +02004713 memset(&utime, 0, sizeof(utime_t));
Larry Hastings76ad59b2012-05-03 00:30:07 -07004714
Larry Hastings9cf065c2012-06-22 16:30:09 -07004715 if (times && (times != Py_None) && ns) {
4716 PyErr_SetString(PyExc_ValueError,
4717 "utime: you may specify either 'times'"
4718 " or 'ns' but not both");
4719 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004720 }
4721
4722 if (times && (times != Py_None)) {
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004723 time_t a_sec, m_sec;
4724 long a_nsec, m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004725 if (!PyTuple_CheckExact(times) || (PyTuple_Size(times) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004726 PyErr_SetString(PyExc_TypeError,
4727 "utime: 'times' must be either"
4728 " a tuple of two ints or None");
4729 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004730 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004731 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004732 if (_PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 0),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004733 &a_sec, &a_nsec, _PyTime_ROUND_FLOOR) == -1 ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004734 _PyTime_ObjectToTimespec(PyTuple_GET_ITEM(times, 1),
Victor Stinnerdca028b2015-03-30 01:02:57 +02004735 &m_sec, &m_nsec, _PyTime_ROUND_FLOOR) == -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004736 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004737 }
Antoine Pitroucf8a1e52013-04-17 22:06:44 +02004738 utime.atime_s = a_sec;
4739 utime.atime_ns = a_nsec;
4740 utime.mtime_s = m_sec;
4741 utime.mtime_ns = m_nsec;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004742 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004743 else if (ns) {
Larry Hastings76ad59b2012-05-03 00:30:07 -07004744 if (!PyTuple_CheckExact(ns) || (PyTuple_Size(ns) != 2)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07004745 PyErr_SetString(PyExc_TypeError,
4746 "utime: 'ns' must be a tuple of two ints");
4747 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004748 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004749 utime.now = 0;
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004750 if (!split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 0),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004751 &utime.atime_s, &utime.atime_ns) ||
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004752 !split_py_long_to_s_and_ns(PyTuple_GET_ITEM(ns, 1),
Larry Hastings9cf065c2012-06-22 16:30:09 -07004753 &utime.mtime_s, &utime.mtime_ns)) {
4754 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004755 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07004756 }
4757 else {
4758 /* times and ns are both None/unspecified. use "now". */
4759 utime.now = 1;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004760 }
4761
Larry Hastings9cf065c2012-06-22 16:30:09 -07004762#if !UTIME_HAVE_NOFOLLOW_SYMLINKS
4763 if (follow_symlinks_specified("utime", follow_symlinks))
4764 goto exit;
4765#endif
Benjamin Petersonb399ab22012-05-04 01:31:13 -04004766
Larry Hastings2f936352014-08-05 14:04:04 +10004767 if (path_and_dir_fd_invalid("utime", path, dir_fd) ||
4768 dir_fd_and_fd_invalid("utime", dir_fd, path->fd) ||
4769 fd_and_follow_symlinks_invalid("utime", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -07004770 goto exit;
Larry Hastings76ad59b2012-05-03 00:30:07 -07004771
Larry Hastings9cf065c2012-06-22 16:30:09 -07004772#if !defined(HAVE_UTIMENSAT)
4773 if ((dir_fd != DEFAULT_DIR_FD) && (!follow_symlinks)) {
Georg Brandl969288e2012-06-26 09:25:44 +02004774 PyErr_SetString(PyExc_ValueError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07004775 "utime: cannot use dir_fd and follow_symlinks "
4776 "together on this platform");
4777 goto exit;
4778 }
4779#endif
Larry Hastings76ad59b2012-05-03 00:30:07 -07004780
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004781#ifdef MS_WINDOWS
Larry Hastings9cf065c2012-06-22 16:30:09 -07004782 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10004783 if (path->wide)
4784 hFile = CreateFileW(path->wide, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004785 NULL, OPEN_EXISTING,
4786 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004787 else
Larry Hastings2f936352014-08-05 14:04:04 +10004788 hFile = CreateFileA(path->narrow, FILE_WRITE_ATTRIBUTES, 0,
Victor Stinner8c62be82010-05-06 00:08:46 +00004789 NULL, OPEN_EXISTING,
4790 FILE_FLAG_BACKUP_SEMANTICS, NULL);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004791 Py_END_ALLOW_THREADS
4792 if (hFile == INVALID_HANDLE_VALUE) {
Larry Hastings2f936352014-08-05 14:04:04 +10004793 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004794 goto exit;
Larry Hastingsb3336402012-05-04 02:31:57 -07004795 }
4796
Larry Hastings9cf065c2012-06-22 16:30:09 -07004797 if (utime.now) {
Antoine Pitrou91a7af32013-11-23 15:23:26 +01004798 GetSystemTimeAsFileTime(&mtime);
4799 atime = mtime;
Victor Stinner8c62be82010-05-06 00:08:46 +00004800 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004801 else {
Steve Dowerbf1f3762015-02-21 15:26:02 -08004802 _Py_time_t_to_FILE_TIME(utime.atime_s, utime.atime_ns, &atime);
4803 _Py_time_t_to_FILE_TIME(utime.mtime_s, utime.mtime_ns, &mtime);
Victor Stinner8c62be82010-05-06 00:08:46 +00004804 }
4805 if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
4806 /* Avoid putting the file name into the error here,
4807 as that may confuse the user into believing that
4808 something is wrong with the file, when it also
4809 could be the time stamp that gives a problem. */
Victor Stinnerb024e842012-10-31 22:24:06 +01004810 PyErr_SetFromWindowsErr(0);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004811 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004812 }
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004813#else /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004814 Py_BEGIN_ALLOW_THREADS
Guido van Rossum1ff6cb41991-04-08 20:59:13 +00004815
Larry Hastings9cf065c2012-06-22 16:30:09 -07004816#if UTIME_HAVE_NOFOLLOW_SYMLINKS
4817 if ((!follow_symlinks) && (dir_fd == DEFAULT_DIR_FD))
Larry Hastings2f936352014-08-05 14:04:04 +10004818 result = utime_nofollow_symlinks(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004819 else
Larry Hastings9e3e70b2011-09-08 19:29:07 -07004820#endif
Larry Hastings9cf065c2012-06-22 16:30:09 -07004821
4822#if UTIME_HAVE_DIR_FD
4823 if ((dir_fd != DEFAULT_DIR_FD) || (!follow_symlinks))
Larry Hastings2f936352014-08-05 14:04:04 +10004824 result = utime_dir_fd(&utime, dir_fd, path->narrow, follow_symlinks);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004825 else
4826#endif
4827
4828#if UTIME_HAVE_FD
Larry Hastings2f936352014-08-05 14:04:04 +10004829 if (path->fd != -1)
4830 result = utime_fd(&utime, path->fd);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004831 else
4832#endif
4833
Larry Hastings2f936352014-08-05 14:04:04 +10004834 result = utime_default(&utime, path->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07004835
4836 Py_END_ALLOW_THREADS
4837
4838 if (result < 0) {
4839 /* see previous comment about not putting filename in error here */
4840 return_value = posix_error();
4841 goto exit;
Victor Stinner8c62be82010-05-06 00:08:46 +00004842 }
Larry Hastings76ad59b2012-05-03 00:30:07 -07004843
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +00004844#endif /* MS_WINDOWS */
Larry Hastings9cf065c2012-06-22 16:30:09 -07004845
4846 Py_INCREF(Py_None);
4847 return_value = Py_None;
4848
4849exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -07004850#ifdef MS_WINDOWS
4851 if (hFile != INVALID_HANDLE_VALUE)
4852 CloseHandle(hFile);
4853#endif
4854 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00004855}
4856
Guido van Rossum3b066191991-06-04 19:40:25 +00004857/* Process operations */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004858
Larry Hastings2f936352014-08-05 14:04:04 +10004859
4860/*[clinic input]
4861os._exit
4862
4863 status: int
4864
4865Exit to the system with specified status, without normal exit processing.
4866[clinic start generated code]*/
4867
Larry Hastings2f936352014-08-05 14:04:04 +10004868static PyObject *
4869os__exit_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03004870/*[clinic end generated code: output=472a3cbaf68f3621 input=5e6d57556b0c4a62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10004871{
4872 _exit(status);
Victor Stinner8c62be82010-05-06 00:08:46 +00004873 return NULL; /* Make gcc -Wall happy */
Guido van Rossum85e3b011991-06-03 12:42:10 +00004874}
4875
Martin v. Löwis114619e2002-10-07 06:44:21 +00004876#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
4877static void
Martin v. Löwis725507b2006-03-07 12:08:51 +00004878free_string_array(char **array, Py_ssize_t count)
Martin v. Löwis114619e2002-10-07 06:44:21 +00004879{
Victor Stinner8c62be82010-05-06 00:08:46 +00004880 Py_ssize_t i;
4881 for (i = 0; i < count; i++)
4882 PyMem_Free(array[i]);
4883 PyMem_DEL(array);
Martin v. Löwis114619e2002-10-07 06:44:21 +00004884}
Martin v. Löwis011e8422009-05-05 04:43:17 +00004885
Antoine Pitrou69f71142009-05-24 21:25:49 +00004886static
Martin v. Löwis011e8422009-05-05 04:43:17 +00004887int fsconvert_strdup(PyObject *o, char**out)
4888{
Victor Stinner8c62be82010-05-06 00:08:46 +00004889 PyObject *bytes;
4890 Py_ssize_t size;
4891 if (!PyUnicode_FSConverter(o, &bytes))
4892 return 0;
4893 size = PyBytes_GET_SIZE(bytes);
4894 *out = PyMem_Malloc(size+1);
Victor Stinner50abf222013-11-07 23:56:10 +01004895 if (!*out) {
4896 PyErr_NoMemory();
Victor Stinner8c62be82010-05-06 00:08:46 +00004897 return 0;
Victor Stinner50abf222013-11-07 23:56:10 +01004898 }
Victor Stinner8c62be82010-05-06 00:08:46 +00004899 memcpy(*out, PyBytes_AsString(bytes), size+1);
4900 Py_DECREF(bytes);
4901 return 1;
Martin v. Löwis011e8422009-05-05 04:43:17 +00004902}
Martin v. Löwis114619e2002-10-07 06:44:21 +00004903#endif
4904
Ross Lagerwall7807c352011-03-17 20:20:30 +02004905#if defined(HAVE_EXECV) || defined (HAVE_FEXECVE)
Victor Stinner13bb71c2010-04-23 21:41:56 +00004906static char**
4907parse_envlist(PyObject* env, Py_ssize_t *envc_ptr)
4908{
Victor Stinner8c62be82010-05-06 00:08:46 +00004909 char **envlist;
4910 Py_ssize_t i, pos, envc;
4911 PyObject *keys=NULL, *vals=NULL;
4912 PyObject *key, *val, *key2, *val2;
4913 char *p, *k, *v;
4914 size_t len;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004915
Victor Stinner8c62be82010-05-06 00:08:46 +00004916 i = PyMapping_Size(env);
4917 if (i < 0)
4918 return NULL;
4919 envlist = PyMem_NEW(char *, i + 1);
4920 if (envlist == NULL) {
4921 PyErr_NoMemory();
4922 return NULL;
4923 }
4924 envc = 0;
4925 keys = PyMapping_Keys(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004926 if (!keys)
4927 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00004928 vals = PyMapping_Values(env);
Victor Stinnerb0314272013-11-14 21:37:05 +01004929 if (!vals)
Victor Stinner8c62be82010-05-06 00:08:46 +00004930 goto error;
4931 if (!PyList_Check(keys) || !PyList_Check(vals)) {
4932 PyErr_Format(PyExc_TypeError,
4933 "env.keys() or env.values() is not a list");
4934 goto error;
4935 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004936
Victor Stinner8c62be82010-05-06 00:08:46 +00004937 for (pos = 0; pos < i; pos++) {
4938 key = PyList_GetItem(keys, pos);
4939 val = PyList_GetItem(vals, pos);
4940 if (!key || !val)
4941 goto error;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004942
Victor Stinner8c62be82010-05-06 00:08:46 +00004943 if (PyUnicode_FSConverter(key, &key2) == 0)
4944 goto error;
4945 if (PyUnicode_FSConverter(val, &val2) == 0) {
4946 Py_DECREF(key2);
4947 goto error;
4948 }
Victor Stinner13bb71c2010-04-23 21:41:56 +00004949
Victor Stinner8c62be82010-05-06 00:08:46 +00004950 k = PyBytes_AsString(key2);
4951 v = PyBytes_AsString(val2);
4952 len = PyBytes_GET_SIZE(key2) + PyBytes_GET_SIZE(val2) + 2;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004953
Victor Stinner8c62be82010-05-06 00:08:46 +00004954 p = PyMem_NEW(char, len);
4955 if (p == NULL) {
4956 PyErr_NoMemory();
4957 Py_DECREF(key2);
4958 Py_DECREF(val2);
4959 goto error;
4960 }
4961 PyOS_snprintf(p, len, "%s=%s", k, v);
4962 envlist[envc++] = p;
4963 Py_DECREF(key2);
4964 Py_DECREF(val2);
Victor Stinner8c62be82010-05-06 00:08:46 +00004965 }
4966 Py_DECREF(vals);
4967 Py_DECREF(keys);
Victor Stinner13bb71c2010-04-23 21:41:56 +00004968
Victor Stinner8c62be82010-05-06 00:08:46 +00004969 envlist[envc] = 0;
4970 *envc_ptr = envc;
4971 return envlist;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004972
4973error:
Victor Stinner8c62be82010-05-06 00:08:46 +00004974 Py_XDECREF(keys);
4975 Py_XDECREF(vals);
4976 while (--envc >= 0)
4977 PyMem_DEL(envlist[envc]);
4978 PyMem_DEL(envlist);
4979 return NULL;
Victor Stinner13bb71c2010-04-23 21:41:56 +00004980}
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00004981
Ross Lagerwall7807c352011-03-17 20:20:30 +02004982static char**
4983parse_arglist(PyObject* argv, Py_ssize_t *argc)
4984{
4985 int i;
4986 char **argvlist = PyMem_NEW(char *, *argc+1);
4987 if (argvlist == NULL) {
4988 PyErr_NoMemory();
4989 return NULL;
4990 }
4991 for (i = 0; i < *argc; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004992 PyObject* item = PySequence_ITEM(argv, i);
4993 if (item == NULL)
4994 goto fail;
4995 if (!fsconvert_strdup(item, &argvlist[i])) {
4996 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02004997 goto fail;
4998 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02004999 Py_DECREF(item);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005000 }
5001 argvlist[*argc] = NULL;
5002 return argvlist;
5003fail:
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02005004 *argc = i;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005005 free_string_array(argvlist, *argc);
5006 return NULL;
5007}
5008#endif
5009
Larry Hastings2f936352014-08-05 14:04:04 +10005010
Ross Lagerwall7807c352011-03-17 20:20:30 +02005011#ifdef HAVE_EXECV
Larry Hastings2f936352014-08-05 14:04:04 +10005012/*[clinic input]
5013os.execv
5014
5015 path: FSConverter
5016 Path of executable file.
5017 argv: object
5018 Tuple or list of strings.
5019 /
5020
5021Execute an executable path with arguments, replacing current process.
5022[clinic start generated code]*/
5023
Larry Hastings2f936352014-08-05 14:04:04 +10005024static PyObject *
5025os_execv_impl(PyModuleDef *module, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005026/*[clinic end generated code: output=9221f08143146fff input=96041559925e5229]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005027{
5028 char *path_char;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005029 char **argvlist;
5030 Py_ssize_t argc;
5031
5032 /* execv has two arguments: (path, argv), where
5033 argv is a list or tuple of strings. */
5034
Larry Hastings2f936352014-08-05 14:04:04 +10005035 path_char = PyBytes_AsString(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005036 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
5037 PyErr_SetString(PyExc_TypeError,
5038 "execv() arg 2 must be a tuple or list");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005039 return NULL;
5040 }
5041 argc = PySequence_Size(argv);
5042 if (argc < 1) {
5043 PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
Ross Lagerwall7807c352011-03-17 20:20:30 +02005044 return NULL;
5045 }
5046
5047 argvlist = parse_arglist(argv, &argc);
5048 if (argvlist == NULL) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02005049 return NULL;
5050 }
5051
Larry Hastings2f936352014-08-05 14:04:04 +10005052 execv(path_char, argvlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005053
5054 /* If we get here it's definitely an error */
5055
5056 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005057 return posix_error();
5058}
5059
Larry Hastings2f936352014-08-05 14:04:04 +10005060
5061/*[clinic input]
5062os.execve
5063
5064 path: path_t(allow_fd='PATH_HAVE_FEXECVE')
5065 Path of executable file.
5066 argv: object
5067 Tuple or list of strings.
5068 env: object
5069 Dictionary of strings mapping to strings.
5070
5071Execute an executable path with arguments, replacing current process.
5072[clinic start generated code]*/
5073
Larry Hastings2f936352014-08-05 14:04:04 +10005074static PyObject *
5075os_execve_impl(PyModuleDef *module, path_t *path, PyObject *argv, PyObject *env)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005076/*[clinic end generated code: output=7758d4f230d8aac6 input=626804fa092606d9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005077{
Larry Hastings9cf065c2012-06-22 16:30:09 -07005078 char **argvlist = NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00005079 char **envlist;
Ross Lagerwall7807c352011-03-17 20:20:30 +02005080 Py_ssize_t argc, envc;
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005081
Victor Stinner8c62be82010-05-06 00:08:46 +00005082 /* execve has three arguments: (path, argv, env), where
5083 argv is a list or tuple of strings and env is a dictionary
5084 like posix.environ. */
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005085
Ross Lagerwall7807c352011-03-17 20:20:30 +02005086 if (!PyList_Check(argv) && !PyTuple_Check(argv)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005087 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005088 "execve: argv must be a tuple or list");
5089 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005090 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02005091 argc = PySequence_Size(argv);
Victor Stinner8c62be82010-05-06 00:08:46 +00005092 if (!PyMapping_Check(env)) {
5093 PyErr_SetString(PyExc_TypeError,
Larry Hastings9cf065c2012-06-22 16:30:09 -07005094 "execve: environment must be a mapping object");
5095 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005096 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005097
Ross Lagerwall7807c352011-03-17 20:20:30 +02005098 argvlist = parse_arglist(argv, &argc);
Victor Stinner8c62be82010-05-06 00:08:46 +00005099 if (argvlist == NULL) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07005100 goto fail;
Victor Stinner8c62be82010-05-06 00:08:46 +00005101 }
Guido van Rossumc6dcc9f1993-11-05 10:15:19 +00005102
Victor Stinner8c62be82010-05-06 00:08:46 +00005103 envlist = parse_envlist(env, &envc);
5104 if (envlist == NULL)
Ross Lagerwall7807c352011-03-17 20:20:30 +02005105 goto fail;
5106
Larry Hastings9cf065c2012-06-22 16:30:09 -07005107#ifdef HAVE_FEXECVE
Larry Hastings2f936352014-08-05 14:04:04 +10005108 if (path->fd > -1)
5109 fexecve(path->fd, argvlist, envlist);
Larry Hastings9cf065c2012-06-22 16:30:09 -07005110 else
5111#endif
Larry Hastings2f936352014-08-05 14:04:04 +10005112 execve(path->narrow, argvlist, envlist);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005113
5114 /* If we get here it's definitely an error */
5115
Larry Hastings2f936352014-08-05 14:04:04 +10005116 path_error(path);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005117
5118 while (--envc >= 0)
5119 PyMem_DEL(envlist[envc]);
5120 PyMem_DEL(envlist);
5121 fail:
Larry Hastings9cf065c2012-06-22 16:30:09 -07005122 if (argvlist)
5123 free_string_array(argvlist, argc);
Ross Lagerwall7807c352011-03-17 20:20:30 +02005124 return NULL;
5125}
Larry Hastings9cf065c2012-06-22 16:30:09 -07005126#endif /* HAVE_EXECV */
5127
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005128
Guido van Rossuma1065681999-01-25 23:20:23 +00005129#ifdef HAVE_SPAWNV
Larry Hastings2f936352014-08-05 14:04:04 +10005130/*[clinic input]
5131os.spawnv
5132
5133 mode: int
5134 Mode of process creation.
5135 path: FSConverter
5136 Path of executable file.
5137 argv: object
5138 Tuple or list of strings.
5139 /
5140
5141Execute the program specified by path in a new process.
5142[clinic start generated code]*/
5143
Larry Hastings2f936352014-08-05 14:04:04 +10005144static PyObject *
5145os_spawnv_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005146/*[clinic end generated code: output=140a7945484c8cc5 input=042c91dfc1e6debc]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005147{
5148 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005149 char **argvlist;
Larry Hastings2f936352014-08-05 14:04:04 +10005150 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00005151 Py_ssize_t argc;
5152 Py_intptr_t spawnval;
5153 PyObject *(*getitem)(PyObject *, Py_ssize_t);
Guido van Rossuma1065681999-01-25 23:20:23 +00005154
Victor Stinner8c62be82010-05-06 00:08:46 +00005155 /* spawnv has three arguments: (mode, path, argv), where
5156 argv is a list or tuple of strings. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005157
Larry Hastings2f936352014-08-05 14:04:04 +10005158 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005159 if (PyList_Check(argv)) {
5160 argc = PyList_Size(argv);
5161 getitem = PyList_GetItem;
5162 }
5163 else if (PyTuple_Check(argv)) {
5164 argc = PyTuple_Size(argv);
5165 getitem = PyTuple_GetItem;
5166 }
5167 else {
5168 PyErr_SetString(PyExc_TypeError,
5169 "spawnv() arg 2 must be a tuple or list");
Victor Stinner8c62be82010-05-06 00:08:46 +00005170 return NULL;
5171 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005172
Victor Stinner8c62be82010-05-06 00:08:46 +00005173 argvlist = PyMem_NEW(char *, argc+1);
5174 if (argvlist == NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00005175 return PyErr_NoMemory();
5176 }
5177 for (i = 0; i < argc; i++) {
5178 if (!fsconvert_strdup((*getitem)(argv, i),
5179 &argvlist[i])) {
5180 free_string_array(argvlist, i);
5181 PyErr_SetString(
5182 PyExc_TypeError,
5183 "spawnv() arg 2 must contain only strings");
Victor Stinner8c62be82010-05-06 00:08:46 +00005184 return NULL;
5185 }
5186 }
5187 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005188
Victor Stinner8c62be82010-05-06 00:08:46 +00005189 if (mode == _OLD_P_OVERLAY)
5190 mode = _P_OVERLAY;
Tim Peters5aa91602002-01-30 05:46:57 +00005191
Victor Stinner8c62be82010-05-06 00:08:46 +00005192 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005193 spawnval = _spawnv(mode, path_char, argvlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005194 Py_END_ALLOW_THREADS
Tim Peters5aa91602002-01-30 05:46:57 +00005195
Victor Stinner8c62be82010-05-06 00:08:46 +00005196 free_string_array(argvlist, argc);
Guido van Rossuma1065681999-01-25 23:20:23 +00005197
Victor Stinner8c62be82010-05-06 00:08:46 +00005198 if (spawnval == -1)
5199 return posix_error();
5200 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005201 return Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005202}
5203
5204
Larry Hastings2f936352014-08-05 14:04:04 +10005205/*[clinic input]
5206os.spawnve
5207
5208 mode: int
5209 Mode of process creation.
5210 path: FSConverter
5211 Path of executable file.
5212 argv: object
5213 Tuple or list of strings.
5214 env: object
5215 Dictionary of strings mapping to strings.
5216 /
5217
5218Execute the program specified by path in a new process.
5219[clinic start generated code]*/
5220
Larry Hastings2f936352014-08-05 14:04:04 +10005221static PyObject *
5222os_spawnve_impl(PyModuleDef *module, int mode, PyObject *path, PyObject *argv, PyObject *env)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005223/*[clinic end generated code: output=1c52955789461be8 input=02362fd937963f8f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005224{
5225 char *path_char;
Victor Stinner8c62be82010-05-06 00:08:46 +00005226 char **argvlist;
5227 char **envlist;
5228 PyObject *res = NULL;
Antoine Pitrou22e41552010-08-15 18:07:50 +00005229 Py_ssize_t argc, i, envc;
Victor Stinner8c62be82010-05-06 00:08:46 +00005230 Py_intptr_t spawnval;
5231 PyObject *(*getitem)(PyObject *, Py_ssize_t);
5232 Py_ssize_t lastarg = 0;
Guido van Rossuma1065681999-01-25 23:20:23 +00005233
Victor Stinner8c62be82010-05-06 00:08:46 +00005234 /* spawnve has four arguments: (mode, path, argv, env), where
5235 argv is a list or tuple of strings and env is a dictionary
5236 like posix.environ. */
Guido van Rossuma1065681999-01-25 23:20:23 +00005237
Larry Hastings2f936352014-08-05 14:04:04 +10005238 path_char = PyBytes_AsString(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00005239 if (PyList_Check(argv)) {
5240 argc = PyList_Size(argv);
5241 getitem = PyList_GetItem;
5242 }
5243 else if (PyTuple_Check(argv)) {
5244 argc = PyTuple_Size(argv);
5245 getitem = PyTuple_GetItem;
5246 }
5247 else {
5248 PyErr_SetString(PyExc_TypeError,
5249 "spawnve() arg 2 must be a tuple or list");
5250 goto fail_0;
5251 }
5252 if (!PyMapping_Check(env)) {
5253 PyErr_SetString(PyExc_TypeError,
5254 "spawnve() arg 3 must be a mapping object");
5255 goto fail_0;
5256 }
Guido van Rossuma1065681999-01-25 23:20:23 +00005257
Victor Stinner8c62be82010-05-06 00:08:46 +00005258 argvlist = PyMem_NEW(char *, argc+1);
5259 if (argvlist == NULL) {
5260 PyErr_NoMemory();
5261 goto fail_0;
5262 }
5263 for (i = 0; i < argc; i++) {
5264 if (!fsconvert_strdup((*getitem)(argv, i),
5265 &argvlist[i]))
5266 {
5267 lastarg = i;
5268 goto fail_1;
5269 }
5270 }
5271 lastarg = argc;
5272 argvlist[argc] = NULL;
Guido van Rossuma1065681999-01-25 23:20:23 +00005273
Victor Stinner8c62be82010-05-06 00:08:46 +00005274 envlist = parse_envlist(env, &envc);
5275 if (envlist == NULL)
5276 goto fail_1;
Guido van Rossuma1065681999-01-25 23:20:23 +00005277
Victor Stinner8c62be82010-05-06 00:08:46 +00005278 if (mode == _OLD_P_OVERLAY)
5279 mode = _P_OVERLAY;
Tim Peters25059d32001-12-07 20:35:43 +00005280
Victor Stinner8c62be82010-05-06 00:08:46 +00005281 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10005282 spawnval = _spawnve(mode, path_char, argvlist, envlist);
Victor Stinner8c62be82010-05-06 00:08:46 +00005283 Py_END_ALLOW_THREADS
Tim Peters25059d32001-12-07 20:35:43 +00005284
Victor Stinner8c62be82010-05-06 00:08:46 +00005285 if (spawnval == -1)
5286 (void) posix_error();
5287 else
Richard Oudkerkac0ad882013-06-05 23:29:30 +01005288 res = Py_BuildValue(_Py_PARSE_INTPTR, spawnval);
Guido van Rossuma1065681999-01-25 23:20:23 +00005289
Victor Stinner8c62be82010-05-06 00:08:46 +00005290 while (--envc >= 0)
5291 PyMem_DEL(envlist[envc]);
5292 PyMem_DEL(envlist);
Guido van Rossum0847c5c2002-12-13 18:36:22 +00005293 fail_1:
Victor Stinner8c62be82010-05-06 00:08:46 +00005294 free_string_array(argvlist, lastarg);
Martin v. Löwis114619e2002-10-07 06:44:21 +00005295 fail_0:
Victor Stinner8c62be82010-05-06 00:08:46 +00005296 return res;
Guido van Rossuma1065681999-01-25 23:20:23 +00005297}
Andrew MacIntyre69e18c92004-04-04 07:11:43 +00005298
Guido van Rossuma1065681999-01-25 23:20:23 +00005299#endif /* HAVE_SPAWNV */
5300
5301
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005302#ifdef HAVE_FORK1
Larry Hastings2f936352014-08-05 14:04:04 +10005303/*[clinic input]
5304os.fork1
5305
5306Fork a child process with a single multiplexed (i.e., not bound) thread.
5307
5308Return 0 to child process and PID of child to parent process.
5309[clinic start generated code]*/
5310
Larry Hastings2f936352014-08-05 14:04:04 +10005311static PyObject *
5312os_fork1_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005313/*[clinic end generated code: output=e27b4f66419c9dcf input=12db02167893926e]*/
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005314{
Victor Stinner8c62be82010-05-06 00:08:46 +00005315 pid_t pid;
5316 int result = 0;
5317 _PyImport_AcquireLock();
5318 pid = fork1();
5319 if (pid == 0) {
5320 /* child: this clobbers and resets the import lock. */
5321 PyOS_AfterFork();
5322 } else {
5323 /* parent: release the import lock. */
5324 result = _PyImport_ReleaseLock();
5325 }
5326 if (pid == -1)
5327 return posix_error();
5328 if (result < 0) {
5329 /* Don't clobber the OSError if the fork failed. */
5330 PyErr_SetString(PyExc_RuntimeError,
5331 "not holding the import lock");
5332 return NULL;
5333 }
5334 return PyLong_FromPid(pid);
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005335}
Larry Hastings2f936352014-08-05 14:04:04 +10005336#endif /* HAVE_FORK1 */
Guido van Rossum2242f2f2001-04-11 20:58:20 +00005337
5338
Guido van Rossumad0ee831995-03-01 10:34:45 +00005339#ifdef HAVE_FORK
Larry Hastings2f936352014-08-05 14:04:04 +10005340/*[clinic input]
5341os.fork
5342
5343Fork a child process.
5344
5345Return 0 to child process and PID of child to parent process.
5346[clinic start generated code]*/
5347
Larry Hastings2f936352014-08-05 14:04:04 +10005348static PyObject *
5349os_fork_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005350/*[clinic end generated code: output=898b1ecd3498ba12 input=13c956413110eeaa]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00005351{
Victor Stinner8c62be82010-05-06 00:08:46 +00005352 pid_t pid;
5353 int result = 0;
5354 _PyImport_AcquireLock();
5355 pid = fork();
5356 if (pid == 0) {
5357 /* child: this clobbers and resets the import lock. */
5358 PyOS_AfterFork();
5359 } else {
5360 /* parent: release the import lock. */
5361 result = _PyImport_ReleaseLock();
5362 }
5363 if (pid == -1)
5364 return posix_error();
5365 if (result < 0) {
5366 /* Don't clobber the OSError if the fork failed. */
5367 PyErr_SetString(PyExc_RuntimeError,
5368 "not holding the import lock");
5369 return NULL;
5370 }
5371 return PyLong_FromPid(pid);
Guido van Rossum85e3b011991-06-03 12:42:10 +00005372}
Larry Hastings2f936352014-08-05 14:04:04 +10005373#endif /* HAVE_FORK */
5374
Guido van Rossum85e3b011991-06-03 12:42:10 +00005375
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005376#ifdef HAVE_SCHED_H
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005377#ifdef HAVE_SCHED_GET_PRIORITY_MAX
Larry Hastings2f936352014-08-05 14:04:04 +10005378/*[clinic input]
5379os.sched_get_priority_max
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005380
Larry Hastings2f936352014-08-05 14:04:04 +10005381 policy: int
5382
5383Get the maximum scheduling priority for policy.
5384[clinic start generated code]*/
5385
Larry Hastings2f936352014-08-05 14:04:04 +10005386static PyObject *
5387os_sched_get_priority_max_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005388/*[clinic end generated code: output=a6a30fa5071f2d81 input=2097b7998eca6874]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005389{
5390 int max;
5391
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005392 max = sched_get_priority_max(policy);
5393 if (max < 0)
5394 return posix_error();
5395 return PyLong_FromLong(max);
5396}
5397
Larry Hastings2f936352014-08-05 14:04:04 +10005398
5399/*[clinic input]
5400os.sched_get_priority_min
5401
5402 policy: int
5403
5404Get the minimum scheduling priority for policy.
5405[clinic start generated code]*/
5406
Larry Hastings2f936352014-08-05 14:04:04 +10005407static PyObject *
5408os_sched_get_priority_min_impl(PyModuleDef *module, int policy)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005409/*[clinic end generated code: output=5ca3ed6bc43e9b20 input=21bc8fa0d70983bf]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005410{
5411 int min = sched_get_priority_min(policy);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005412 if (min < 0)
5413 return posix_error();
5414 return PyLong_FromLong(min);
5415}
Charles-François Nataliea0d5fc2011-09-06 19:03:35 +02005416#endif /* HAVE_SCHED_GET_PRIORITY_MAX */
5417
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005418
Larry Hastings2f936352014-08-05 14:04:04 +10005419#ifdef HAVE_SCHED_SETSCHEDULER
5420/*[clinic input]
5421os.sched_getscheduler
5422 pid: pid_t
5423 /
5424
5425Get the scheduling policy for the process identifiedy by pid.
5426
5427Passing 0 for pid returns the scheduling policy for the calling process.
5428[clinic start generated code]*/
5429
Larry Hastings2f936352014-08-05 14:04:04 +10005430static PyObject *
5431os_sched_getscheduler_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005432/*[clinic end generated code: output=8cd63c15caf54fa9 input=5f14cfd1f189e1a0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005433{
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005434 int policy;
5435
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005436 policy = sched_getscheduler(pid);
5437 if (policy < 0)
5438 return posix_error();
5439 return PyLong_FromLong(policy);
5440}
Larry Hastings2f936352014-08-05 14:04:04 +10005441#endif /* HAVE_SCHED_SETSCHEDULER */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005442
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005443
5444#if defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM)
Larry Hastings2f936352014-08-05 14:04:04 +10005445/*[clinic input]
5446class os.sched_param "PyObject *" "&SchedParamType"
5447
5448@classmethod
5449os.sched_param.__new__
5450
5451 sched_priority: object
5452 A scheduling parameter.
5453
5454Current has only one field: sched_priority");
5455[clinic start generated code]*/
5456
Larry Hastings2f936352014-08-05 14:04:04 +10005457static PyObject *
5458os_sched_param_impl(PyTypeObject *type, PyObject *sched_priority)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005459/*[clinic end generated code: output=48f4067d60f48c13 input=73a4c22f7071fc62]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005460{
5461 PyObject *res;
5462
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005463 res = PyStructSequence_New(type);
5464 if (!res)
5465 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10005466 Py_INCREF(sched_priority);
5467 PyStructSequence_SET_ITEM(res, 0, sched_priority);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005468 return res;
5469}
5470
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005471
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005472PyDoc_VAR(os_sched_param__doc__);
5473
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005474static PyStructSequence_Field sched_param_fields[] = {
5475 {"sched_priority", "the scheduling priority"},
5476 {0}
5477};
5478
5479static PyStructSequence_Desc sched_param_desc = {
5480 "sched_param", /* name */
Larry Hastings2f936352014-08-05 14:04:04 +10005481 os_sched_param__doc__, /* doc */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005482 sched_param_fields,
5483 1
5484};
5485
5486static int
5487convert_sched_param(PyObject *param, struct sched_param *res)
5488{
5489 long priority;
5490
5491 if (Py_TYPE(param) != &SchedParamType) {
5492 PyErr_SetString(PyExc_TypeError, "must have a sched_param object");
5493 return 0;
5494 }
5495 priority = PyLong_AsLong(PyStructSequence_GET_ITEM(param, 0));
5496 if (priority == -1 && PyErr_Occurred())
5497 return 0;
5498 if (priority > INT_MAX || priority < INT_MIN) {
5499 PyErr_SetString(PyExc_OverflowError, "sched_priority out of range");
5500 return 0;
5501 }
5502 res->sched_priority = Py_SAFE_DOWNCAST(priority, long, int);
5503 return 1;
5504}
Larry Hastings2f936352014-08-05 14:04:04 +10005505#endif /* defined(HAVE_SCHED_SETSCHEDULER) || defined(HAVE_SCHED_SETPARAM) */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005506
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005507
5508#ifdef HAVE_SCHED_SETSCHEDULER
Larry Hastings2f936352014-08-05 14:04:04 +10005509/*[clinic input]
5510os.sched_setscheduler
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005511
Larry Hastings2f936352014-08-05 14:04:04 +10005512 pid: pid_t
5513 policy: int
5514 param: sched_param
5515 /
5516
5517Set the scheduling policy for the process identified by pid.
5518
5519If pid is 0, the calling process is changed.
5520param is an instance of sched_param.
5521[clinic start generated code]*/
5522
Larry Hastings2f936352014-08-05 14:04:04 +10005523static PyObject *
5524os_sched_setscheduler_impl(PyModuleDef *module, pid_t pid, int policy, struct sched_param *param)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005525/*[clinic end generated code: output=97f40f8384e554b0 input=c581f9469a5327dd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005526{
Jesus Cea9c822272011-09-10 01:40:52 +02005527 /*
Jesus Cea54b01492011-09-10 01:53:19 +02005528 ** sched_setscheduler() returns 0 in Linux, but the previous
5529 ** scheduling policy under Solaris/Illumos, and others.
5530 ** On error, -1 is returned in all Operating Systems.
Jesus Cea9c822272011-09-10 01:40:52 +02005531 */
Larry Hastings2f936352014-08-05 14:04:04 +10005532 if (sched_setscheduler(pid, policy, param) == -1)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005533 return posix_error();
5534 Py_RETURN_NONE;
5535}
Larry Hastings2f936352014-08-05 14:04:04 +10005536#endif /* HAVE_SCHED_SETSCHEDULER*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005537
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005538
5539#ifdef HAVE_SCHED_SETPARAM
Larry Hastings2f936352014-08-05 14:04:04 +10005540/*[clinic input]
5541os.sched_getparam
5542 pid: pid_t
5543 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005544
Larry Hastings2f936352014-08-05 14:04:04 +10005545Returns scheduling parameters for the process identified by pid.
5546
5547If pid is 0, returns parameters for the calling process.
5548Return value is an instance of sched_param.
5549[clinic start generated code]*/
5550
Larry Hastings2f936352014-08-05 14:04:04 +10005551static PyObject *
5552os_sched_getparam_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005553/*[clinic end generated code: output=f42c5bd2604ecd08 input=18a1ef9c2efae296]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005554{
5555 struct sched_param param;
5556 PyObject *result;
5557 PyObject *priority;
5558
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005559 if (sched_getparam(pid, &param))
5560 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10005561 result = PyStructSequence_New(&SchedParamType);
5562 if (!result)
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005563 return NULL;
5564 priority = PyLong_FromLong(param.sched_priority);
5565 if (!priority) {
Larry Hastings2f936352014-08-05 14:04:04 +10005566 Py_DECREF(result);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005567 return NULL;
5568 }
Larry Hastings2f936352014-08-05 14:04:04 +10005569 PyStructSequence_SET_ITEM(result, 0, priority);
5570 return result;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005571}
5572
Larry Hastings2f936352014-08-05 14:04:04 +10005573
5574/*[clinic input]
5575os.sched_setparam
5576 pid: pid_t
5577 param: sched_param
5578 /
5579
5580Set scheduling parameters for the process identified by pid.
5581
5582If pid is 0, sets parameters for the calling process.
5583param should be an instance of sched_param.
5584[clinic start generated code]*/
5585
Larry Hastings2f936352014-08-05 14:04:04 +10005586static PyObject *
5587os_sched_setparam_impl(PyModuleDef *module, pid_t pid, struct sched_param *param)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005588/*[clinic end generated code: output=c6560b34395bb343 input=6b8d6dfcecdc21bd]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005589{
5590 if (sched_setparam(pid, param))
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005591 return posix_error();
5592 Py_RETURN_NONE;
5593}
Larry Hastings2f936352014-08-05 14:04:04 +10005594#endif /* HAVE_SCHED_SETPARAM */
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005595
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005596
5597#ifdef HAVE_SCHED_RR_GET_INTERVAL
Larry Hastings2f936352014-08-05 14:04:04 +10005598/*[clinic input]
5599os.sched_rr_get_interval -> double
5600 pid: pid_t
5601 /
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005602
Larry Hastings2f936352014-08-05 14:04:04 +10005603Return the round-robin quantum for the process identified by pid, in seconds.
5604
5605Value returned is a float.
5606[clinic start generated code]*/
5607
Larry Hastings2f936352014-08-05 14:04:04 +10005608static double
5609os_sched_rr_get_interval_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005610/*[clinic end generated code: output=7adc137a86dea581 input=2a973da15cca6fae]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005611{
5612 struct timespec interval;
5613 if (sched_rr_get_interval(pid, &interval)) {
5614 posix_error();
5615 return -1.0;
5616 }
5617 return (double)interval.tv_sec + 1e-9*interval.tv_nsec;
5618}
5619#endif /* HAVE_SCHED_RR_GET_INTERVAL */
Benjamin Petersonc5fce4d2011-08-02 18:07:32 -05005620
Larry Hastings2f936352014-08-05 14:04:04 +10005621
5622/*[clinic input]
5623os.sched_yield
5624
5625Voluntarily relinquish the CPU.
5626[clinic start generated code]*/
5627
Larry Hastings2f936352014-08-05 14:04:04 +10005628static PyObject *
5629os_sched_yield_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005630/*[clinic end generated code: output=d7bd51869c4cb6a8 input=e54d6f98189391d4]*/
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005631{
5632 if (sched_yield())
5633 return posix_error();
5634 Py_RETURN_NONE;
5635}
5636
Benjamin Peterson2740af82011-08-02 17:41:34 -05005637#ifdef HAVE_SCHED_SETAFFINITY
Antoine Pitrou84869872012-08-04 16:16:35 +02005638/* The minimum number of CPUs allocated in a cpu_set_t */
5639static const int NCPUS_START = sizeof(unsigned long) * CHAR_BIT;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005640
Larry Hastings2f936352014-08-05 14:04:04 +10005641/*[clinic input]
5642os.sched_setaffinity
5643 pid: pid_t
5644 mask : object
5645 /
5646
5647Set the CPU affinity of the process identified by pid to mask.
5648
5649mask should be an iterable of integers identifying CPUs.
5650[clinic start generated code]*/
5651
Larry Hastings2f936352014-08-05 14:04:04 +10005652static PyObject *
5653os_sched_setaffinity_impl(PyModuleDef *module, pid_t pid, PyObject *mask)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005654/*[clinic end generated code: output=582bcbf40d3253a9 input=a0791a597c7085ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005655{
Antoine Pitrou84869872012-08-04 16:16:35 +02005656 int ncpus;
5657 size_t setsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005658 cpu_set_t *cpu_set = NULL;
5659 PyObject *iterator = NULL, *item;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005660
Larry Hastings2f936352014-08-05 14:04:04 +10005661 iterator = PyObject_GetIter(mask);
Antoine Pitrou84869872012-08-04 16:16:35 +02005662 if (iterator == NULL)
5663 return NULL;
5664
5665 ncpus = NCPUS_START;
5666 setsize = CPU_ALLOC_SIZE(ncpus);
Larry Hastings2f936352014-08-05 14:04:04 +10005667 cpu_set = CPU_ALLOC(ncpus);
5668 if (cpu_set == NULL) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005669 PyErr_NoMemory();
5670 goto error;
5671 }
Larry Hastings2f936352014-08-05 14:04:04 +10005672 CPU_ZERO_S(setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005673
5674 while ((item = PyIter_Next(iterator))) {
5675 long cpu;
5676 if (!PyLong_Check(item)) {
5677 PyErr_Format(PyExc_TypeError,
5678 "expected an iterator of ints, "
5679 "but iterator yielded %R",
5680 Py_TYPE(item));
5681 Py_DECREF(item);
5682 goto error;
5683 }
5684 cpu = PyLong_AsLong(item);
5685 Py_DECREF(item);
5686 if (cpu < 0) {
5687 if (!PyErr_Occurred())
5688 PyErr_SetString(PyExc_ValueError, "negative CPU number");
5689 goto error;
5690 }
5691 if (cpu > INT_MAX - 1) {
5692 PyErr_SetString(PyExc_OverflowError, "CPU number too large");
5693 goto error;
5694 }
5695 if (cpu >= ncpus) {
5696 /* Grow CPU mask to fit the CPU number */
5697 int newncpus = ncpus;
5698 cpu_set_t *newmask;
5699 size_t newsetsize;
5700 while (newncpus <= cpu) {
5701 if (newncpus > INT_MAX / 2)
5702 newncpus = cpu + 1;
5703 else
5704 newncpus = newncpus * 2;
5705 }
5706 newmask = CPU_ALLOC(newncpus);
5707 if (newmask == NULL) {
5708 PyErr_NoMemory();
5709 goto error;
5710 }
5711 newsetsize = CPU_ALLOC_SIZE(newncpus);
5712 CPU_ZERO_S(newsetsize, newmask);
Larry Hastings2f936352014-08-05 14:04:04 +10005713 memcpy(newmask, cpu_set, setsize);
5714 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005715 setsize = newsetsize;
Larry Hastings2f936352014-08-05 14:04:04 +10005716 cpu_set = newmask;
Antoine Pitrou84869872012-08-04 16:16:35 +02005717 ncpus = newncpus;
5718 }
Larry Hastings2f936352014-08-05 14:04:04 +10005719 CPU_SET_S(cpu, setsize, cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005720 }
5721 Py_CLEAR(iterator);
5722
Larry Hastings2f936352014-08-05 14:04:04 +10005723 if (sched_setaffinity(pid, setsize, cpu_set)) {
Antoine Pitrou84869872012-08-04 16:16:35 +02005724 posix_error();
5725 goto error;
5726 }
Larry Hastings2f936352014-08-05 14:04:04 +10005727 CPU_FREE(cpu_set);
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005728 Py_RETURN_NONE;
Antoine Pitrou84869872012-08-04 16:16:35 +02005729
5730error:
Larry Hastings2f936352014-08-05 14:04:04 +10005731 if (cpu_set)
5732 CPU_FREE(cpu_set);
Antoine Pitrou84869872012-08-04 16:16:35 +02005733 Py_XDECREF(iterator);
5734 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005735}
5736
Larry Hastings2f936352014-08-05 14:04:04 +10005737
5738/*[clinic input]
5739os.sched_getaffinity
5740 pid: pid_t
5741 /
5742
5743Return the affinity of the process identified by pid.
5744
5745The affinity is returned as a set of CPU identifiers.
5746[clinic start generated code]*/
5747
Larry Hastings2f936352014-08-05 14:04:04 +10005748static PyObject *
5749os_sched_getaffinity_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005750/*[clinic end generated code: output=b431a8f310e369e7 input=eaf161936874b8a1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10005751{
Antoine Pitrou84869872012-08-04 16:16:35 +02005752 int cpu, ncpus, count;
5753 size_t setsize;
5754 cpu_set_t *mask = NULL;
5755 PyObject *res = NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005756
Antoine Pitrou84869872012-08-04 16:16:35 +02005757 ncpus = NCPUS_START;
5758 while (1) {
5759 setsize = CPU_ALLOC_SIZE(ncpus);
5760 mask = CPU_ALLOC(ncpus);
5761 if (mask == NULL)
5762 return PyErr_NoMemory();
5763 if (sched_getaffinity(pid, setsize, mask) == 0)
5764 break;
5765 CPU_FREE(mask);
5766 if (errno != EINVAL)
5767 return posix_error();
5768 if (ncpus > INT_MAX / 2) {
5769 PyErr_SetString(PyExc_OverflowError, "could not allocate "
5770 "a large enough CPU set");
5771 return NULL;
5772 }
5773 ncpus = ncpus * 2;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005774 }
Antoine Pitrou84869872012-08-04 16:16:35 +02005775
5776 res = PySet_New(NULL);
5777 if (res == NULL)
5778 goto error;
5779 for (cpu = 0, count = CPU_COUNT_S(setsize, mask); count; cpu++) {
5780 if (CPU_ISSET_S(cpu, setsize, mask)) {
5781 PyObject *cpu_num = PyLong_FromLong(cpu);
5782 --count;
5783 if (cpu_num == NULL)
5784 goto error;
5785 if (PySet_Add(res, cpu_num)) {
5786 Py_DECREF(cpu_num);
5787 goto error;
5788 }
5789 Py_DECREF(cpu_num);
5790 }
5791 }
5792 CPU_FREE(mask);
5793 return res;
5794
5795error:
5796 if (mask)
5797 CPU_FREE(mask);
5798 Py_XDECREF(res);
5799 return NULL;
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005800}
5801
Benjamin Peterson2740af82011-08-02 17:41:34 -05005802#endif /* HAVE_SCHED_SETAFFINITY */
5803
Benjamin Peterson94b580d2011-08-02 17:30:04 -05005804#endif /* HAVE_SCHED_H */
5805
Larry Hastings2f936352014-08-05 14:04:04 +10005806
Neal Norwitzb59798b2003-03-21 01:43:31 +00005807/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
Neal Norwitz2deaddb2003-03-21 03:08:31 +00005808/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
5809#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
Neal Norwitzb59798b2003-03-21 01:43:31 +00005810#define DEV_PTY_FILE "/dev/ptc"
5811#define HAVE_DEV_PTMX
5812#else
5813#define DEV_PTY_FILE "/dev/ptmx"
5814#endif
5815
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005816#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
Fred Drake8cef4cf2000-06-28 16:40:38 +00005817#ifdef HAVE_PTY_H
5818#include <pty.h>
5819#else
5820#ifdef HAVE_LIBUTIL_H
5821#include <libutil.h>
Ronald Oussoren755740f2010-02-07 19:56:39 +00005822#else
5823#ifdef HAVE_UTIL_H
5824#include <util.h>
5825#endif /* HAVE_UTIL_H */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005826#endif /* HAVE_LIBUTIL_H */
5827#endif /* HAVE_PTY_H */
Martin v. Löwis14e73b12003-01-01 09:51:12 +00005828#ifdef HAVE_STROPTS_H
5829#include <stropts.h>
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005830#endif
5831#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005832
Larry Hastings2f936352014-08-05 14:04:04 +10005833
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005834#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
Larry Hastings2f936352014-08-05 14:04:04 +10005835/*[clinic input]
5836os.openpty
5837
5838Open a pseudo-terminal.
5839
5840Return a tuple of (master_fd, slave_fd) containing open file descriptors
5841for both the master and slave ends.
5842[clinic start generated code]*/
5843
Larry Hastings2f936352014-08-05 14:04:04 +10005844static PyObject *
5845os_openpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005846/*[clinic end generated code: output=358e571c1ba135ee input=f3d99fd99e762907]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005847{
Victor Stinnerdaf45552013-08-28 00:53:59 +02005848 int master_fd = -1, slave_fd = -1;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005849#ifndef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005850 char * slave_name;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005851#endif
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005852#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005853 PyOS_sighandler_t sig_saved;
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005854#ifdef sun
Victor Stinner8c62be82010-05-06 00:08:46 +00005855 extern char *ptsname(int fildes);
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005856#endif
5857#endif
Thomas Wouters70c21a12000-07-14 14:28:33 +00005858
Thomas Wouters70c21a12000-07-14 14:28:33 +00005859#ifdef HAVE_OPENPTY
Victor Stinner8c62be82010-05-06 00:08:46 +00005860 if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005861 goto posix_error;
5862
5863 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5864 goto error;
5865 if (_Py_set_inheritable(slave_fd, 0, NULL) < 0)
5866 goto error;
5867
Neal Norwitzb59798b2003-03-21 01:43:31 +00005868#elif defined(HAVE__GETPTY)
Victor Stinner8c62be82010-05-06 00:08:46 +00005869 slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
5870 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005871 goto posix_error;
5872 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5873 goto error;
Thomas Wouters70c21a12000-07-14 14:28:33 +00005874
Victor Stinnerdaf45552013-08-28 00:53:59 +02005875 slave_fd = _Py_open(slave_name, O_RDWR);
Victor Stinner8c62be82010-05-06 00:08:46 +00005876 if (slave_fd < 0)
Victor Stinnera555cfc2015-03-18 00:22:14 +01005877 goto error;
Victor Stinnerdaf45552013-08-28 00:53:59 +02005878
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005879#else
Victor Stinner000de532013-11-25 23:19:58 +01005880 master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
Victor Stinner8c62be82010-05-06 00:08:46 +00005881 if (master_fd < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005882 goto posix_error;
5883
Victor Stinner8c62be82010-05-06 00:08:46 +00005884 sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005885
Victor Stinner8c62be82010-05-06 00:08:46 +00005886 /* change permission of slave */
5887 if (grantpt(master_fd) < 0) {
5888 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005889 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005890 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005891
Victor Stinner8c62be82010-05-06 00:08:46 +00005892 /* unlock slave */
5893 if (unlockpt(master_fd) < 0) {
5894 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005895 goto posix_error;
Victor Stinner8c62be82010-05-06 00:08:46 +00005896 }
Victor Stinnerdaf45552013-08-28 00:53:59 +02005897
Victor Stinner8c62be82010-05-06 00:08:46 +00005898 PyOS_setsig(SIGCHLD, sig_saved);
Victor Stinnerdaf45552013-08-28 00:53:59 +02005899
Victor Stinner8c62be82010-05-06 00:08:46 +00005900 slave_name = ptsname(master_fd); /* get name of slave */
5901 if (slave_name == NULL)
Victor Stinnerdaf45552013-08-28 00:53:59 +02005902 goto posix_error;
5903
5904 slave_fd = _Py_open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
Victor Stinnera555cfc2015-03-18 00:22:14 +01005905 if (slave_fd == -1)
5906 goto error;
Victor Stinner000de532013-11-25 23:19:58 +01005907
5908 if (_Py_set_inheritable(master_fd, 0, NULL) < 0)
5909 goto posix_error;
5910
Neal Norwitzb59798b2003-03-21 01:43:31 +00005911#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
Victor Stinner8c62be82010-05-06 00:08:46 +00005912 ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
5913 ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
Neal Norwitz6700e472002-12-31 16:16:07 +00005914#ifndef __hpux
Victor Stinner8c62be82010-05-06 00:08:46 +00005915 ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
Neal Norwitz6700e472002-12-31 16:16:07 +00005916#endif /* __hpux */
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005917#endif /* HAVE_CYGWIN */
Thomas Wouters1e0c2f42000-07-24 16:06:23 +00005918#endif /* HAVE_OPENPTY */
Thomas Wouters70c21a12000-07-14 14:28:33 +00005919
Victor Stinner8c62be82010-05-06 00:08:46 +00005920 return Py_BuildValue("(ii)", master_fd, slave_fd);
Thomas Wouters70c21a12000-07-14 14:28:33 +00005921
Victor Stinnerdaf45552013-08-28 00:53:59 +02005922posix_error:
5923 posix_error();
5924error:
5925 if (master_fd != -1)
5926 close(master_fd);
5927 if (slave_fd != -1)
5928 close(slave_fd);
5929 return NULL;
Fred Drake8cef4cf2000-06-28 16:40:38 +00005930}
Martin v. Löwis24a880b2002-12-31 12:55:15 +00005931#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
Fred Drake8cef4cf2000-06-28 16:40:38 +00005932
Larry Hastings2f936352014-08-05 14:04:04 +10005933
Fred Drake8cef4cf2000-06-28 16:40:38 +00005934#ifdef HAVE_FORKPTY
Larry Hastings2f936352014-08-05 14:04:04 +10005935/*[clinic input]
5936os.forkpty
5937
5938Fork a new process with a new pseudo-terminal as controlling tty.
5939
5940Returns a tuple of (pid, master_fd).
5941Like fork(), return pid of 0 to the child process,
5942and pid of child to the parent process.
5943To both, return fd of newly opened pseudo-terminal.
5944[clinic start generated code]*/
5945
Larry Hastings2f936352014-08-05 14:04:04 +10005946static PyObject *
5947os_forkpty_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005948/*[clinic end generated code: output=a11b8391dce3cb57 input=f1f7f4bae3966010]*/
Fred Drake8cef4cf2000-06-28 16:40:38 +00005949{
Victor Stinner8c62be82010-05-06 00:08:46 +00005950 int master_fd = -1, result = 0;
5951 pid_t pid;
Tim Peters5aa91602002-01-30 05:46:57 +00005952
Victor Stinner8c62be82010-05-06 00:08:46 +00005953 _PyImport_AcquireLock();
5954 pid = forkpty(&master_fd, NULL, NULL, NULL);
5955 if (pid == 0) {
5956 /* child: this clobbers and resets the import lock. */
5957 PyOS_AfterFork();
5958 } else {
5959 /* parent: release the import lock. */
5960 result = _PyImport_ReleaseLock();
5961 }
5962 if (pid == -1)
5963 return posix_error();
5964 if (result < 0) {
5965 /* Don't clobber the OSError if the fork failed. */
5966 PyErr_SetString(PyExc_RuntimeError,
5967 "not holding the import lock");
5968 return NULL;
5969 }
5970 return Py_BuildValue("(Ni)", PyLong_FromPid(pid), master_fd);
Fred Drake8cef4cf2000-06-28 16:40:38 +00005971}
Larry Hastings2f936352014-08-05 14:04:04 +10005972#endif /* HAVE_FORKPTY */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005973
Ross Lagerwall7807c352011-03-17 20:20:30 +02005974
Guido van Rossumad0ee831995-03-01 10:34:45 +00005975#ifdef HAVE_GETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10005976/*[clinic input]
5977os.getegid
5978
5979Return the current process's effective group id.
5980[clinic start generated code]*/
5981
Larry Hastings2f936352014-08-05 14:04:04 +10005982static PyObject *
5983os_getegid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03005984/*[clinic end generated code: output=90f433a8c0b1d919 input=1596f79ad1107d5d]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00005985{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02005986 return _PyLong_FromGid(getegid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00005987}
Larry Hastings2f936352014-08-05 14:04:04 +10005988#endif /* HAVE_GETEGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00005989
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00005990
Guido van Rossumad0ee831995-03-01 10:34:45 +00005991#ifdef HAVE_GETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10005992/*[clinic input]
5993os.geteuid
5994
5995Return the current process's effective user id.
5996[clinic start generated code]*/
5997
Larry Hastings2f936352014-08-05 14:04:04 +10005998static PyObject *
5999os_geteuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006000/*[clinic end generated code: output=1a532c4a66874357 input=4644c662d3bd9f19]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006001{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006002 return _PyLong_FromUid(geteuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006003}
Larry Hastings2f936352014-08-05 14:04:04 +10006004#endif /* HAVE_GETEUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006005
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006006
Guido van Rossumad0ee831995-03-01 10:34:45 +00006007#ifdef HAVE_GETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006008/*[clinic input]
6009os.getgid
6010
6011Return the current process's group id.
6012[clinic start generated code]*/
6013
Larry Hastings2f936352014-08-05 14:04:04 +10006014static PyObject *
6015os_getgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006016/*[clinic end generated code: output=91a22021b74ea46b input=58796344cd87c0f6]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006017{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006018 return _PyLong_FromGid(getgid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006019}
Larry Hastings2f936352014-08-05 14:04:04 +10006020#endif /* HAVE_GETGID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006021
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006022
Larry Hastings2f936352014-08-05 14:04:04 +10006023/*[clinic input]
6024os.getpid
6025
6026Return the current process id.
6027[clinic start generated code]*/
6028
Larry Hastings2f936352014-08-05 14:04:04 +10006029static PyObject *
6030os_getpid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006031/*[clinic end generated code: output=8fbf3a934ee09e62 input=5a9a00f0ab68aa00]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006032{
Victor Stinner8c62be82010-05-06 00:08:46 +00006033 return PyLong_FromPid(getpid());
Guido van Rossum85e3b011991-06-03 12:42:10 +00006034}
6035
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006036#ifdef HAVE_GETGROUPLIST
Larry Hastings2f936352014-08-05 14:04:04 +10006037
6038/* AC 3.5: funny apple logic below */
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006039PyDoc_STRVAR(posix_getgrouplist__doc__,
6040"getgrouplist(user, group) -> list of groups to which a user belongs\n\n\
6041Returns a list of groups to which a user belongs.\n\n\
6042 user: username to lookup\n\
6043 group: base group id of the user");
6044
6045static PyObject *
6046posix_getgrouplist(PyObject *self, PyObject *args)
6047{
6048#ifdef NGROUPS_MAX
6049#define MAX_GROUPS NGROUPS_MAX
6050#else
6051 /* defined to be 16 on Solaris7, so this should be a small number */
6052#define MAX_GROUPS 64
6053#endif
6054
6055 const char *user;
6056 int i, ngroups;
6057 PyObject *list;
6058#ifdef __APPLE__
6059 int *groups, basegid;
6060#else
6061 gid_t *groups, basegid;
6062#endif
6063 ngroups = MAX_GROUPS;
6064
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006065#ifdef __APPLE__
6066 if (!PyArg_ParseTuple(args, "si:getgrouplist", &user, &basegid))
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006067 return NULL;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006068#else
6069 if (!PyArg_ParseTuple(args, "sO&:getgrouplist", &user,
6070 _Py_Gid_Converter, &basegid))
6071 return NULL;
6072#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006073
6074#ifdef __APPLE__
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006075 groups = PyMem_New(int, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006076#else
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006077 groups = PyMem_New(gid_t, ngroups);
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006078#endif
6079 if (groups == NULL)
6080 return PyErr_NoMemory();
6081
6082 if (getgrouplist(user, basegid, groups, &ngroups) == -1) {
6083 PyMem_Del(groups);
6084 return posix_error();
6085 }
6086
6087 list = PyList_New(ngroups);
6088 if (list == NULL) {
6089 PyMem_Del(groups);
6090 return NULL;
6091 }
6092
6093 for (i = 0; i < ngroups; i++) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006094#ifdef __APPLE__
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006095 PyObject *o = PyLong_FromUnsignedLong((unsigned long)groups[i]);
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006096#else
6097 PyObject *o = _PyLong_FromGid(groups[i]);
6098#endif
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +02006099 if (o == NULL) {
6100 Py_DECREF(list);
6101 PyMem_Del(groups);
6102 return NULL;
6103 }
6104 PyList_SET_ITEM(list, i, o);
6105 }
6106
6107 PyMem_Del(groups);
6108
6109 return list;
6110}
Larry Hastings2f936352014-08-05 14:04:04 +10006111#endif /* HAVE_GETGROUPLIST */
6112
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006113
Fred Drakec9680921999-12-13 16:37:25 +00006114#ifdef HAVE_GETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006115/*[clinic input]
6116os.getgroups
6117
6118Return list of supplemental group IDs for the process.
6119[clinic start generated code]*/
6120
Larry Hastings2f936352014-08-05 14:04:04 +10006121static PyObject *
6122os_getgroups_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006123/*[clinic end generated code: output=6e7c4fd2db6d5c60 input=d3f109412e6a155c]*/
Fred Drakec9680921999-12-13 16:37:25 +00006124{
6125 PyObject *result = NULL;
6126
Fred Drakec9680921999-12-13 16:37:25 +00006127#ifdef NGROUPS_MAX
6128#define MAX_GROUPS NGROUPS_MAX
6129#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006130 /* defined to be 16 on Solaris7, so this should be a small number */
Fred Drakec9680921999-12-13 16:37:25 +00006131#define MAX_GROUPS 64
6132#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006133 gid_t grouplist[MAX_GROUPS];
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006134
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006135 /* On MacOSX getgroups(2) can return more than MAX_GROUPS results
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006136 * This is a helper variable to store the intermediate result when
6137 * that happens.
6138 *
6139 * To keep the code readable the OSX behaviour is unconditional,
6140 * according to the POSIX spec this should be safe on all unix-y
6141 * systems.
6142 */
6143 gid_t* alt_grouplist = grouplist;
Victor Stinner8c62be82010-05-06 00:08:46 +00006144 int n;
Fred Drakec9680921999-12-13 16:37:25 +00006145
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006146#ifdef __APPLE__
6147 /* Issue #17557: As of OS X 10.8, getgroups(2) no longer raises EINVAL if
6148 * there are more groups than can fit in grouplist. Therefore, on OS X
6149 * always first call getgroups with length 0 to get the actual number
6150 * of groups.
6151 */
6152 n = getgroups(0, NULL);
6153 if (n < 0) {
6154 return posix_error();
6155 } else if (n <= MAX_GROUPS) {
6156 /* groups will fit in existing array */
6157 alt_grouplist = grouplist;
6158 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006159 alt_grouplist = PyMem_New(gid_t, n);
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006160 if (alt_grouplist == NULL) {
6161 errno = EINVAL;
6162 return posix_error();
6163 }
6164 }
6165
6166 n = getgroups(n, alt_grouplist);
6167 if (n == -1) {
6168 if (alt_grouplist != grouplist) {
6169 PyMem_Free(alt_grouplist);
6170 }
6171 return posix_error();
6172 }
6173#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006174 n = getgroups(MAX_GROUPS, grouplist);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006175 if (n < 0) {
6176 if (errno == EINVAL) {
6177 n = getgroups(0, NULL);
6178 if (n == -1) {
6179 return posix_error();
6180 }
6181 if (n == 0) {
6182 /* Avoid malloc(0) */
6183 alt_grouplist = grouplist;
6184 } else {
Serhiy Storchaka1a1ff292015-02-16 13:28:22 +02006185 alt_grouplist = PyMem_New(gid_t, n);
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006186 if (alt_grouplist == NULL) {
6187 errno = EINVAL;
6188 return posix_error();
6189 }
6190 n = getgroups(n, alt_grouplist);
6191 if (n == -1) {
6192 PyMem_Free(alt_grouplist);
6193 return posix_error();
6194 }
6195 }
6196 } else {
6197 return posix_error();
6198 }
6199 }
Ned Deilyb5dd6d22013-08-01 21:21:15 -07006200#endif
6201
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006202 result = PyList_New(n);
6203 if (result != NULL) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006204 int i;
6205 for (i = 0; i < n; ++i) {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006206 PyObject *o = _PyLong_FromGid(alt_grouplist[i]);
Victor Stinner8c62be82010-05-06 00:08:46 +00006207 if (o == NULL) {
Stefan Krah0e803b32010-11-26 16:16:47 +00006208 Py_DECREF(result);
6209 result = NULL;
6210 break;
Fred Drakec9680921999-12-13 16:37:25 +00006211 }
Victor Stinner8c62be82010-05-06 00:08:46 +00006212 PyList_SET_ITEM(result, i, o);
Fred Drakec9680921999-12-13 16:37:25 +00006213 }
Ronald Oussorenb6ee4f52010-07-23 13:53:51 +00006214 }
6215
6216 if (alt_grouplist != grouplist) {
6217 PyMem_Free(alt_grouplist);
Victor Stinner8c62be82010-05-06 00:08:46 +00006218 }
Neal Norwitze241ce82003-02-17 18:17:05 +00006219
Fred Drakec9680921999-12-13 16:37:25 +00006220 return result;
6221}
Larry Hastings2f936352014-08-05 14:04:04 +10006222#endif /* HAVE_GETGROUPS */
Fred Drakec9680921999-12-13 16:37:25 +00006223
Antoine Pitroub7572f02009-12-02 20:46:48 +00006224#ifdef HAVE_INITGROUPS
6225PyDoc_STRVAR(posix_initgroups__doc__,
6226"initgroups(username, gid) -> None\n\n\
6227Call the system initgroups() to initialize the group access list with all of\n\
6228the groups of which the specified username is a member, plus the specified\n\
6229group id.");
6230
Larry Hastings2f936352014-08-05 14:04:04 +10006231/* AC 3.5: funny apple logic */
Antoine Pitroub7572f02009-12-02 20:46:48 +00006232static PyObject *
6233posix_initgroups(PyObject *self, PyObject *args)
6234{
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006235 PyObject *oname;
Victor Stinner8c62be82010-05-06 00:08:46 +00006236 char *username;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006237 int res;
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006238#ifdef __APPLE__
6239 int gid;
6240#else
6241 gid_t gid;
6242#endif
Antoine Pitroub7572f02009-12-02 20:46:48 +00006243
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006244#ifdef __APPLE__
6245 if (!PyArg_ParseTuple(args, "O&i:initgroups",
6246 PyUnicode_FSConverter, &oname,
6247 &gid))
6248#else
6249 if (!PyArg_ParseTuple(args, "O&O&:initgroups",
6250 PyUnicode_FSConverter, &oname,
6251 _Py_Gid_Converter, &gid))
6252#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00006253 return NULL;
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006254 username = PyBytes_AS_STRING(oname);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006255
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006256 res = initgroups(username, gid);
Victor Stinner61ec5dc2010-08-15 09:22:44 +00006257 Py_DECREF(oname);
6258 if (res == -1)
Victor Stinner8c62be82010-05-06 00:08:46 +00006259 return PyErr_SetFromErrno(PyExc_OSError);
Antoine Pitroub7572f02009-12-02 20:46:48 +00006260
Victor Stinner8c62be82010-05-06 00:08:46 +00006261 Py_INCREF(Py_None);
6262 return Py_None;
Antoine Pitroub7572f02009-12-02 20:46:48 +00006263}
Larry Hastings2f936352014-08-05 14:04:04 +10006264#endif /* HAVE_INITGROUPS */
6265
Antoine Pitroub7572f02009-12-02 20:46:48 +00006266
Martin v. Löwis606edc12002-06-13 21:09:11 +00006267#ifdef HAVE_GETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10006268/*[clinic input]
6269os.getpgid
6270
6271 pid: pid_t
6272
6273Call the system call getpgid(), and return the result.
6274[clinic start generated code]*/
6275
Larry Hastings2f936352014-08-05 14:04:04 +10006276static PyObject *
6277os_getpgid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006278/*[clinic end generated code: output=70e713b4d54b7c61 input=39d710ae3baaf1c7]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006279{
6280 pid_t pgid = getpgid(pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006281 if (pgid < 0)
6282 return posix_error();
6283 return PyLong_FromPid(pgid);
Martin v. Löwis606edc12002-06-13 21:09:11 +00006284}
6285#endif /* HAVE_GETPGID */
6286
6287
Guido van Rossumb6775db1994-08-01 11:34:53 +00006288#ifdef HAVE_GETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006289/*[clinic input]
6290os.getpgrp
6291
6292Return the current process group id.
6293[clinic start generated code]*/
6294
Larry Hastings2f936352014-08-05 14:04:04 +10006295static PyObject *
6296os_getpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006297/*[clinic end generated code: output=cf3403585846811f input=6846fb2bb9a3705e]*/
Guido van Rossum04814471991-06-04 20:23:49 +00006298{
Guido van Rossumb6775db1994-08-01 11:34:53 +00006299#ifdef GETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006300 return PyLong_FromPid(getpgrp(0));
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006301#else /* GETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006302 return PyLong_FromPid(getpgrp());
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006303#endif /* GETPGRP_HAVE_ARG */
Guido van Rossum04814471991-06-04 20:23:49 +00006304}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006305#endif /* HAVE_GETPGRP */
Guido van Rossum04814471991-06-04 20:23:49 +00006306
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006307
Guido van Rossumb6775db1994-08-01 11:34:53 +00006308#ifdef HAVE_SETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10006309/*[clinic input]
6310os.setpgrp
6311
6312Make the current process the leader of its process group.
6313[clinic start generated code]*/
6314
Larry Hastings2f936352014-08-05 14:04:04 +10006315static PyObject *
6316os_setpgrp_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006317/*[clinic end generated code: output=59650f55a963d7ac input=1f0619fcb5731e7e]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00006318{
Guido van Rossum64933891994-10-20 21:56:42 +00006319#ifdef SETPGRP_HAVE_ARG
Victor Stinner8c62be82010-05-06 00:08:46 +00006320 if (setpgrp(0, 0) < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006321#else /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006322 if (setpgrp() < 0)
Guido van Rossum64933891994-10-20 21:56:42 +00006323#endif /* SETPGRP_HAVE_ARG */
Victor Stinner8c62be82010-05-06 00:08:46 +00006324 return posix_error();
6325 Py_INCREF(Py_None);
6326 return Py_None;
Guido van Rossumc2670a01992-09-13 20:07:29 +00006327}
Guido van Rossumb6775db1994-08-01 11:34:53 +00006328#endif /* HAVE_SETPGRP */
6329
Guido van Rossumad0ee831995-03-01 10:34:45 +00006330#ifdef HAVE_GETPPID
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006331
6332#ifdef MS_WINDOWS
6333#include <tlhelp32.h>
6334
6335static PyObject*
6336win32_getppid()
6337{
6338 HANDLE snapshot;
6339 pid_t mypid;
6340 PyObject* result = NULL;
6341 BOOL have_record;
6342 PROCESSENTRY32 pe;
6343
6344 mypid = getpid(); /* This function never fails */
6345
6346 snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
6347 if (snapshot == INVALID_HANDLE_VALUE)
6348 return PyErr_SetFromWindowsErr(GetLastError());
6349
6350 pe.dwSize = sizeof(pe);
6351 have_record = Process32First(snapshot, &pe);
6352 while (have_record) {
6353 if (mypid == (pid_t)pe.th32ProcessID) {
6354 /* We could cache the ulong value in a static variable. */
6355 result = PyLong_FromPid((pid_t)pe.th32ParentProcessID);
6356 break;
6357 }
6358
6359 have_record = Process32Next(snapshot, &pe);
6360 }
6361
6362 /* If our loop exits and our pid was not found (result will be NULL)
6363 * then GetLastError will return ERROR_NO_MORE_FILES. This is an
6364 * error anyway, so let's raise it. */
6365 if (!result)
6366 result = PyErr_SetFromWindowsErr(GetLastError());
6367
6368 CloseHandle(snapshot);
6369
6370 return result;
6371}
6372#endif /*MS_WINDOWS*/
6373
Larry Hastings2f936352014-08-05 14:04:04 +10006374
6375/*[clinic input]
6376os.getppid
6377
6378Return the parent's process id.
6379
6380If the parent process has already exited, Windows machines will still
6381return its id; others systems will return the id of the 'init' process (1).
6382[clinic start generated code]*/
6383
Larry Hastings2f936352014-08-05 14:04:04 +10006384static PyObject *
6385os_getppid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006386/*[clinic end generated code: output=4e49c8e7a8738cd2 input=e637cb87539c030e]*/
Guido van Rossum85e3b011991-06-03 12:42:10 +00006387{
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006388#ifdef MS_WINDOWS
6389 return win32_getppid();
6390#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006391 return PyLong_FromPid(getppid());
Guido van Rossumad0ee831995-03-01 10:34:45 +00006392#endif
Amaury Forgeot d'Arc4b6fdf32010-09-07 21:31:17 +00006393}
6394#endif /* HAVE_GETPPID */
Guido van Rossum85e3b011991-06-03 12:42:10 +00006395
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006396
Fred Drake12c6e2d1999-12-14 21:25:03 +00006397#ifdef HAVE_GETLOGIN
Larry Hastings2f936352014-08-05 14:04:04 +10006398/*[clinic input]
6399os.getlogin
6400
6401Return the actual login name.
6402[clinic start generated code]*/
6403
Larry Hastings2f936352014-08-05 14:04:04 +10006404static PyObject *
6405os_getlogin_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006406/*[clinic end generated code: output=037ebdb3e4b5dac1 input=2a21ab1e917163df]*/
Fred Drake12c6e2d1999-12-14 21:25:03 +00006407{
Victor Stinner8c62be82010-05-06 00:08:46 +00006408 PyObject *result = NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006409#ifdef MS_WINDOWS
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006410 wchar_t user_name[UNLEN + 1];
Victor Stinner63941882011-09-29 00:42:28 +02006411 DWORD num_chars = Py_ARRAY_LENGTH(user_name);
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006412
6413 if (GetUserNameW(user_name, &num_chars)) {
6414 /* num_chars is the number of unicode chars plus null terminator */
6415 result = PyUnicode_FromWideChar(user_name, num_chars - 1);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00006416 }
6417 else
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006418 result = PyErr_SetFromWindowsErr(GetLastError());
6419#else
Victor Stinner8c62be82010-05-06 00:08:46 +00006420 char *name;
6421 int old_errno = errno;
Fred Drake12c6e2d1999-12-14 21:25:03 +00006422
Victor Stinner8c62be82010-05-06 00:08:46 +00006423 errno = 0;
6424 name = getlogin();
6425 if (name == NULL) {
6426 if (errno)
Victor Stinnere039ffe2010-08-15 09:33:08 +00006427 posix_error();
Fred Drake12c6e2d1999-12-14 21:25:03 +00006428 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006429 PyErr_SetString(PyExc_OSError, "unable to determine login name");
Victor Stinner8c62be82010-05-06 00:08:46 +00006430 }
6431 else
Victor Stinnere039ffe2010-08-15 09:33:08 +00006432 result = PyUnicode_DecodeFSDefault(name);
Victor Stinner8c62be82010-05-06 00:08:46 +00006433 errno = old_errno;
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006434#endif
Fred Drake12c6e2d1999-12-14 21:25:03 +00006435 return result;
6436}
Brian Curtine8e4b3b2010-09-23 20:04:14 +00006437#endif /* HAVE_GETLOGIN */
Fred Drake12c6e2d1999-12-14 21:25:03 +00006438
Larry Hastings2f936352014-08-05 14:04:04 +10006439
Guido van Rossumad0ee831995-03-01 10:34:45 +00006440#ifdef HAVE_GETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006441/*[clinic input]
6442os.getuid
6443
6444Return the current process's user id.
6445[clinic start generated code]*/
6446
Larry Hastings2f936352014-08-05 14:04:04 +10006447static PyObject *
6448os_getuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006449/*[clinic end generated code: output=03a8b894cefb3fa5 input=b53c8b35f110a516]*/
Guido van Rossum46003ff1992-05-15 11:05:24 +00006450{
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006451 return _PyLong_FromUid(getuid());
Guido van Rossum46003ff1992-05-15 11:05:24 +00006452}
Larry Hastings2f936352014-08-05 14:04:04 +10006453#endif /* HAVE_GETUID */
Guido van Rossum46003ff1992-05-15 11:05:24 +00006454
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006455
Brian Curtineb24d742010-04-12 17:16:38 +00006456#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10006457#define HAVE_KILL
6458#endif /* MS_WINDOWS */
6459
6460#ifdef HAVE_KILL
6461/*[clinic input]
6462os.kill
6463
6464 pid: pid_t
6465 signal: Py_ssize_t
6466 /
6467
6468Kill a process with a signal.
6469[clinic start generated code]*/
6470
Larry Hastings2f936352014-08-05 14:04:04 +10006471static PyObject *
6472os_kill_impl(PyModuleDef *module, pid_t pid, Py_ssize_t signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006473/*[clinic end generated code: output=74f907dd00a83c26 input=61a36b86ca275ab9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006474#ifndef MS_WINDOWS
6475{
6476 if (kill(pid, (int)signal) == -1)
6477 return posix_error();
6478 Py_RETURN_NONE;
6479}
6480#else /* !MS_WINDOWS */
Brian Curtineb24d742010-04-12 17:16:38 +00006481{
Amaury Forgeot d'Arc0a589c92010-05-15 20:35:12 +00006482 PyObject *result;
Larry Hastings2f936352014-08-05 14:04:04 +10006483 DWORD sig = (DWORD)signal;
6484 DWORD err;
Victor Stinner8c62be82010-05-06 00:08:46 +00006485 HANDLE handle;
Brian Curtineb24d742010-04-12 17:16:38 +00006486
Victor Stinner8c62be82010-05-06 00:08:46 +00006487 /* Console processes which share a common console can be sent CTRL+C or
6488 CTRL+BREAK events, provided they handle said events. */
6489 if (sig == CTRL_C_EVENT || sig == CTRL_BREAK_EVENT) {
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006490 if (GenerateConsoleCtrlEvent(sig, (DWORD)pid) == 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006491 err = GetLastError();
6492 PyErr_SetFromWindowsErr(err);
6493 }
6494 else
6495 Py_RETURN_NONE;
6496 }
Brian Curtineb24d742010-04-12 17:16:38 +00006497
Victor Stinner8c62be82010-05-06 00:08:46 +00006498 /* If the signal is outside of what GenerateConsoleCtrlEvent can use,
6499 attempt to open and terminate the process. */
Richard Oudkerkac0ad882013-06-05 23:29:30 +01006500 handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)pid);
Victor Stinner8c62be82010-05-06 00:08:46 +00006501 if (handle == NULL) {
6502 err = GetLastError();
6503 return PyErr_SetFromWindowsErr(err);
6504 }
Brian Curtineb24d742010-04-12 17:16:38 +00006505
Victor Stinner8c62be82010-05-06 00:08:46 +00006506 if (TerminateProcess(handle, sig) == 0) {
6507 err = GetLastError();
6508 result = PyErr_SetFromWindowsErr(err);
6509 } else {
6510 Py_INCREF(Py_None);
6511 result = Py_None;
6512 }
Brian Curtineb24d742010-04-12 17:16:38 +00006513
Victor Stinner8c62be82010-05-06 00:08:46 +00006514 CloseHandle(handle);
6515 return result;
Brian Curtineb24d742010-04-12 17:16:38 +00006516}
Larry Hastings2f936352014-08-05 14:04:04 +10006517#endif /* !MS_WINDOWS */
6518#endif /* HAVE_KILL */
6519
6520
6521#ifdef HAVE_KILLPG
6522/*[clinic input]
6523os.killpg
6524
6525 pgid: pid_t
6526 signal: int
6527 /
6528
6529Kill a process group with a signal.
6530[clinic start generated code]*/
6531
Larry Hastings2f936352014-08-05 14:04:04 +10006532static PyObject *
6533os_killpg_impl(PyModuleDef *module, pid_t pgid, int signal)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006534/*[clinic end generated code: output=3434a766ef945f93 input=38b5449eb8faec19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006535{
6536 /* XXX some man pages make the `pgid` parameter an int, others
6537 a pid_t. Since getpgrp() returns a pid_t, we assume killpg should
6538 take the same type. Moreover, pid_t is always at least as wide as
6539 int (else compilation of this module fails), which is safe. */
6540 if (killpg(pgid, signal) == -1)
6541 return posix_error();
6542 Py_RETURN_NONE;
6543}
6544#endif /* HAVE_KILLPG */
6545
Brian Curtineb24d742010-04-12 17:16:38 +00006546
Guido van Rossumc0125471996-06-28 18:55:32 +00006547#ifdef HAVE_PLOCK
Guido van Rossumc0125471996-06-28 18:55:32 +00006548#ifdef HAVE_SYS_LOCK_H
6549#include <sys/lock.h>
6550#endif
6551
Larry Hastings2f936352014-08-05 14:04:04 +10006552/*[clinic input]
6553os.plock
6554 op: int
6555 /
6556
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +00006557Lock program segments into memory.");
Larry Hastings2f936352014-08-05 14:04:04 +10006558[clinic start generated code]*/
6559
Larry Hastings2f936352014-08-05 14:04:04 +10006560static PyObject *
6561os_plock_impl(PyModuleDef *module, int op)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006562/*[clinic end generated code: output=5cb851f81b914984 input=e6e5e348e1525f60]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006563{
Victor Stinner8c62be82010-05-06 00:08:46 +00006564 if (plock(op) == -1)
6565 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006566 Py_RETURN_NONE;
Guido van Rossumc0125471996-06-28 18:55:32 +00006567}
Larry Hastings2f936352014-08-05 14:04:04 +10006568#endif /* HAVE_PLOCK */
6569
Guido van Rossumc0125471996-06-28 18:55:32 +00006570
Guido van Rossumb6775db1994-08-01 11:34:53 +00006571#ifdef HAVE_SETUID
Larry Hastings2f936352014-08-05 14:04:04 +10006572/*[clinic input]
6573os.setuid
6574
6575 uid: uid_t
6576 /
6577
6578Set the current process's user id.
6579[clinic start generated code]*/
6580
Larry Hastings2f936352014-08-05 14:04:04 +10006581static PyObject *
6582os_setuid_impl(PyModuleDef *module, uid_t uid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006583/*[clinic end generated code: output=941ea9a8d1e5d565 input=c921a3285aa22256]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006584{
Victor Stinner8c62be82010-05-06 00:08:46 +00006585 if (setuid(uid) < 0)
6586 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006587 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006588}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006589#endif /* HAVE_SETUID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006590
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006591
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006592#ifdef HAVE_SETEUID
Larry Hastings2f936352014-08-05 14:04:04 +10006593/*[clinic input]
6594os.seteuid
6595
6596 euid: uid_t
6597 /
6598
6599Set the current process's effective user id.
6600[clinic start generated code]*/
6601
Larry Hastings2f936352014-08-05 14:04:04 +10006602static PyObject *
6603os_seteuid_impl(PyModuleDef *module, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006604/*[clinic end generated code: output=66f4f6823a648d6d input=ba93d927e4781aa9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006605{
6606 if (seteuid(euid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006607 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006608 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006609}
6610#endif /* HAVE_SETEUID */
6611
Larry Hastings2f936352014-08-05 14:04:04 +10006612
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006613#ifdef HAVE_SETEGID
Larry Hastings2f936352014-08-05 14:04:04 +10006614/*[clinic input]
6615os.setegid
6616
6617 egid: gid_t
6618 /
6619
6620Set the current process's effective group id.
6621[clinic start generated code]*/
6622
Larry Hastings2f936352014-08-05 14:04:04 +10006623static PyObject *
6624os_setegid_impl(PyModuleDef *module, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006625/*[clinic end generated code: output=ca094a69a081a60f input=4080526d0ccd6ce3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006626{
6627 if (setegid(egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006628 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006629 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006630}
6631#endif /* HAVE_SETEGID */
6632
Larry Hastings2f936352014-08-05 14:04:04 +10006633
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006634#ifdef HAVE_SETREUID
Larry Hastings2f936352014-08-05 14:04:04 +10006635/*[clinic input]
6636os.setreuid
6637
6638 ruid: uid_t
6639 euid: uid_t
6640 /
6641
6642Set the current process's real and effective user ids.
6643[clinic start generated code]*/
6644
Larry Hastings2f936352014-08-05 14:04:04 +10006645static PyObject *
6646os_setreuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006647/*[clinic end generated code: output=b2938c3e73d27ec7 input=0ca8978de663880c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006648{
Victor Stinner8c62be82010-05-06 00:08:46 +00006649 if (setreuid(ruid, euid) < 0) {
6650 return posix_error();
6651 } else {
6652 Py_INCREF(Py_None);
6653 return Py_None;
6654 }
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006655}
6656#endif /* HAVE_SETREUID */
6657
Larry Hastings2f936352014-08-05 14:04:04 +10006658
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006659#ifdef HAVE_SETREGID
Larry Hastings2f936352014-08-05 14:04:04 +10006660/*[clinic input]
6661os.setregid
6662
6663 rgid: gid_t
6664 egid: gid_t
6665 /
6666
6667Set the current process's real and effective group ids.
6668[clinic start generated code]*/
6669
Larry Hastings2f936352014-08-05 14:04:04 +10006670static PyObject *
6671os_setregid_impl(PyModuleDef *module, gid_t rgid, gid_t egid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006672/*[clinic end generated code: output=db18f1839ababe3d input=c59499f72846db78]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006673{
6674 if (setregid(rgid, egid) < 0)
Victor Stinner8c62be82010-05-06 00:08:46 +00006675 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006676 Py_RETURN_NONE;
Andrew M. Kuchling8d2f2b2d2000-07-13 01:26:58 +00006677}
6678#endif /* HAVE_SETREGID */
6679
Larry Hastings2f936352014-08-05 14:04:04 +10006680
Guido van Rossumb6775db1994-08-01 11:34:53 +00006681#ifdef HAVE_SETGID
Larry Hastings2f936352014-08-05 14:04:04 +10006682/*[clinic input]
6683os.setgid
6684 gid: gid_t
6685 /
6686
6687Set the current process's group id.
6688[clinic start generated code]*/
6689
Larry Hastings2f936352014-08-05 14:04:04 +10006690static PyObject *
6691os_setgid_impl(PyModuleDef *module, gid_t gid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006692/*[clinic end generated code: output=756cb42c6abd9d87 input=27d30c4059045dc6]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006693{
Victor Stinner8c62be82010-05-06 00:08:46 +00006694 if (setgid(gid) < 0)
6695 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10006696 Py_RETURN_NONE;
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006697}
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00006698#endif /* HAVE_SETGID */
Guido van Rossuma3d78fb1993-11-10 09:23:53 +00006699
Larry Hastings2f936352014-08-05 14:04:04 +10006700
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006701#ifdef HAVE_SETGROUPS
Larry Hastings2f936352014-08-05 14:04:04 +10006702/*[clinic input]
6703os.setgroups
6704
6705 groups: object
6706 /
6707
6708Set the groups of the current process to list.
6709[clinic start generated code]*/
6710
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006711static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10006712os_setgroups(PyModuleDef *module, PyObject *groups)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006713/*[clinic end generated code: output=7945c2e3cc817c58 input=fa742ca3daf85a7e]*/
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006714{
Victor Stinner8c62be82010-05-06 00:08:46 +00006715 int i, len;
6716 gid_t grouplist[MAX_GROUPS];
Tim Peters5aa91602002-01-30 05:46:57 +00006717
Victor Stinner8c62be82010-05-06 00:08:46 +00006718 if (!PySequence_Check(groups)) {
6719 PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
6720 return NULL;
6721 }
6722 len = PySequence_Size(groups);
6723 if (len > MAX_GROUPS) {
6724 PyErr_SetString(PyExc_ValueError, "too many groups");
6725 return NULL;
6726 }
6727 for(i = 0; i < len; i++) {
6728 PyObject *elem;
6729 elem = PySequence_GetItem(groups, i);
6730 if (!elem)
6731 return NULL;
6732 if (!PyLong_Check(elem)) {
6733 PyErr_SetString(PyExc_TypeError,
6734 "groups must be integers");
6735 Py_DECREF(elem);
6736 return NULL;
6737 } else {
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006738 if (!_Py_Gid_Converter(elem, &grouplist[i])) {
Victor Stinner8c62be82010-05-06 00:08:46 +00006739 Py_DECREF(elem);
6740 return NULL;
6741 }
6742 }
6743 Py_DECREF(elem);
6744 }
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006745
Victor Stinner8c62be82010-05-06 00:08:46 +00006746 if (setgroups(len, grouplist) < 0)
6747 return posix_error();
6748 Py_INCREF(Py_None);
6749 return Py_None;
Martin v. Löwis61c5edf2001-10-18 04:06:00 +00006750}
6751#endif /* HAVE_SETGROUPS */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00006752
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006753#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
6754static PyObject *
Victor Stinner4195b5c2012-02-08 23:03:19 +01006755wait_helper(pid_t pid, int status, struct rusage *ru)
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006756{
Victor Stinner8c62be82010-05-06 00:08:46 +00006757 PyObject *result;
6758 static PyObject *struct_rusage;
Martin v. Löwisbd928fe2011-10-14 10:20:37 +02006759 _Py_IDENTIFIER(struct_rusage);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006760
Victor Stinner8c62be82010-05-06 00:08:46 +00006761 if (pid == -1)
6762 return posix_error();
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006763
Victor Stinner8c62be82010-05-06 00:08:46 +00006764 if (struct_rusage == NULL) {
6765 PyObject *m = PyImport_ImportModuleNoBlock("resource");
6766 if (m == NULL)
6767 return NULL;
Martin v. Löwis1ee1b6f2011-10-10 18:11:30 +02006768 struct_rusage = _PyObject_GetAttrId(m, &PyId_struct_rusage);
Victor Stinner8c62be82010-05-06 00:08:46 +00006769 Py_DECREF(m);
6770 if (struct_rusage == NULL)
6771 return NULL;
6772 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006773
Victor Stinner8c62be82010-05-06 00:08:46 +00006774 /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
6775 result = PyStructSequence_New((PyTypeObject*) struct_rusage);
6776 if (!result)
6777 return NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006778
6779#ifndef doubletime
6780#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
6781#endif
6782
Victor Stinner8c62be82010-05-06 00:08:46 +00006783 PyStructSequence_SET_ITEM(result, 0,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006784 PyFloat_FromDouble(doubletime(ru->ru_utime)));
Victor Stinner8c62be82010-05-06 00:08:46 +00006785 PyStructSequence_SET_ITEM(result, 1,
Victor Stinner4195b5c2012-02-08 23:03:19 +01006786 PyFloat_FromDouble(doubletime(ru->ru_stime)));
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006787#define SET_INT(result, index, value)\
Victor Stinner8c62be82010-05-06 00:08:46 +00006788 PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
6789 SET_INT(result, 2, ru->ru_maxrss);
6790 SET_INT(result, 3, ru->ru_ixrss);
6791 SET_INT(result, 4, ru->ru_idrss);
6792 SET_INT(result, 5, ru->ru_isrss);
6793 SET_INT(result, 6, ru->ru_minflt);
6794 SET_INT(result, 7, ru->ru_majflt);
6795 SET_INT(result, 8, ru->ru_nswap);
6796 SET_INT(result, 9, ru->ru_inblock);
6797 SET_INT(result, 10, ru->ru_oublock);
6798 SET_INT(result, 11, ru->ru_msgsnd);
6799 SET_INT(result, 12, ru->ru_msgrcv);
6800 SET_INT(result, 13, ru->ru_nsignals);
6801 SET_INT(result, 14, ru->ru_nvcsw);
6802 SET_INT(result, 15, ru->ru_nivcsw);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006803#undef SET_INT
6804
Victor Stinner8c62be82010-05-06 00:08:46 +00006805 if (PyErr_Occurred()) {
6806 Py_DECREF(result);
6807 return NULL;
6808 }
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006809
Victor Stinner8c62be82010-05-06 00:08:46 +00006810 return Py_BuildValue("NiN", PyLong_FromPid(pid), status, result);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006811}
6812#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
6813
Larry Hastings2f936352014-08-05 14:04:04 +10006814
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006815#ifdef HAVE_WAIT3
Larry Hastings2f936352014-08-05 14:04:04 +10006816/*[clinic input]
6817os.wait3
6818
6819 options: int
6820Wait for completion of a child process.
6821
6822Returns a tuple of information about the child process:
6823 (pid, status, rusage)
6824[clinic start generated code]*/
6825
Larry Hastings2f936352014-08-05 14:04:04 +10006826static PyObject *
6827os_wait3_impl(PyModuleDef *module, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006828/*[clinic end generated code: output=e18af4924dc54945 input=8ac4c56956b61710]*/
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006829{
Victor Stinner8c62be82010-05-06 00:08:46 +00006830 pid_t pid;
Victor Stinner8c62be82010-05-06 00:08:46 +00006831 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006832 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006833 WAIT_TYPE status;
6834 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006835
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006836 do {
6837 Py_BEGIN_ALLOW_THREADS
6838 pid = wait3(&status, options, &ru);
6839 Py_END_ALLOW_THREADS
6840 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6841 if (pid < 0)
6842 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006843
Victor Stinner4195b5c2012-02-08 23:03:19 +01006844 return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006845}
6846#endif /* HAVE_WAIT3 */
6847
Larry Hastings2f936352014-08-05 14:04:04 +10006848
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006849#ifdef HAVE_WAIT4
Larry Hastings2f936352014-08-05 14:04:04 +10006850/*[clinic input]
6851
6852os.wait4
6853
6854 pid: pid_t
6855 options: int
6856
6857Wait for completion of a specific child process.
6858
6859Returns a tuple of information about the child process:
6860 (pid, status, rusage)
6861[clinic start generated code]*/
6862
Larry Hastings2f936352014-08-05 14:04:04 +10006863static PyObject *
6864os_wait4_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006865/*[clinic end generated code: output=714f19e6ff01e099 input=d11deed0750600ba]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006866{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006867 pid_t res;
Victor Stinner8c62be82010-05-06 00:08:46 +00006868 struct rusage ru;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006869 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006870 WAIT_TYPE status;
6871 WAIT_STATUS_INT(status) = 0;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006872
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006873 do {
6874 Py_BEGIN_ALLOW_THREADS
6875 res = wait4(pid, &status, options, &ru);
6876 Py_END_ALLOW_THREADS
6877 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6878 if (res < 0)
6879 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006880
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006881 return wait_helper(res, WAIT_STATUS_INT(status), &ru);
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006882}
6883#endif /* HAVE_WAIT4 */
6884
Larry Hastings2f936352014-08-05 14:04:04 +10006885
Ross Lagerwall7807c352011-03-17 20:20:30 +02006886#if defined(HAVE_WAITID) && !defined(__APPLE__)
Larry Hastings2f936352014-08-05 14:04:04 +10006887/*[clinic input]
6888os.waitid
6889
6890 idtype: idtype_t
6891 Must be one of be P_PID, P_PGID or P_ALL.
6892 id: id_t
6893 The id to wait on.
6894 options: int
6895 Constructed from the ORing of one or more of WEXITED, WSTOPPED
6896 or WCONTINUED and additionally may be ORed with WNOHANG or WNOWAIT.
6897 /
6898
6899Returns the result of waiting for a process or processes.
6900
6901Returns either waitid_result or None if WNOHANG is specified and there are
6902no children in a waitable state.
6903[clinic start generated code]*/
6904
Larry Hastings2f936352014-08-05 14:04:04 +10006905static PyObject *
6906os_waitid_impl(PyModuleDef *module, idtype_t idtype, id_t id, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006907/*[clinic end generated code: output=5c0192750e22fa2e input=d8e7f76e052b7920]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006908{
6909 PyObject *result;
6910 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006911 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006912 siginfo_t si;
6913 si.si_pid = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10006914
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006915 do {
6916 Py_BEGIN_ALLOW_THREADS
6917 res = waitid(idtype, id, &si, options);
6918 Py_END_ALLOW_THREADS
6919 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6920 if (res < 0)
6921 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02006922
6923 if (si.si_pid == 0)
6924 Py_RETURN_NONE;
6925
6926 result = PyStructSequence_New(&WaitidResultType);
6927 if (!result)
6928 return NULL;
6929
6930 PyStructSequence_SET_ITEM(result, 0, PyLong_FromPid(si.si_pid));
Serhiy Storchaka7cf55992013-02-10 21:56:49 +02006931 PyStructSequence_SET_ITEM(result, 1, _PyLong_FromUid(si.si_uid));
Ross Lagerwall7807c352011-03-17 20:20:30 +02006932 PyStructSequence_SET_ITEM(result, 2, PyLong_FromLong((long)(si.si_signo)));
6933 PyStructSequence_SET_ITEM(result, 3, PyLong_FromLong((long)(si.si_status)));
6934 PyStructSequence_SET_ITEM(result, 4, PyLong_FromLong((long)(si.si_code)));
6935 if (PyErr_Occurred()) {
6936 Py_DECREF(result);
6937 return NULL;
6938 }
6939
6940 return result;
6941}
Larry Hastings2f936352014-08-05 14:04:04 +10006942#endif /* defined(HAVE_WAITID) && !defined(__APPLE__) */
Ross Lagerwall7807c352011-03-17 20:20:30 +02006943
Larry Hastings2f936352014-08-05 14:04:04 +10006944
6945#if defined(HAVE_WAITPID)
6946/*[clinic input]
6947os.waitpid
6948 pid: pid_t
6949 options: int
6950 /
6951
6952Wait for completion of a given child process.
6953
6954Returns a tuple of information regarding the child process:
6955 (pid, status)
6956
6957The options argument is ignored on Windows.
6958[clinic start generated code]*/
6959
Larry Hastings2f936352014-08-05 14:04:04 +10006960static PyObject *
6961os_waitpid_impl(PyModuleDef *module, pid_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006962/*[clinic end generated code: output=5e3593353d54b15b input=0bf1666b8758fda3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006963{
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006964 pid_t res;
6965 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00006966 WAIT_TYPE status;
6967 WAIT_STATUS_INT(status) = 0;
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00006968
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006969 do {
6970 Py_BEGIN_ALLOW_THREADS
6971 res = waitpid(pid, &status, options);
6972 Py_END_ALLOW_THREADS
6973 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
6974 if (res < 0)
6975 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00006976
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00006977 return Py_BuildValue("Ni", PyLong_FromPid(res), WAIT_STATUS_INT(status));
Guido van Rossum21803b81992-08-09 12:55:27 +00006978}
Tim Petersab034fa2002-02-01 11:27:43 +00006979#elif defined(HAVE_CWAIT)
Tim Petersab034fa2002-02-01 11:27:43 +00006980/* MS C has a variant of waitpid() that's usable for most purposes. */
Larry Hastings2f936352014-08-05 14:04:04 +10006981/*[clinic input]
6982os.waitpid
6983 pid: Py_intptr_t
6984 options: int
6985 /
6986
6987Wait for completion of a given process.
6988
6989Returns a tuple of information regarding the process:
6990 (pid, status << 8)
6991
6992The options argument is ignored on Windows.
6993[clinic start generated code]*/
6994
Larry Hastings2f936352014-08-05 14:04:04 +10006995static PyObject *
6996os_waitpid_impl(PyModuleDef *module, Py_intptr_t pid, int options)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03006997/*[clinic end generated code: output=fc1d520db019625f input=444c8f51cca5b862]*/
Larry Hastings2f936352014-08-05 14:04:04 +10006998{
6999 int status;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007000 Py_intptr_t res;
7001 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007002
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007003 do {
7004 Py_BEGIN_ALLOW_THREADS
7005 res = _cwait(&status, pid, options);
7006 Py_END_ALLOW_THREADS
7007 } while (res < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7008 if (res != 0)
7009 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007010
Victor Stinner8c62be82010-05-06 00:08:46 +00007011 /* shift the status left a byte so this is more like the POSIX waitpid */
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007012 return Py_BuildValue(_Py_PARSE_INTPTR "i", res, status << 8);
Tim Petersab034fa2002-02-01 11:27:43 +00007013}
Larry Hastings2f936352014-08-05 14:04:04 +10007014#endif
7015
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007016
Guido van Rossumad0ee831995-03-01 10:34:45 +00007017#ifdef HAVE_WAIT
Larry Hastings2f936352014-08-05 14:04:04 +10007018/*[clinic input]
7019os.wait
7020
7021Wait for completion of a child process.
7022
7023Returns a tuple of information about the child process:
7024 (pid, status)
7025[clinic start generated code]*/
7026
Larry Hastings2f936352014-08-05 14:04:04 +10007027static PyObject *
7028os_wait_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007029/*[clinic end generated code: output=4a7f4978393e0654 input=03b0182d4a4700ce]*/
Guido van Rossum21803b81992-08-09 12:55:27 +00007030{
Victor Stinner8c62be82010-05-06 00:08:46 +00007031 pid_t pid;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007032 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00007033 WAIT_TYPE status;
7034 WAIT_STATUS_INT(status) = 0;
Neal Norwitze241ce82003-02-17 18:17:05 +00007035
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007036 do {
7037 Py_BEGIN_ALLOW_THREADS
7038 pid = wait(&status);
7039 Py_END_ALLOW_THREADS
7040 } while (pid < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
7041 if (pid < 0)
7042 return (!async_err) ? posix_error() : NULL;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +00007043
Victor Stinner8c62be82010-05-06 00:08:46 +00007044 return Py_BuildValue("Ni", PyLong_FromPid(pid), WAIT_STATUS_INT(status));
Guido van Rossum85e3b011991-06-03 12:42:10 +00007045}
Larry Hastings2f936352014-08-05 14:04:04 +10007046#endif /* HAVE_WAIT */
Guido van Rossum85e3b011991-06-03 12:42:10 +00007047
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007048
Larry Hastings9cf065c2012-06-22 16:30:09 -07007049#if defined(HAVE_READLINK) || defined(MS_WINDOWS)
7050PyDoc_STRVAR(readlink__doc__,
7051"readlink(path, *, dir_fd=None) -> path\n\n\
7052Return a string representing the path to which the symbolic link points.\n\
7053\n\
7054If dir_fd is not None, it should be a file descriptor open to a directory,\n\
7055 and path should be relative; path will then be relative to that directory.\n\
7056dir_fd may not be implemented on your platform.\n\
7057 If it is unavailable, using it will raise a NotImplementedError.");
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007058#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007059
Guido van Rossumb6775db1994-08-01 11:34:53 +00007060#ifdef HAVE_READLINK
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007061
Larry Hastings2f936352014-08-05 14:04:04 +10007062/* AC 3.5: merge win32 and not together */
Barry Warsaw53699e91996-12-10 23:23:01 +00007063static PyObject *
Larry Hastings9cf065c2012-06-22 16:30:09 -07007064posix_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007065{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007066 path_t path;
7067 int dir_fd = DEFAULT_DIR_FD;
7068 char buffer[MAXPATHLEN];
7069 ssize_t length;
7070 PyObject *return_value = NULL;
7071 static char *keywords[] = {"path", "dir_fd", NULL};
Thomas Wouters89f507f2006-12-13 04:49:30 +00007072
Larry Hastings9cf065c2012-06-22 16:30:09 -07007073 memset(&path, 0, sizeof(path));
Victor Stinner292c8352012-10-30 02:17:38 +01007074 path.function_name = "readlink";
Larry Hastings9cf065c2012-06-22 16:30:09 -07007075 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O&|$O&:readlink", keywords,
7076 path_converter, &path,
Larry Hastings2f936352014-08-05 14:04:04 +10007077 READLINKAT_DIR_FD_CONVERTER, &dir_fd))
Victor Stinner8c62be82010-05-06 00:08:46 +00007078 return NULL;
Thomas Wouters89f507f2006-12-13 04:49:30 +00007079
Victor Stinner8c62be82010-05-06 00:08:46 +00007080 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007081#ifdef HAVE_READLINKAT
7082 if (dir_fd != DEFAULT_DIR_FD)
7083 length = readlinkat(dir_fd, path.narrow, buffer, sizeof(buffer));
Victor Stinnera45598a2010-05-14 16:35:39 +00007084 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007085#endif
7086 length = readlink(path.narrow, buffer, sizeof(buffer));
7087 Py_END_ALLOW_THREADS
7088
7089 if (length < 0) {
Victor Stinner292c8352012-10-30 02:17:38 +01007090 return_value = path_error(&path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007091 goto exit;
7092 }
7093
7094 if (PyUnicode_Check(path.object))
7095 return_value = PyUnicode_DecodeFSDefaultAndSize(buffer, length);
7096 else
7097 return_value = PyBytes_FromStringAndSize(buffer, length);
7098exit:
7099 path_cleanup(&path);
7100 return return_value;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007101}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007102
Guido van Rossumb6775db1994-08-01 11:34:53 +00007103#endif /* HAVE_READLINK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +00007104
Larry Hastings2f936352014-08-05 14:04:04 +10007105#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
7106
7107static PyObject *
7108win_readlink(PyObject *self, PyObject *args, PyObject *kwargs)
7109{
7110 wchar_t *path;
7111 DWORD n_bytes_returned;
7112 DWORD io_result;
7113 PyObject *po, *result;
7114 int dir_fd;
7115 HANDLE reparse_point_handle;
7116
7117 char target_buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
7118 REPARSE_DATA_BUFFER *rdb = (REPARSE_DATA_BUFFER *)target_buffer;
7119 wchar_t *print_name;
7120
7121 static char *keywords[] = {"path", "dir_fd", NULL};
7122
7123 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "U|$O&:readlink", keywords,
7124 &po,
7125 dir_fd_unavailable, &dir_fd
7126 ))
7127 return NULL;
7128
7129 path = PyUnicode_AsUnicode(po);
7130 if (path == NULL)
7131 return NULL;
7132
7133 /* First get a handle to the reparse point */
7134 Py_BEGIN_ALLOW_THREADS
7135 reparse_point_handle = CreateFileW(
7136 path,
7137 0,
7138 0,
7139 0,
7140 OPEN_EXISTING,
7141 FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS,
7142 0);
7143 Py_END_ALLOW_THREADS
7144
7145 if (reparse_point_handle==INVALID_HANDLE_VALUE)
7146 return win32_error_object("readlink", po);
7147
7148 Py_BEGIN_ALLOW_THREADS
7149 /* New call DeviceIoControl to read the reparse point */
7150 io_result = DeviceIoControl(
7151 reparse_point_handle,
7152 FSCTL_GET_REPARSE_POINT,
7153 0, 0, /* in buffer */
7154 target_buffer, sizeof(target_buffer),
7155 &n_bytes_returned,
7156 0 /* we're not using OVERLAPPED_IO */
7157 );
7158 CloseHandle(reparse_point_handle);
7159 Py_END_ALLOW_THREADS
7160
7161 if (io_result==0)
7162 return win32_error_object("readlink", po);
7163
7164 if (rdb->ReparseTag != IO_REPARSE_TAG_SYMLINK)
7165 {
7166 PyErr_SetString(PyExc_ValueError,
7167 "not a symbolic link");
7168 return NULL;
7169 }
7170 print_name = rdb->SymbolicLinkReparseBuffer.PathBuffer +
7171 rdb->SymbolicLinkReparseBuffer.PrintNameOffset;
7172
7173 result = PyUnicode_FromWideChar(print_name,
7174 rdb->SymbolicLinkReparseBuffer.PrintNameLength/2);
7175 return result;
7176}
7177
7178#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
7179
7180
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007181
Larry Hastings9cf065c2012-06-22 16:30:09 -07007182#ifdef HAVE_SYMLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -07007183
7184#if defined(MS_WINDOWS)
7185
7186/* Grab CreateSymbolicLinkW dynamically from kernel32 */
7187static DWORD (CALLBACK *Py_CreateSymbolicLinkW)(LPWSTR, LPWSTR, DWORD) = NULL;
7188static DWORD (CALLBACK *Py_CreateSymbolicLinkA)(LPSTR, LPSTR, DWORD) = NULL;
Victor Stinner31b3b922013-06-05 01:49:17 +02007189
Larry Hastings9cf065c2012-06-22 16:30:09 -07007190static int
Victor Stinner31b3b922013-06-05 01:49:17 +02007191check_CreateSymbolicLink(void)
Larry Hastings9cf065c2012-06-22 16:30:09 -07007192{
7193 HINSTANCE hKernel32;
7194 /* only recheck */
7195 if (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA)
7196 return 1;
7197 hKernel32 = GetModuleHandleW(L"KERNEL32");
7198 *(FARPROC*)&Py_CreateSymbolicLinkW = GetProcAddress(hKernel32,
7199 "CreateSymbolicLinkW");
7200 *(FARPROC*)&Py_CreateSymbolicLinkA = GetProcAddress(hKernel32,
7201 "CreateSymbolicLinkA");
7202 return (Py_CreateSymbolicLinkW && Py_CreateSymbolicLinkA);
7203}
7204
Victor Stinner31b3b922013-06-05 01:49:17 +02007205/* Remove the last portion of the path */
7206static void
7207_dirnameW(WCHAR *path)
7208{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007209 WCHAR *ptr;
7210
7211 /* walk the path from the end until a backslash is encountered */
Victor Stinner31b3b922013-06-05 01:49:17 +02007212 for(ptr = path + wcslen(path); ptr != path; ptr--) {
Victor Stinner072318b2013-06-05 02:07:46 +02007213 if (*ptr == L'\\' || *ptr == L'/')
Jason R. Coombs3a092862013-05-27 23:21:28 -04007214 break;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007215 }
7216 *ptr = 0;
7217}
7218
Victor Stinner31b3b922013-06-05 01:49:17 +02007219/* Remove the last portion of the path */
7220static void
7221_dirnameA(char *path)
7222{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007223 char *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 + strlen(path); ptr != path; ptr--) {
7227 if (*ptr == '\\' || *ptr == '/')
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/* Is this path absolute? */
7234static int
7235_is_absW(const WCHAR *path)
7236{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007237 return path[0] == L'\\' || path[0] == L'/' || path[1] == L':';
7238
7239}
7240
Victor Stinner31b3b922013-06-05 01:49:17 +02007241/* Is this path absolute? */
7242static int
7243_is_absA(const char *path)
7244{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007245 return path[0] == '\\' || path[0] == '/' || path[1] == ':';
7246
7247}
7248
Victor Stinner31b3b922013-06-05 01:49:17 +02007249/* join root and rest with a backslash */
7250static void
7251_joinW(WCHAR *dest_path, const WCHAR *root, const WCHAR *rest)
7252{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007253 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007254
Victor Stinner31b3b922013-06-05 01:49:17 +02007255 if (_is_absW(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007256 wcscpy(dest_path, rest);
7257 return;
7258 }
7259
7260 root_len = wcslen(root);
7261
7262 wcscpy(dest_path, root);
7263 if(root_len) {
Victor Stinner31b3b922013-06-05 01:49:17 +02007264 dest_path[root_len] = L'\\';
7265 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007266 }
7267 wcscpy(dest_path+root_len, rest);
7268}
7269
Victor Stinner31b3b922013-06-05 01:49:17 +02007270/* join root and rest with a backslash */
7271static void
7272_joinA(char *dest_path, const char *root, const char *rest)
7273{
Victor Stinnere7e7eba2013-06-05 00:35:54 +02007274 size_t root_len;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007275
Victor Stinner31b3b922013-06-05 01:49:17 +02007276 if (_is_absA(rest)) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007277 strcpy(dest_path, rest);
7278 return;
7279 }
7280
7281 root_len = strlen(root);
7282
7283 strcpy(dest_path, root);
7284 if(root_len) {
7285 dest_path[root_len] = '\\';
Victor Stinner31b3b922013-06-05 01:49:17 +02007286 root_len++;
Jason R. Coombs3a092862013-05-27 23:21:28 -04007287 }
7288 strcpy(dest_path+root_len, rest);
7289}
7290
Victor Stinner31b3b922013-06-05 01:49:17 +02007291/* Return True if the path at src relative to dest is a directory */
7292static int
7293_check_dirW(WCHAR *src, WCHAR *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007294{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007295 WIN32_FILE_ATTRIBUTE_DATA src_info;
7296 WCHAR dest_parent[MAX_PATH];
7297 WCHAR src_resolved[MAX_PATH] = L"";
7298
7299 /* dest_parent = os.path.dirname(dest) */
7300 wcscpy(dest_parent, dest);
7301 _dirnameW(dest_parent);
7302 /* src_resolved = os.path.join(dest_parent, src) */
7303 _joinW(src_resolved, dest_parent, src);
7304 return (
7305 GetFileAttributesExW(src_resolved, GetFileExInfoStandard, &src_info)
7306 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7307 );
7308}
7309
Victor Stinner31b3b922013-06-05 01:49:17 +02007310/* Return True if the path at src relative to dest is a directory */
7311static int
7312_check_dirA(char *src, char *dest)
Jason R. Coombs3a092862013-05-27 23:21:28 -04007313{
Jason R. Coombs3a092862013-05-27 23:21:28 -04007314 WIN32_FILE_ATTRIBUTE_DATA src_info;
7315 char dest_parent[MAX_PATH];
7316 char src_resolved[MAX_PATH] = "";
7317
7318 /* dest_parent = os.path.dirname(dest) */
7319 strcpy(dest_parent, dest);
Victor Stinner5a436762013-06-05 00:37:12 +02007320 _dirnameA(dest_parent);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007321 /* src_resolved = os.path.join(dest_parent, src) */
Victor Stinner5a436762013-06-05 00:37:12 +02007322 _joinA(src_resolved, dest_parent, src);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007323 return (
7324 GetFileAttributesExA(src_resolved, GetFileExInfoStandard, &src_info)
7325 && src_info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY
7326 );
7327}
Larry Hastings9cf065c2012-06-22 16:30:09 -07007328#endif
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007329
Larry Hastings2f936352014-08-05 14:04:04 +10007330
7331/*[clinic input]
7332os.symlink
7333 src: path_t
7334 dst: path_t
7335 target_is_directory: bool = False
7336 *
7337 dir_fd: dir_fd(requires='symlinkat')=None
7338
7339# "symlink(src, dst, target_is_directory=False, *, dir_fd=None)\n\n\
7340
7341Create a symbolic link pointing to src named dst.
7342
7343target_is_directory is required on Windows if the target is to be
7344 interpreted as a directory. (On Windows, symlink requires
7345 Windows 6.0 or greater, and raises a NotImplementedError otherwise.)
7346 target_is_directory is ignored on non-Windows platforms.
7347
7348If dir_fd is not None, it should be a file descriptor open to a directory,
7349 and path should be relative; path will then be relative to that directory.
7350dir_fd may not be implemented on your platform.
7351 If it is unavailable, using it will raise a NotImplementedError.
7352
7353[clinic start generated code]*/
7354
Larry Hastings2f936352014-08-05 14:04:04 +10007355static PyObject *
7356os_symlink_impl(PyModuleDef *module, path_t *src, path_t *dst, int target_is_directory, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007357/*[clinic end generated code: output=11aa03f278bb2c8a input=e820ec4472547bc3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007358{
Larry Hastings9cf065c2012-06-22 16:30:09 -07007359#ifdef MS_WINDOWS
7360 DWORD result;
7361#else
7362 int result;
7363#endif
7364
Larry Hastings9cf065c2012-06-22 16:30:09 -07007365#ifdef MS_WINDOWS
7366 if (!check_CreateSymbolicLink()) {
7367 PyErr_SetString(PyExc_NotImplementedError,
7368 "CreateSymbolicLink functions not found");
Larry Hastings2f936352014-08-05 14:04:04 +10007369 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007370 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007371 if (!win32_can_symlink) {
7372 PyErr_SetString(PyExc_OSError, "symbolic link privilege not held");
Larry Hastings2f936352014-08-05 14:04:04 +10007373 return NULL;
Petri Lehtinen5445a8c2012-10-23 16:12:14 +03007374 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007375#endif
7376
Larry Hastings2f936352014-08-05 14:04:04 +10007377 if ((src->narrow && dst->wide) || (src->wide && dst->narrow)) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07007378 PyErr_SetString(PyExc_ValueError,
7379 "symlink: src and dst must be the same type");
Larry Hastings2f936352014-08-05 14:04:04 +10007380 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007381 }
7382
7383#ifdef MS_WINDOWS
Jason R. Coombs3a092862013-05-27 23:21:28 -04007384
Larry Hastings9cf065c2012-06-22 16:30:09 -07007385 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007386 if (dst->wide) {
Jason R. Coombs3a092862013-05-27 23:21:28 -04007387 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007388 target_is_directory |= _check_dirW(src->wide, dst->wide);
7389 result = Py_CreateSymbolicLinkW(dst->wide, src->wide,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007390 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007391 }
7392 else {
7393 /* if src is a directory, ensure target_is_directory==1 */
Larry Hastings2f936352014-08-05 14:04:04 +10007394 target_is_directory |= _check_dirA(src->narrow, dst->narrow);
7395 result = Py_CreateSymbolicLinkA(dst->narrow, src->narrow,
Larry Hastings9cf065c2012-06-22 16:30:09 -07007396 target_is_directory);
Jason R. Coombs3a092862013-05-27 23:21:28 -04007397 }
Larry Hastings9cf065c2012-06-22 16:30:09 -07007398 Py_END_ALLOW_THREADS
7399
Larry Hastings2f936352014-08-05 14:04:04 +10007400 if (!result)
7401 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007402
7403#else
7404
7405 Py_BEGIN_ALLOW_THREADS
7406#if HAVE_SYMLINKAT
7407 if (dir_fd != DEFAULT_DIR_FD)
Larry Hastings2f936352014-08-05 14:04:04 +10007408 result = symlinkat(src->narrow, dir_fd, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007409 else
7410#endif
Larry Hastings2f936352014-08-05 14:04:04 +10007411 result = symlink(src->narrow, dst->narrow);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007412 Py_END_ALLOW_THREADS
7413
Larry Hastings2f936352014-08-05 14:04:04 +10007414 if (result)
7415 return path_error2(src, dst);
Larry Hastings9cf065c2012-06-22 16:30:09 -07007416#endif
7417
Larry Hastings2f936352014-08-05 14:04:04 +10007418 Py_RETURN_NONE;
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007419}
7420#endif /* HAVE_SYMLINK */
7421
Larry Hastings9cf065c2012-06-22 16:30:09 -07007422
Brian Curtind40e6f72010-07-08 21:39:08 +00007423
Guido van Rossumbfaf3d61997-12-29 20:02:27 +00007424
Larry Hastings605a62d2012-06-24 04:33:36 -07007425static PyStructSequence_Field times_result_fields[] = {
7426 {"user", "user time"},
7427 {"system", "system time"},
7428 {"children_user", "user time of children"},
7429 {"children_system", "system time of children"},
7430 {"elapsed", "elapsed time since an arbitrary point in the past"},
7431 {NULL}
7432};
7433
7434PyDoc_STRVAR(times_result__doc__,
7435"times_result: Result from os.times().\n\n\
7436This object may be accessed either as a tuple of\n\
7437 (user, system, children_user, children_system, elapsed),\n\
7438or via the attributes user, system, children_user, children_system,\n\
7439and elapsed.\n\
7440\n\
7441See os.times for more information.");
7442
7443static PyStructSequence_Desc times_result_desc = {
7444 "times_result", /* name */
7445 times_result__doc__, /* doc */
7446 times_result_fields,
7447 5
7448};
7449
7450static PyTypeObject TimesResultType;
7451
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007452#ifdef MS_WINDOWS
7453#define HAVE_TIMES /* mandatory, for the method table */
7454#endif
Larry Hastings605a62d2012-06-24 04:33:36 -07007455
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007456#ifdef HAVE_TIMES
Larry Hastings605a62d2012-06-24 04:33:36 -07007457
7458static PyObject *
7459build_times_result(double user, double system,
7460 double children_user, double children_system,
7461 double elapsed)
7462{
7463 PyObject *value = PyStructSequence_New(&TimesResultType);
7464 if (value == NULL)
7465 return NULL;
7466
7467#define SET(i, field) \
7468 { \
7469 PyObject *o = PyFloat_FromDouble(field); \
7470 if (!o) { \
7471 Py_DECREF(value); \
7472 return NULL; \
7473 } \
7474 PyStructSequence_SET_ITEM(value, i, o); \
7475 } \
7476
7477 SET(0, user);
7478 SET(1, system);
7479 SET(2, children_user);
7480 SET(3, children_system);
7481 SET(4, elapsed);
7482
7483#undef SET
7484
7485 return value;
7486}
7487
Larry Hastings605a62d2012-06-24 04:33:36 -07007488
Larry Hastings2f936352014-08-05 14:04:04 +10007489#ifndef MS_WINDOWS
7490#define NEED_TICKS_PER_SECOND
7491static long ticks_per_second = -1;
7492#endif /* MS_WINDOWS */
7493
7494/*[clinic input]
7495os.times
7496
7497Return a collection containing process timing information.
7498
7499The object returned behaves like a named tuple with these fields:
7500 (utime, stime, cutime, cstime, elapsed_time)
7501All fields are floating point numbers.
7502[clinic start generated code]*/
7503
Larry Hastings2f936352014-08-05 14:04:04 +10007504static PyObject *
7505os_times_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007506/*[clinic end generated code: output=df0a63ebe6e6f091 input=2bf9df3d6ab2e48b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007507#ifdef MS_WINDOWS
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007508{
Victor Stinner8c62be82010-05-06 00:08:46 +00007509 FILETIME create, exit, kernel, user;
7510 HANDLE hProc;
7511 hProc = GetCurrentProcess();
7512 GetProcessTimes(hProc, &create, &exit, &kernel, &user);
7513 /* The fields of a FILETIME structure are the hi and lo part
7514 of a 64-bit value expressed in 100 nanosecond units.
7515 1e7 is one second in such units; 1e-7 the inverse.
7516 429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
7517 */
Larry Hastings605a62d2012-06-24 04:33:36 -07007518 return build_times_result(
Victor Stinner8c62be82010-05-06 00:08:46 +00007519 (double)(user.dwHighDateTime*429.4967296 +
7520 user.dwLowDateTime*1e-7),
7521 (double)(kernel.dwHighDateTime*429.4967296 +
7522 kernel.dwLowDateTime*1e-7),
7523 (double)0,
7524 (double)0,
7525 (double)0);
Guido van Rossum14ed0b21994-09-29 09:50:09 +00007526}
Larry Hastings2f936352014-08-05 14:04:04 +10007527#else /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007528{
Larry Hastings2f936352014-08-05 14:04:04 +10007529
7530
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007531 struct tms t;
7532 clock_t c;
7533 errno = 0;
7534 c = times(&t);
7535 if (c == (clock_t) -1)
7536 return posix_error();
7537 return build_times_result(
7538 (double)t.tms_utime / ticks_per_second,
7539 (double)t.tms_stime / ticks_per_second,
7540 (double)t.tms_cutime / ticks_per_second,
7541 (double)t.tms_cstime / ticks_per_second,
7542 (double)c / ticks_per_second);
7543}
Larry Hastings2f936352014-08-05 14:04:04 +10007544#endif /* MS_WINDOWS */
Antoine Pitrouf3923e92012-07-24 21:23:53 +02007545#endif /* HAVE_TIMES */
7546
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007547
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007548#ifdef HAVE_GETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007549/*[clinic input]
7550os.getsid
7551
7552 pid: pid_t
7553 /
7554
7555Call the system call getsid(pid) and return the result.
7556[clinic start generated code]*/
7557
Larry Hastings2f936352014-08-05 14:04:04 +10007558static PyObject *
7559os_getsid_impl(PyModuleDef *module, pid_t pid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007560/*[clinic end generated code: output=a074f80c0e6bfb38 input=eeb2b923a30ce04e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007561{
Victor Stinner8c62be82010-05-06 00:08:46 +00007562 int sid;
Victor Stinner8c62be82010-05-06 00:08:46 +00007563 sid = getsid(pid);
7564 if (sid < 0)
7565 return posix_error();
7566 return PyLong_FromLong((long)sid);
Martin v. Löwis49ee14d2003-11-10 06:35:36 +00007567}
7568#endif /* HAVE_GETSID */
7569
7570
Guido van Rossumb6775db1994-08-01 11:34:53 +00007571#ifdef HAVE_SETSID
Larry Hastings2f936352014-08-05 14:04:04 +10007572/*[clinic input]
7573os.setsid
7574
7575Call the system call setsid().
7576[clinic start generated code]*/
7577
Larry Hastings2f936352014-08-05 14:04:04 +10007578static PyObject *
7579os_setsid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007580/*[clinic end generated code: output=398fc152ae327330 input=5fff45858e2f0776]*/
Guido van Rossumc2670a01992-09-13 20:07:29 +00007581{
Victor Stinner8c62be82010-05-06 00:08:46 +00007582 if (setsid() < 0)
7583 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007584 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007585}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007586#endif /* HAVE_SETSID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007587
Larry Hastings2f936352014-08-05 14:04:04 +10007588
Guido van Rossumb6775db1994-08-01 11:34:53 +00007589#ifdef HAVE_SETPGID
Larry Hastings2f936352014-08-05 14:04:04 +10007590/*[clinic input]
7591os.setpgid
7592
7593 pid: pid_t
7594 pgrp: pid_t
7595 /
7596
7597Call the system call setpgid(pid, pgrp).
7598[clinic start generated code]*/
7599
Larry Hastings2f936352014-08-05 14:04:04 +10007600static PyObject *
7601os_setpgid_impl(PyModuleDef *module, pid_t pid, pid_t pgrp)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007602/*[clinic end generated code: output=7079a8e932912841 input=fceb395eca572e1a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007603{
Victor Stinner8c62be82010-05-06 00:08:46 +00007604 if (setpgid(pid, pgrp) < 0)
7605 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007606 Py_RETURN_NONE;
Guido van Rossumc2670a01992-09-13 20:07:29 +00007607}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007608#endif /* HAVE_SETPGID */
Guido van Rossumc2670a01992-09-13 20:07:29 +00007609
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007610
Guido van Rossumb6775db1994-08-01 11:34:53 +00007611#ifdef HAVE_TCGETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007612/*[clinic input]
7613os.tcgetpgrp
7614
7615 fd: int
7616 /
7617
7618Return the process group associated with the terminal specified by fd.
7619[clinic start generated code]*/
7620
Larry Hastings2f936352014-08-05 14:04:04 +10007621static PyObject *
7622os_tcgetpgrp_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007623/*[clinic end generated code: output=ebb6dc5f111c7dc0 input=7f6c18eac10ada86]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007624{
7625 pid_t pgid = tcgetpgrp(fd);
Victor Stinner8c62be82010-05-06 00:08:46 +00007626 if (pgid < 0)
7627 return posix_error();
7628 return PyLong_FromPid(pgid);
Guido van Rossum7066dd71992-09-17 17:54:56 +00007629}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007630#endif /* HAVE_TCGETPGRP */
Guido van Rossum7066dd71992-09-17 17:54:56 +00007631
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007632
Guido van Rossumb6775db1994-08-01 11:34:53 +00007633#ifdef HAVE_TCSETPGRP
Larry Hastings2f936352014-08-05 14:04:04 +10007634/*[clinic input]
7635os.tcsetpgrp
7636
7637 fd: int
7638 pgid: pid_t
7639 /
7640
7641Set the process group associated with the terminal specified by fd.
7642[clinic start generated code]*/
7643
Larry Hastings2f936352014-08-05 14:04:04 +10007644static PyObject *
7645os_tcsetpgrp_impl(PyModuleDef *module, int fd, pid_t pgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007646/*[clinic end generated code: output=3e4b05177462cd22 input=5bdc997c6a619020]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007647{
Victor Stinner8c62be82010-05-06 00:08:46 +00007648 if (tcsetpgrp(fd, pgid) < 0)
7649 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007650 Py_RETURN_NONE;
Guido van Rossum7066dd71992-09-17 17:54:56 +00007651}
Guido van Rossumb6775db1994-08-01 11:34:53 +00007652#endif /* HAVE_TCSETPGRP */
Guido van Rossum22db57e1992-04-05 14:25:30 +00007653
Guido van Rossum687dd131993-05-17 08:34:16 +00007654/* Functions acting on file descriptors */
7655
Victor Stinnerdaf45552013-08-28 00:53:59 +02007656#ifdef O_CLOEXEC
7657extern int _Py_open_cloexec_works;
7658#endif
7659
Larry Hastings2f936352014-08-05 14:04:04 +10007660
7661/*[clinic input]
7662os.open -> int
7663 path: path_t
7664 flags: int
7665 mode: int = 0o777
7666 *
7667 dir_fd: dir_fd(requires='openat') = None
7668
7669# "open(path, flags, mode=0o777, *, dir_fd=None)\n\n\
7670
7671Open a file for low level IO. Returns a file descriptor (integer).
7672
7673If dir_fd is not None, it should be a file descriptor open to a directory,
7674 and path should be relative; path will then be relative to that directory.
7675dir_fd may not be implemented on your platform.
7676 If it is unavailable, using it will raise a NotImplementedError.
7677[clinic start generated code]*/
7678
Larry Hastings2f936352014-08-05 14:04:04 +10007679static int
7680os_open_impl(PyModuleDef *module, path_t *path, int flags, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007681/*[clinic end generated code: output=c95a64f0e62f199b input=ad8623b29acd2934]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007682{
7683 int fd;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007684 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10007685
Victor Stinnerdaf45552013-08-28 00:53:59 +02007686#ifdef O_CLOEXEC
7687 int *atomic_flag_works = &_Py_open_cloexec_works;
7688#elif !defined(MS_WINDOWS)
7689 int *atomic_flag_works = NULL;
7690#endif
Mark Hammondc2e85bd2002-10-03 05:10:39 +00007691
Victor Stinnerdaf45552013-08-28 00:53:59 +02007692#ifdef MS_WINDOWS
7693 flags |= O_NOINHERIT;
7694#elif defined(O_CLOEXEC)
7695 flags |= O_CLOEXEC;
7696#endif
7697
Steve Dower8fc89802015-04-12 00:26:27 -04007698 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007699 do {
7700 Py_BEGIN_ALLOW_THREADS
Larry Hastings9cf065c2012-06-22 16:30:09 -07007701#ifdef MS_WINDOWS
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007702 if (path->wide)
7703 fd = _wopen(path->wide, flags, mode);
7704 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007705#endif
7706#ifdef HAVE_OPENAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007707 if (dir_fd != DEFAULT_DIR_FD)
7708 fd = openat(dir_fd, path->narrow, flags, mode);
7709 else
Larry Hastings9cf065c2012-06-22 16:30:09 -07007710#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007711 fd = open(path->narrow, flags, mode);
7712 Py_END_ALLOW_THREADS
7713 } while (fd < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04007714 _Py_END_SUPPRESS_IPH
Guido van Rossum687dd131993-05-17 08:34:16 +00007715
Larry Hastings9cf065c2012-06-22 16:30:09 -07007716 if (fd == -1) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007717 if (!async_err)
7718 PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, path->object);
Larry Hastings2f936352014-08-05 14:04:04 +10007719 return -1;
Larry Hastings9cf065c2012-06-22 16:30:09 -07007720 }
7721
Victor Stinnerdaf45552013-08-28 00:53:59 +02007722#ifndef MS_WINDOWS
7723 if (_Py_set_inheritable(fd, 0, atomic_flag_works) < 0) {
7724 close(fd);
Larry Hastings2f936352014-08-05 14:04:04 +10007725 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +02007726 }
7727#endif
7728
Larry Hastings2f936352014-08-05 14:04:04 +10007729 return fd;
7730}
7731
7732
7733/*[clinic input]
7734os.close
7735
7736 fd: int
7737
7738Close a file descriptor.
7739[clinic start generated code]*/
7740
Barry Warsaw53699e91996-12-10 23:23:01 +00007741static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +10007742os_close_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007743/*[clinic end generated code: output=47bf2ea536445a26 input=2bc42451ca5c3223]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00007744{
Larry Hastings2f936352014-08-05 14:04:04 +10007745 int res;
Victor Stinner8c62be82010-05-06 00:08:46 +00007746 if (!_PyVerify_fd(fd))
7747 return posix_error();
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007748 /* We do not want to retry upon EINTR: see http://lwn.net/Articles/576478/
7749 * and http://linux.derkeiler.com/Mailing-Lists/Kernel/2005-09/3000.html
7750 * for more details.
7751 */
Victor Stinner8c62be82010-05-06 00:08:46 +00007752 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007753 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007754 res = close(fd);
Steve Dower8fc89802015-04-12 00:26:27 -04007755 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007756 Py_END_ALLOW_THREADS
7757 if (res < 0)
7758 return posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10007759 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007760}
7761
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007762
Larry Hastings2f936352014-08-05 14:04:04 +10007763/*[clinic input]
7764os.closerange
7765
7766 fd_low: int
7767 fd_high: int
7768 /
7769
7770Closes all file descriptors in [fd_low, fd_high), ignoring errors.
7771[clinic start generated code]*/
7772
Larry Hastings2f936352014-08-05 14:04:04 +10007773static PyObject *
7774os_closerange_impl(PyModuleDef *module, int fd_low, int fd_high)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007775/*[clinic end generated code: output=70e6adb95220ba96 input=5855a3d053ebd4ec]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007776{
7777 int i;
Victor Stinner8c62be82010-05-06 00:08:46 +00007778 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007779 _Py_BEGIN_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10007780 for (i = fd_low; i < fd_high; i++)
Victor Stinner8c62be82010-05-06 00:08:46 +00007781 if (_PyVerify_fd(i))
7782 close(i);
Steve Dower8fc89802015-04-12 00:26:27 -04007783 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007784 Py_END_ALLOW_THREADS
7785 Py_RETURN_NONE;
Christian Heimesfdab48e2008-01-20 09:06:41 +00007786}
7787
7788
Larry Hastings2f936352014-08-05 14:04:04 +10007789/*[clinic input]
7790os.dup -> int
7791
7792 fd: int
7793 /
7794
7795Return a duplicate of a file descriptor.
7796[clinic start generated code]*/
7797
Larry Hastings2f936352014-08-05 14:04:04 +10007798static int
7799os_dup_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007800/*[clinic end generated code: output=f4bbac8c7652d05e input=6f10f7ea97f7852a]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007801{
7802 return _Py_dup(fd);
Guido van Rossum687dd131993-05-17 08:34:16 +00007803}
7804
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007805
Larry Hastings2f936352014-08-05 14:04:04 +10007806/*[clinic input]
7807os.dup2
7808 fd: int
7809 fd2: int
7810 inheritable: bool=True
7811
7812Duplicate file descriptor.
7813[clinic start generated code]*/
7814
Larry Hastings2f936352014-08-05 14:04:04 +10007815static PyObject *
7816os_dup2_impl(PyModuleDef *module, int fd, int fd2, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007817/*[clinic end generated code: output=9a099d95881a7923 input=76e96f511be0352f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007818{
Victor Stinnerdaf45552013-08-28 00:53:59 +02007819 int res;
7820#if defined(HAVE_DUP3) && \
7821 !(defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC))
7822 /* dup3() is available on Linux 2.6.27+ and glibc 2.9 */
7823 int dup3_works = -1;
7824#endif
7825
Victor Stinner8c62be82010-05-06 00:08:46 +00007826 if (!_PyVerify_fd_dup2(fd, fd2))
7827 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007828
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00007829 /* dup2() can fail with EINTR if the target FD is already open, because it
7830 * then has to be closed. See os_close_impl() for why we don't handle EINTR
7831 * upon close(), and therefore below.
7832 */
Victor Stinnerdaf45552013-08-28 00:53:59 +02007833#ifdef MS_WINDOWS
7834 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007835 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007836 res = dup2(fd, fd2);
Steve Dower8fc89802015-04-12 00:26:27 -04007837 _Py_END_SUPPRESS_IPH
Victor Stinnerdaf45552013-08-28 00:53:59 +02007838 Py_END_ALLOW_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +00007839 if (res < 0)
7840 return posix_error();
Victor Stinnerdaf45552013-08-28 00:53:59 +02007841
7842 /* Character files like console cannot be make non-inheritable */
7843 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7844 close(fd2);
7845 return NULL;
7846 }
7847
7848#elif defined(HAVE_FCNTL_H) && defined(F_DUP2FD_CLOEXEC)
7849 Py_BEGIN_ALLOW_THREADS
7850 if (!inheritable)
7851 res = fcntl(fd, F_DUP2FD_CLOEXEC, fd2);
7852 else
7853 res = dup2(fd, fd2);
7854 Py_END_ALLOW_THREADS
7855 if (res < 0)
7856 return posix_error();
7857
7858#else
7859
7860#ifdef HAVE_DUP3
7861 if (!inheritable && dup3_works != 0) {
7862 Py_BEGIN_ALLOW_THREADS
7863 res = dup3(fd, fd2, O_CLOEXEC);
7864 Py_END_ALLOW_THREADS
7865 if (res < 0) {
7866 if (dup3_works == -1)
7867 dup3_works = (errno != ENOSYS);
7868 if (dup3_works)
7869 return posix_error();
7870 }
7871 }
7872
7873 if (inheritable || dup3_works == 0)
7874 {
7875#endif
7876 Py_BEGIN_ALLOW_THREADS
7877 res = dup2(fd, fd2);
7878 Py_END_ALLOW_THREADS
7879 if (res < 0)
7880 return posix_error();
7881
7882 if (!inheritable && _Py_set_inheritable(fd2, 0, NULL) < 0) {
7883 close(fd2);
7884 return NULL;
7885 }
7886#ifdef HAVE_DUP3
7887 }
7888#endif
7889
7890#endif
7891
Larry Hastings2f936352014-08-05 14:04:04 +10007892 Py_RETURN_NONE;
Guido van Rossum687dd131993-05-17 08:34:16 +00007893}
7894
Larry Hastings2f936352014-08-05 14:04:04 +10007895
Ross Lagerwall7807c352011-03-17 20:20:30 +02007896#ifdef HAVE_LOCKF
Larry Hastings2f936352014-08-05 14:04:04 +10007897/*[clinic input]
7898os.lockf
7899
7900 fd: int
7901 An open file descriptor.
7902 command: int
7903 One of F_LOCK, F_TLOCK, F_ULOCK or F_TEST.
7904 length: Py_off_t
7905 The number of bytes to lock, starting at the current position.
7906 /
7907
7908Apply, test or remove a POSIX lock on an open file descriptor.
7909
7910[clinic start generated code]*/
7911
Larry Hastings2f936352014-08-05 14:04:04 +10007912static PyObject *
7913os_lockf_impl(PyModuleDef *module, int fd, int command, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007914/*[clinic end generated code: output=25ff778f9e2fbf1b input=65da41d2106e9b79]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007915{
7916 int res;
Ross Lagerwall7807c352011-03-17 20:20:30 +02007917
7918 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007919 res = lockf(fd, command, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02007920 Py_END_ALLOW_THREADS
7921
7922 if (res < 0)
7923 return posix_error();
7924
7925 Py_RETURN_NONE;
7926}
Larry Hastings2f936352014-08-05 14:04:04 +10007927#endif /* HAVE_LOCKF */
Ross Lagerwall7807c352011-03-17 20:20:30 +02007928
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007929
Larry Hastings2f936352014-08-05 14:04:04 +10007930/*[clinic input]
7931os.lseek -> Py_off_t
7932
7933 fd: int
7934 position: Py_off_t
7935 how: int
7936 /
7937
7938Set the position of a file descriptor. Return the new position.
7939
7940Return the new cursor position in number of bytes
7941relative to the beginning of the file.
7942[clinic start generated code]*/
7943
Larry Hastings2f936352014-08-05 14:04:04 +10007944static Py_off_t
7945os_lseek_impl(PyModuleDef *module, int fd, Py_off_t position, int how)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007946/*[clinic end generated code: output=65d4ab96d664998c input=902654ad3f96a6d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007947{
7948 Py_off_t result;
7949
7950 if (!_PyVerify_fd(fd)) {
7951 posix_error();
7952 return -1;
7953 }
Guido van Rossum687dd131993-05-17 08:34:16 +00007954#ifdef SEEK_SET
Victor Stinner8c62be82010-05-06 00:08:46 +00007955 /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
7956 switch (how) {
Larry Hastings2f936352014-08-05 14:04:04 +10007957 case 0: how = SEEK_SET; break;
7958 case 1: how = SEEK_CUR; break;
7959 case 2: how = SEEK_END; break;
Victor Stinner8c62be82010-05-06 00:08:46 +00007960 }
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +00007961#endif /* SEEK_END */
Guido van Rossum94f6f721999-01-06 18:42:14 +00007962
Victor Stinner8c62be82010-05-06 00:08:46 +00007963 if (PyErr_Occurred())
Larry Hastings2f936352014-08-05 14:04:04 +10007964 return -1;
Guido van Rossum94f6f721999-01-06 18:42:14 +00007965
Larry Hastings2f936352014-08-05 14:04:04 +10007966 if (!_PyVerify_fd(fd)) {
7967 posix_error();
7968 return -1;
7969 }
Victor Stinner8c62be82010-05-06 00:08:46 +00007970 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04007971 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner14b9b112013-06-25 00:37:25 +02007972#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10007973 result = _lseeki64(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007974#else
Larry Hastings2f936352014-08-05 14:04:04 +10007975 result = lseek(fd, position, how);
Fred Drake699f3522000-06-29 21:12:41 +00007976#endif
Steve Dower8fc89802015-04-12 00:26:27 -04007977 _Py_END_SUPPRESS_IPH
Victor Stinner8c62be82010-05-06 00:08:46 +00007978 Py_END_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10007979 if (result < 0)
7980 posix_error();
Guido van Rossum94f6f721999-01-06 18:42:14 +00007981
Larry Hastings2f936352014-08-05 14:04:04 +10007982 return result;
Guido van Rossum687dd131993-05-17 08:34:16 +00007983}
7984
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00007985
Larry Hastings2f936352014-08-05 14:04:04 +10007986/*[clinic input]
7987os.read
7988 fd: int
7989 length: Py_ssize_t
7990 /
7991
7992Read from a file descriptor. Returns a bytes object.
7993[clinic start generated code]*/
7994
Larry Hastings2f936352014-08-05 14:04:04 +10007995static PyObject *
7996os_read_impl(PyModuleDef *module, int fd, Py_ssize_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03007997/*[clinic end generated code: output=be24f44178455e8b input=1df2eaa27c0bf1d3]*/
Larry Hastings2f936352014-08-05 14:04:04 +10007998{
Victor Stinner8c62be82010-05-06 00:08:46 +00007999 Py_ssize_t n;
8000 PyObject *buffer;
Larry Hastings2f936352014-08-05 14:04:04 +10008001
8002 if (length < 0) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008003 errno = EINVAL;
8004 return posix_error();
8005 }
Larry Hastings2f936352014-08-05 14:04:04 +10008006
8007#ifdef MS_WINDOWS
Victor Stinner66aab0c2015-03-19 22:53:20 +01008008 /* On Windows, the count parameter of read() is an int */
Larry Hastings2f936352014-08-05 14:04:04 +10008009 if (length > INT_MAX)
8010 length = INT_MAX;
Larry Hastings2f936352014-08-05 14:04:04 +10008011#endif
8012
8013 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Victor Stinner8c62be82010-05-06 00:08:46 +00008014 if (buffer == NULL)
8015 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008016
Victor Stinner66aab0c2015-03-19 22:53:20 +01008017 n = _Py_read(fd, PyBytes_AS_STRING(buffer), length);
8018 if (n == -1) {
Victor Stinner8c62be82010-05-06 00:08:46 +00008019 Py_DECREF(buffer);
Victor Stinner66aab0c2015-03-19 22:53:20 +01008020 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +00008021 }
Larry Hastings2f936352014-08-05 14:04:04 +10008022
8023 if (n != length)
Victor Stinner8c62be82010-05-06 00:08:46 +00008024 _PyBytes_Resize(&buffer, n);
Larry Hastings2f936352014-08-05 14:04:04 +10008025
Victor Stinner8c62be82010-05-06 00:08:46 +00008026 return buffer;
Guido van Rossum687dd131993-05-17 08:34:16 +00008027}
8028
Ross Lagerwall7807c352011-03-17 20:20:30 +02008029#if (defined(HAVE_SENDFILE) && (defined(__FreeBSD__) || defined(__DragonFly__) \
8030 || defined(__APPLE__))) || defined(HAVE_READV) || defined(HAVE_WRITEV)
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008031static Py_ssize_t
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008032iov_setup(struct iovec **iov, Py_buffer **buf, PyObject *seq, int cnt, int type)
8033{
8034 int i, j;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008035 Py_ssize_t blen, total = 0;
8036
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008037 *iov = PyMem_New(struct iovec, cnt);
8038 if (*iov == NULL) {
8039 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008040 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008041 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008042
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008043 *buf = PyMem_New(Py_buffer, cnt);
8044 if (*buf == NULL) {
8045 PyMem_Del(*iov);
8046 PyErr_NoMemory();
Victor Stinner57ddf782014-01-08 15:21:28 +01008047 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008048 }
8049
8050 for (i = 0; i < cnt; i++) {
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008051 PyObject *item = PySequence_GetItem(seq, i);
8052 if (item == NULL)
8053 goto fail;
8054 if (PyObject_GetBuffer(item, &(*buf)[i], type) == -1) {
8055 Py_DECREF(item);
8056 goto fail;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008057 }
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008058 Py_DECREF(item);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008059 (*iov)[i].iov_base = (*buf)[i].buf;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008060 blen = (*buf)[i].len;
8061 (*iov)[i].iov_len = blen;
8062 total += blen;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008063 }
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008064 return total;
Ross Lagerwall9ad63e02011-03-19 09:11:14 +02008065
8066fail:
8067 PyMem_Del(*iov);
8068 for (j = 0; j < i; j++) {
8069 PyBuffer_Release(&(*buf)[j]);
8070 }
8071 PyMem_Del(*buf);
Victor Stinner57ddf782014-01-08 15:21:28 +01008072 return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008073}
8074
8075static void
8076iov_cleanup(struct iovec *iov, Py_buffer *buf, int cnt)
8077{
8078 int i;
8079 PyMem_Del(iov);
8080 for (i = 0; i < cnt; i++) {
8081 PyBuffer_Release(&buf[i]);
8082 }
8083 PyMem_Del(buf);
8084}
8085#endif
8086
Larry Hastings2f936352014-08-05 14:04:04 +10008087
Ross Lagerwall7807c352011-03-17 20:20:30 +02008088#ifdef HAVE_READV
Larry Hastings2f936352014-08-05 14:04:04 +10008089/*[clinic input]
8090os.readv -> Py_ssize_t
8091
8092 fd: int
8093 buffers: object
8094 /
8095
8096Read from a file descriptor fd into an iterable of buffers.
8097
8098The buffers should be mutable buffers accepting bytes.
8099readv will transfer data into each buffer until it is full
8100and then move on to the next buffer in the sequence to hold
8101the rest of the data.
8102
8103readv returns the total number of bytes read,
8104which may be less than the total capacity of all the buffers.
8105[clinic start generated code]*/
8106
Larry Hastings2f936352014-08-05 14:04:04 +10008107static Py_ssize_t
8108os_readv_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008109/*[clinic end generated code: output=00fc56ff1800059f input=e679eb5dbfa0357d]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008110{
8111 int cnt;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008112 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008113 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008114 struct iovec *iov;
8115 Py_buffer *buf;
8116
Larry Hastings2f936352014-08-05 14:04:04 +10008117 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008118 PyErr_SetString(PyExc_TypeError,
8119 "readv() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008120 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008121 }
Ross Lagerwall7807c352011-03-17 20:20:30 +02008122
Larry Hastings2f936352014-08-05 14:04:04 +10008123 cnt = PySequence_Size(buffers);
8124
8125 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_WRITABLE) < 0)
8126 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008127
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008128 do {
8129 Py_BEGIN_ALLOW_THREADS
8130 n = readv(fd, iov, cnt);
8131 Py_END_ALLOW_THREADS
8132 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008133
8134 iov_cleanup(iov, buf, cnt);
Larry Hastings2f936352014-08-05 14:04:04 +10008135 if (n < 0) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008136 if (!async_err)
8137 posix_error();
Larry Hastings2f936352014-08-05 14:04:04 +10008138 return -1;
8139 }
Victor Stinner57ddf782014-01-08 15:21:28 +01008140
Larry Hastings2f936352014-08-05 14:04:04 +10008141 return n;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008142}
Larry Hastings2f936352014-08-05 14:04:04 +10008143#endif /* HAVE_READV */
8144
Ross Lagerwall7807c352011-03-17 20:20:30 +02008145
8146#ifdef HAVE_PREAD
Larry Hastings2f936352014-08-05 14:04:04 +10008147/*[clinic input]
8148# TODO length should be size_t! but Python doesn't support parsing size_t yet.
8149os.pread
8150
8151 fd: int
8152 length: int
8153 offset: Py_off_t
8154 /
8155
8156Read a number of bytes from a file descriptor starting at a particular offset.
8157
8158Read length bytes from file descriptor fd, starting at offset bytes from
8159the beginning of the file. The file offset remains unchanged.
8160[clinic start generated code]*/
8161
Larry Hastings2f936352014-08-05 14:04:04 +10008162static PyObject *
8163os_pread_impl(PyModuleDef *module, int fd, int length, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008164/*[clinic end generated code: output=90d1fed87f68fa33 input=084948dcbaa35d4c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008165{
Ross Lagerwall7807c352011-03-17 20:20:30 +02008166 Py_ssize_t n;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008167 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008168 PyObject *buffer;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008169
Larry Hastings2f936352014-08-05 14:04:04 +10008170 if (length < 0) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008171 errno = EINVAL;
8172 return posix_error();
8173 }
Larry Hastings2f936352014-08-05 14:04:04 +10008174 buffer = PyBytes_FromStringAndSize((char *)NULL, length);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008175 if (buffer == NULL)
8176 return NULL;
8177 if (!_PyVerify_fd(fd)) {
8178 Py_DECREF(buffer);
8179 return posix_error();
8180 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008181
8182 do {
8183 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008184 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008185 n = pread(fd, PyBytes_AS_STRING(buffer), length, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008186 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008187 Py_END_ALLOW_THREADS
8188 } while (n < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
8189
Ross Lagerwall7807c352011-03-17 20:20:30 +02008190 if (n < 0) {
8191 Py_DECREF(buffer);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008192 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008193 }
Larry Hastings2f936352014-08-05 14:04:04 +10008194 if (n != length)
Ross Lagerwall7807c352011-03-17 20:20:30 +02008195 _PyBytes_Resize(&buffer, n);
8196 return buffer;
8197}
Larry Hastings2f936352014-08-05 14:04:04 +10008198#endif /* HAVE_PREAD */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008199
Larry Hastings2f936352014-08-05 14:04:04 +10008200
8201/*[clinic input]
8202os.write -> Py_ssize_t
8203
8204 fd: int
8205 data: Py_buffer
8206 /
8207
8208Write a bytes object to a file descriptor.
8209[clinic start generated code]*/
8210
Larry Hastings2f936352014-08-05 14:04:04 +10008211static Py_ssize_t
8212os_write_impl(PyModuleDef *module, int fd, Py_buffer *data)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008213/*[clinic end generated code: output=58845c93c9ee1dda input=3207e28963234f3c]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008214{
Victor Stinner66aab0c2015-03-19 22:53:20 +01008215 return _Py_write(fd, data->buf, data->len);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008216}
8217
8218#ifdef HAVE_SENDFILE
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008219PyDoc_STRVAR(posix_sendfile__doc__,
8220"sendfile(out, in, offset, nbytes) -> byteswritten\n\
8221sendfile(out, in, offset, nbytes, headers=None, trailers=None, flags=0)\n\
8222 -> byteswritten\n\
8223Copy nbytes bytes from file descriptor in to file descriptor out.");
8224
Larry Hastings2f936352014-08-05 14:04:04 +10008225/* AC 3.5: don't bother converting, has optional group*/
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008226static PyObject *
8227posix_sendfile(PyObject *self, PyObject *args, PyObject *kwdict)
8228{
8229 int in, out;
8230 Py_ssize_t ret;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008231 int async_err = 0;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008232 off_t offset;
8233
8234#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__APPLE__)
8235#ifndef __APPLE__
8236 Py_ssize_t len;
8237#endif
8238 PyObject *headers = NULL, *trailers = NULL;
8239 Py_buffer *hbuf, *tbuf;
8240 off_t sbytes;
8241 struct sf_hdtr sf;
8242 int flags = 0;
Benjamin Petersond8a43b42011-02-26 21:35:16 +00008243 static char *keywords[] = {"out", "in",
8244 "offset", "count",
8245 "headers", "trailers", "flags", NULL};
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008246
Victor Stinner6ce0dbf2013-07-07 16:32:36 +02008247 sf.headers = NULL;
8248 sf.trailers = NULL;
8249
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008250#ifdef __APPLE__
8251 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&O&|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008252 keywords, &out, &in, Py_off_t_converter, &offset, Py_off_t_converter, &sbytes,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008253#else
8254 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiO&n|OOi:sendfile",
Larry Hastings2f936352014-08-05 14:04:04 +10008255 keywords, &out, &in, Py_off_t_converter, &offset, &len,
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008256#endif
8257 &headers, &trailers, &flags))
8258 return NULL;
8259 if (headers != NULL) {
8260 if (!PySequence_Check(headers)) {
8261 PyErr_SetString(PyExc_TypeError,
8262 "sendfile() headers must be a sequence or None");
8263 return NULL;
8264 } else {
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008265 Py_ssize_t i = 0; /* Avoid uninitialized warning */
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008266 sf.hdr_cnt = PySequence_Size(headers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008267 if (sf.hdr_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008268 (i = iov_setup(&(sf.headers), &hbuf,
8269 headers, sf.hdr_cnt, PyBUF_SIMPLE)) < 0)
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008270 return NULL;
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008271#ifdef __APPLE__
8272 sbytes += i;
8273#endif
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008274 }
8275 }
8276 if (trailers != NULL) {
8277 if (!PySequence_Check(trailers)) {
8278 PyErr_SetString(PyExc_TypeError,
8279 "sendfile() trailers must be a sequence or None");
8280 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.trl_cnt = PySequence_Size(trailers);
Giampaolo Rodolàacdad9a2011-03-03 16:10:51 +00008284 if (sf.trl_cnt > 0 &&
Victor Stinner57ddf782014-01-08 15:21:28 +01008285 (i = iov_setup(&(sf.trailers), &tbuf,
8286 trailers, sf.trl_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
Steve Dower8fc89802015-04-12 00:26:27 -04008294 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008295 do {
8296 Py_BEGIN_ALLOW_THREADS
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008297#ifdef __APPLE__
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008298 ret = sendfile(in, out, offset, &sbytes, &sf, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008299#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008300 ret = sendfile(in, out, offset, len, &sf, &sbytes, flags);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008301#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008302 Py_END_ALLOW_THREADS
8303 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Steve Dower8fc89802015-04-12 00:26:27 -04008304 _Py_END_SUPPRESS_IPH
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008305
8306 if (sf.headers != NULL)
8307 iov_cleanup(sf.headers, hbuf, sf.hdr_cnt);
8308 if (sf.trailers != NULL)
8309 iov_cleanup(sf.trailers, tbuf, sf.trl_cnt);
8310
8311 if (ret < 0) {
8312 if ((errno == EAGAIN) || (errno == EBUSY)) {
8313 if (sbytes != 0) {
8314 // some data has been sent
8315 goto done;
8316 }
8317 else {
8318 // no data has been sent; upper application is supposed
8319 // to retry on EAGAIN or EBUSY
8320 return posix_error();
8321 }
8322 }
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008323 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008324 }
8325 goto done;
8326
8327done:
8328 #if !defined(HAVE_LARGEFILE_SUPPORT)
8329 return Py_BuildValue("l", sbytes);
8330 #else
8331 return Py_BuildValue("L", sbytes);
8332 #endif
8333
8334#else
8335 Py_ssize_t count;
8336 PyObject *offobj;
8337 static char *keywords[] = {"out", "in",
8338 "offset", "count", NULL};
8339 if (!PyArg_ParseTupleAndKeywords(args, kwdict, "iiOn:sendfile",
8340 keywords, &out, &in, &offobj, &count))
8341 return NULL;
8342#ifdef linux
8343 if (offobj == Py_None) {
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008344 do {
8345 Py_BEGIN_ALLOW_THREADS
8346 ret = sendfile(out, in, NULL, count);
8347 Py_END_ALLOW_THREADS
8348 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008349 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008350 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodola'ff1a7352011-04-19 09:47:16 +02008351 return Py_BuildValue("n", ret);
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008352 }
8353#endif
Larry Hastings2f936352014-08-05 14:04:04 +10008354 if (!Py_off_t_converter(offobj, &offset))
Antoine Pitroudcc20b82011-02-26 13:38:35 +00008355 return NULL;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008356
8357 do {
8358 Py_BEGIN_ALLOW_THREADS
8359 ret = sendfile(out, in, &offset, count);
8360 Py_END_ALLOW_THREADS
8361 } while (ret < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008362 if (ret < 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008363 return (!async_err) ? posix_error() : NULL;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +00008364 return Py_BuildValue("n", ret);
8365#endif
8366}
Larry Hastings2f936352014-08-05 14:04:04 +10008367#endif /* HAVE_SENDFILE */
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008368
Larry Hastings2f936352014-08-05 14:04:04 +10008369
8370/*[clinic input]
8371os.fstat
8372
8373 fd : int
8374
8375Perform a stat system call on the given file descriptor.
8376
8377Like stat(), but for an open file descriptor.
8378Equivalent to os.stat(fd).
8379[clinic start generated code]*/
8380
Larry Hastings2f936352014-08-05 14:04:04 +10008381static PyObject *
8382os_fstat_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008383/*[clinic end generated code: output=d71fe98bf042b626 input=27e0e0ebbe5600c9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008384{
Victor Stinner8c62be82010-05-06 00:08:46 +00008385 STRUCT_STAT st;
8386 int res;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008387 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008388
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008389 do {
8390 Py_BEGIN_ALLOW_THREADS
8391 res = FSTAT(fd, &st);
8392 Py_END_ALLOW_THREADS
8393 } while (res != 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Victor Stinner8c62be82010-05-06 00:08:46 +00008394 if (res != 0) {
Martin v. Löwis14694662006-02-03 12:54:16 +00008395#ifdef MS_WINDOWS
Victor Stinnerb024e842012-10-31 22:24:06 +01008396 return PyErr_SetFromWindowsErr(0);
Martin v. Löwis14694662006-02-03 12:54:16 +00008397#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008398 return (!async_err) ? posix_error() : NULL;
Martin v. Löwis14694662006-02-03 12:54:16 +00008399#endif
Victor Stinner8c62be82010-05-06 00:08:46 +00008400 }
Tim Peters5aa91602002-01-30 05:46:57 +00008401
Victor Stinner4195b5c2012-02-08 23:03:19 +01008402 return _pystat_fromstructstat(&st);
Guido van Rossum687dd131993-05-17 08:34:16 +00008403}
8404
Larry Hastings2f936352014-08-05 14:04:04 +10008405
8406/*[clinic input]
8407os.isatty -> bool
8408 fd: int
8409 /
8410
8411Return True if the fd is connected to a terminal.
8412
8413Return True if the file descriptor is an open file descriptor
8414connected to the slave end of a terminal.
8415[clinic start generated code]*/
8416
Larry Hastings2f936352014-08-05 14:04:04 +10008417static int
8418os_isatty_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008419/*[clinic end generated code: output=acec9d3c29d16d33 input=08ce94aa1eaf7b5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008420{
Steve Dower8fc89802015-04-12 00:26:27 -04008421 int return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008422 if (!_PyVerify_fd(fd))
8423 return 0;
Steve Dower8fc89802015-04-12 00:26:27 -04008424 _Py_BEGIN_SUPPRESS_IPH
8425 return_value = isatty(fd);
8426 _Py_END_SUPPRESS_IPH
8427 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +10008428}
8429
8430
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008431#ifdef HAVE_PIPE
Larry Hastings2f936352014-08-05 14:04:04 +10008432/*[clinic input]
8433os.pipe
8434
8435Create a pipe.
8436
8437Returns a tuple of two file descriptors:
8438 (read_fd, write_fd)
8439[clinic start generated code]*/
8440
Larry Hastings2f936352014-08-05 14:04:04 +10008441static PyObject *
8442os_pipe_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008443/*[clinic end generated code: output=6b0cd3f868ec3c40 input=02535e8c8fa6c4d4]*/
Guido van Rossum687dd131993-05-17 08:34:16 +00008444{
Victor Stinner8c62be82010-05-06 00:08:46 +00008445 int fds[2];
Victor Stinnerdaf45552013-08-28 00:53:59 +02008446#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +00008447 HANDLE read, write;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008448 SECURITY_ATTRIBUTES attr;
Victor Stinner8c62be82010-05-06 00:08:46 +00008449 BOOL ok;
Victor Stinnerdaf45552013-08-28 00:53:59 +02008450#else
8451 int res;
8452#endif
8453
8454#ifdef MS_WINDOWS
8455 attr.nLength = sizeof(attr);
8456 attr.lpSecurityDescriptor = NULL;
8457 attr.bInheritHandle = FALSE;
8458
8459 Py_BEGIN_ALLOW_THREADS
8460 ok = CreatePipe(&read, &write, &attr, 0);
8461 if (ok) {
8462 fds[0] = _open_osfhandle((Py_intptr_t)read, _O_RDONLY);
8463 fds[1] = _open_osfhandle((Py_intptr_t)write, _O_WRONLY);
8464 if (fds[0] == -1 || fds[1] == -1) {
8465 CloseHandle(read);
8466 CloseHandle(write);
8467 ok = 0;
8468 }
8469 }
8470 Py_END_ALLOW_THREADS
8471
Victor Stinner8c62be82010-05-06 00:08:46 +00008472 if (!ok)
Victor Stinnerb024e842012-10-31 22:24:06 +01008473 return PyErr_SetFromWindowsErr(0);
Victor Stinnerdaf45552013-08-28 00:53:59 +02008474#else
8475
8476#ifdef HAVE_PIPE2
8477 Py_BEGIN_ALLOW_THREADS
8478 res = pipe2(fds, O_CLOEXEC);
8479 Py_END_ALLOW_THREADS
8480
8481 if (res != 0 && errno == ENOSYS)
8482 {
8483#endif
8484 Py_BEGIN_ALLOW_THREADS
8485 res = pipe(fds);
8486 Py_END_ALLOW_THREADS
8487
8488 if (res == 0) {
8489 if (_Py_set_inheritable(fds[0], 0, NULL) < 0) {
8490 close(fds[0]);
8491 close(fds[1]);
8492 return NULL;
8493 }
8494 if (_Py_set_inheritable(fds[1], 0, NULL) < 0) {
8495 close(fds[0]);
8496 close(fds[1]);
8497 return NULL;
8498 }
8499 }
8500#ifdef HAVE_PIPE2
8501 }
8502#endif
8503
8504 if (res != 0)
8505 return PyErr_SetFromErrno(PyExc_OSError);
8506#endif /* !MS_WINDOWS */
8507 return Py_BuildValue("(ii)", fds[0], fds[1]);
Guido van Rossum687dd131993-05-17 08:34:16 +00008508}
Guido van Rossuma4916fa1996-05-23 22:58:55 +00008509#endif /* HAVE_PIPE */
8510
Larry Hastings2f936352014-08-05 14:04:04 +10008511
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008512#ifdef HAVE_PIPE2
Larry Hastings2f936352014-08-05 14:04:04 +10008513/*[clinic input]
8514os.pipe2
8515
8516 flags: int
8517 /
8518
8519Create a pipe with flags set atomically.
8520
8521Returns a tuple of two file descriptors:
8522 (read_fd, write_fd)
8523
8524flags can be constructed by ORing together one or more of these values:
8525O_NONBLOCK, O_CLOEXEC.
8526[clinic start generated code]*/
8527
Larry Hastings2f936352014-08-05 14:04:04 +10008528static PyObject *
8529os_pipe2_impl(PyModuleDef *module, int flags)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008530/*[clinic end generated code: output=c15b6075d0c6b2e7 input=f261b6e7e63c6817]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008531{
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008532 int fds[2];
8533 int res;
8534
Charles-François Natalidaafdd52011-05-29 20:07:40 +02008535 res = pipe2(fds, flags);
8536 if (res != 0)
8537 return posix_error();
8538 return Py_BuildValue("(ii)", fds[0], fds[1]);
8539}
8540#endif /* HAVE_PIPE2 */
8541
Larry Hastings2f936352014-08-05 14:04:04 +10008542
Ross Lagerwall7807c352011-03-17 20:20:30 +02008543#ifdef HAVE_WRITEV
Larry Hastings2f936352014-08-05 14:04:04 +10008544/*[clinic input]
8545os.writev -> Py_ssize_t
8546 fd: int
8547 buffers: object
8548 /
8549
8550Iterate over buffers, and write the contents of each to a file descriptor.
8551
8552Returns the total number of bytes written.
8553buffers must be a sequence of bytes-like objects.
8554[clinic start generated code]*/
8555
Larry Hastings2f936352014-08-05 14:04:04 +10008556static Py_ssize_t
8557os_writev_impl(PyModuleDef *module, int fd, PyObject *buffers)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008558/*[clinic end generated code: output=a48925dbf2d5c238 input=5b8d17fe4189d2fe]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008559{
8560 int cnt;
8561 Py_ssize_t result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008562 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008563 struct iovec *iov;
8564 Py_buffer *buf;
Larry Hastings2f936352014-08-05 14:04:04 +10008565
8566 if (!PySequence_Check(buffers)) {
Ross Lagerwall7807c352011-03-17 20:20:30 +02008567 PyErr_SetString(PyExc_TypeError,
8568 "writev() arg 2 must be a sequence");
Larry Hastings2f936352014-08-05 14:04:04 +10008569 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008570 }
Larry Hastings2f936352014-08-05 14:04:04 +10008571 cnt = PySequence_Size(buffers);
Ross Lagerwall7807c352011-03-17 20:20:30 +02008572
Larry Hastings2f936352014-08-05 14:04:04 +10008573 if (iov_setup(&iov, &buf, buffers, cnt, PyBUF_SIMPLE) < 0) {
8574 return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008575 }
8576
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008577 do {
8578 Py_BEGIN_ALLOW_THREADS
8579 result = writev(fd, iov, cnt);
8580 Py_END_ALLOW_THREADS
8581 } while (result < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Ross Lagerwall7807c352011-03-17 20:20:30 +02008582
8583 iov_cleanup(iov, buf, cnt);
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008584 if (result < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008585 posix_error();
Victor Stinner57ddf782014-01-08 15:21:28 +01008586
Georg Brandl306336b2012-06-24 12:55:33 +02008587 return result;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008588}
Larry Hastings2f936352014-08-05 14:04:04 +10008589#endif /* HAVE_WRITEV */
8590
8591
8592#ifdef HAVE_PWRITE
8593/*[clinic input]
8594os.pwrite -> Py_ssize_t
8595
8596 fd: int
8597 buffer: Py_buffer
8598 offset: Py_off_t
8599 /
8600
8601Write bytes to a file descriptor starting at a particular offset.
8602
8603Write buffer to fd, starting at offset bytes from the beginning of
8604the file. Returns the number of bytes writte. Does not change the
8605current file offset.
8606[clinic start generated code]*/
8607
Larry Hastings2f936352014-08-05 14:04:04 +10008608static Py_ssize_t
8609os_pwrite_impl(PyModuleDef *module, int fd, Py_buffer *buffer, Py_off_t offset)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008610/*[clinic end generated code: output=95225f3b496feaf3 input=19903f1b3dd26377]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008611{
8612 Py_ssize_t size;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008613 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008614
8615 if (!_PyVerify_fd(fd)) {
8616 posix_error();
8617 return -1;
8618 }
8619
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008620 do {
8621 Py_BEGIN_ALLOW_THREADS
Steve Dower8fc89802015-04-12 00:26:27 -04008622 _Py_BEGIN_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008623 size = pwrite(fd, buffer->buf, (size_t)buffer->len, offset);
Steve Dower8fc89802015-04-12 00:26:27 -04008624 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008625 Py_END_ALLOW_THREADS
8626 } while (size < 0 && errno == EINTR && !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10008627
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008628 if (size < 0 && !async_err)
Larry Hastings2f936352014-08-05 14:04:04 +10008629 posix_error();
8630 return size;
8631}
8632#endif /* HAVE_PWRITE */
8633
8634
8635#ifdef HAVE_MKFIFO
8636/*[clinic input]
8637os.mkfifo
8638
8639 path: path_t
8640 mode: int=0o666
8641 *
8642 dir_fd: dir_fd(requires='mkfifoat')=None
8643
8644Create a "fifo" (a POSIX named pipe).
8645
8646If dir_fd is not None, it should be a file descriptor open to a directory,
8647 and path should be relative; path will then be relative to that directory.
8648dir_fd may not be implemented on your platform.
8649 If it is unavailable, using it will raise a NotImplementedError.
8650[clinic start generated code]*/
8651
Larry Hastings2f936352014-08-05 14:04:04 +10008652static PyObject *
8653os_mkfifo_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008654/*[clinic end generated code: output=8f5f5e72c630049a input=73032e98a36e0e19]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008655{
8656 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008657 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008658
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008659 do {
8660 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008661#ifdef HAVE_MKFIFOAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008662 if (dir_fd != DEFAULT_DIR_FD)
8663 result = mkfifoat(dir_fd, path->narrow, mode);
8664 else
Ross Lagerwall7807c352011-03-17 20:20:30 +02008665#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008666 result = mkfifo(path->narrow, mode);
8667 Py_END_ALLOW_THREADS
8668 } while (result != 0 && errno == EINTR &&
8669 !(async_err = PyErr_CheckSignals()));
8670 if (result != 0)
8671 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008672
8673 Py_RETURN_NONE;
8674}
8675#endif /* HAVE_MKFIFO */
8676
8677
8678#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
8679/*[clinic input]
8680os.mknod
8681
8682 path: path_t
8683 mode: int=0o600
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008684 device: dev_t=0
Larry Hastings2f936352014-08-05 14:04:04 +10008685 *
8686 dir_fd: dir_fd(requires='mknodat')=None
8687
8688Create a node in the file system.
8689
8690Create a node in the file system (file, device special file or named pipe)
8691at path. mode specifies both the permissions to use and the
8692type of node to be created, being combined (bitwise OR) with one of
8693S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. If S_IFCHR or S_IFBLK is set on mode,
8694device defines the newly created device special file (probably using
8695os.makedev()). Otherwise device is ignored.
8696
8697If dir_fd is not None, it should be a file descriptor open to a directory,
8698 and path should be relative; path will then be relative to that directory.
8699dir_fd may not be implemented on your platform.
8700 If it is unavailable, using it will raise a NotImplementedError.
8701[clinic start generated code]*/
8702
Larry Hastings2f936352014-08-05 14:04:04 +10008703static PyObject *
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008704os_mknod_impl(PyModuleDef *module, path_t *path, int mode, dev_t device, int dir_fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008705/*[clinic end generated code: output=f7f813e8847de12f input=ee44531551a4d83b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008706{
8707 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008708 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008709
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008710 do {
8711 Py_BEGIN_ALLOW_THREADS
Larry Hastings2f936352014-08-05 14:04:04 +10008712#ifdef HAVE_MKNODAT
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008713 if (dir_fd != DEFAULT_DIR_FD)
8714 result = mknodat(dir_fd, path->narrow, mode, device);
8715 else
Larry Hastings2f936352014-08-05 14:04:04 +10008716#endif
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008717 result = mknod(path->narrow, mode, device);
8718 Py_END_ALLOW_THREADS
8719 } while (result != 0 && errno == EINTR &&
8720 !(async_err = PyErr_CheckSignals()));
8721 if (result != 0)
8722 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008723
8724 Py_RETURN_NONE;
8725}
8726#endif /* defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV) */
8727
8728
8729#ifdef HAVE_DEVICE_MACROS
8730/*[clinic input]
8731os.major -> unsigned_int
8732
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008733 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008734 /
8735
8736Extracts a device major number from a raw device number.
8737[clinic start generated code]*/
8738
Larry Hastings2f936352014-08-05 14:04:04 +10008739static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008740os_major_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008741/*[clinic end generated code: output=ba55693ab49bac34 input=1e16a4d30c4d4462]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008742{
8743 return major(device);
8744}
8745
8746
8747/*[clinic input]
8748os.minor -> unsigned_int
8749
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008750 device: dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008751 /
8752
8753Extracts a device minor number from a raw device number.
8754[clinic start generated code]*/
8755
Larry Hastings2f936352014-08-05 14:04:04 +10008756static unsigned int
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008757os_minor_impl(PyModuleDef *module, dev_t device)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008758/*[clinic end generated code: output=2867219ebf274e27 input=0842c6d23f24c65e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008759{
8760 return minor(device);
8761}
8762
8763
8764/*[clinic input]
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008765os.makedev -> dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008766
8767 major: int
8768 minor: int
8769 /
8770
8771Composes a raw device number from the major and minor device numbers.
8772[clinic start generated code]*/
8773
Serhiy Storchakaacdb7c12015-01-18 11:17:39 +02008774static dev_t
Larry Hastings2f936352014-08-05 14:04:04 +10008775os_makedev_impl(PyModuleDef *module, int major, int minor)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008776/*[clinic end generated code: output=7cb6264352437660 input=4b9fd8fc73cbe48f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008777{
8778 return makedev(major, minor);
8779}
8780#endif /* HAVE_DEVICE_MACROS */
8781
8782
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008783#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008784/*[clinic input]
8785os.ftruncate
8786
8787 fd: int
8788 length: Py_off_t
8789 /
8790
8791Truncate a file, specified by file descriptor, to a specific length.
8792[clinic start generated code]*/
8793
Larry Hastings2f936352014-08-05 14:04:04 +10008794static PyObject *
8795os_ftruncate_impl(PyModuleDef *module, int fd, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008796/*[clinic end generated code: output=3666f401d76bf834 input=63b43641e52818f2]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008797{
8798 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008799 int async_err = 0;
Larry Hastings2f936352014-08-05 14:04:04 +10008800
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008801 if (!_PyVerify_fd(fd))
8802 return posix_error();
8803
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008804 do {
8805 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008806 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008807#ifdef MS_WINDOWS
8808 result = _chsize_s(fd, length);
8809#else
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008810 result = ftruncate(fd, length);
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008811#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008812 _Py_END_SUPPRESS_IPH
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008813 Py_END_ALLOW_THREADS
8814 } while (result != 0 && errno == EINTR &&
8815 !(async_err = PyErr_CheckSignals()));
8816 if (result != 0)
8817 return (!async_err) ? posix_error() : NULL;
Larry Hastings2f936352014-08-05 14:04:04 +10008818 Py_RETURN_NONE;
8819}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008820#endif /* HAVE_FTRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008821
8822
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008823#if defined HAVE_TRUNCATE || defined MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008824/*[clinic input]
8825os.truncate
8826 path: path_t(allow_fd='PATH_HAVE_FTRUNCATE')
8827 length: Py_off_t
8828
8829Truncate a file, specified by path, to a specific length.
8830
8831On some platforms, path may also be specified as an open file descriptor.
8832 If this functionality is unavailable, using it raises an exception.
8833[clinic start generated code]*/
8834
Larry Hastings2f936352014-08-05 14:04:04 +10008835static PyObject *
8836os_truncate_impl(PyModuleDef *module, path_t *path, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008837/*[clinic end generated code: output=f60a9e08370e9e2e input=77229cf0b50a9b77]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008838{
8839 int result;
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008840#ifdef MS_WINDOWS
8841 int fd;
8842#endif
8843
8844 if (path->fd != -1)
8845 return os_ftruncate_impl(module, path->fd, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008846
8847 Py_BEGIN_ALLOW_THREADS
Steve Dowera1c7e722015-04-12 00:26:43 -04008848 _Py_BEGIN_SUPPRESS_IPH
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008849#ifdef MS_WINDOWS
8850 if (path->wide)
8851 fd = _wopen(path->wide, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
Larry Hastings2f936352014-08-05 14:04:04 +10008852 else
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008853 fd = _open(path->narrow, _O_WRONLY | _O_BINARY | _O_NOINHERIT);
8854 if (fd < 0)
8855 result = -1;
8856 else {
8857 result = _chsize_s(fd, length);
8858 close(fd);
8859 if (result < 0)
8860 errno = result;
8861 }
8862#else
8863 result = truncate(path->narrow, length);
Larry Hastings2f936352014-08-05 14:04:04 +10008864#endif
Steve Dowera1c7e722015-04-12 00:26:43 -04008865 _Py_END_SUPPRESS_IPH
Larry Hastings2f936352014-08-05 14:04:04 +10008866 Py_END_ALLOW_THREADS
8867 if (result < 0)
8868 return path_error(path);
8869
8870 Py_RETURN_NONE;
8871}
Steve Dowerfe0a41a2015-03-20 19:50:46 -07008872#endif /* HAVE_TRUNCATE || MS_WINDOWS */
Larry Hastings2f936352014-08-05 14:04:04 +10008873
Ross Lagerwall7807c352011-03-17 20:20:30 +02008874
Victor Stinnerd6b17692014-09-30 12:20:05 +02008875/* Issue #22396: On 32-bit AIX platform, the prototypes of os.posix_fadvise()
8876 and os.posix_fallocate() in system headers are wrong if _LARGE_FILES is
8877 defined, which is the case in Python on AIX. AIX bug report:
8878 http://www-01.ibm.com/support/docview.wss?uid=isg1IV56170 */
8879#if defined(_AIX) && defined(_LARGE_FILES) && !defined(__64BIT__)
8880# define POSIX_FADVISE_AIX_BUG
8881#endif
8882
Victor Stinnerec39e262014-09-30 12:35:58 +02008883
Victor Stinnerd6b17692014-09-30 12:20:05 +02008884#if defined(HAVE_POSIX_FALLOCATE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008885/*[clinic input]
8886os.posix_fallocate
8887
8888 fd: int
8889 offset: Py_off_t
8890 length: Py_off_t
8891 /
8892
8893Ensure a file has allocated at least a particular number of bytes on disk.
8894
8895Ensure that the file specified by fd encompasses a range of bytes
8896starting at offset bytes from the beginning and continuing for length bytes.
8897[clinic start generated code]*/
8898
Larry Hastings2f936352014-08-05 14:04:04 +10008899static PyObject *
8900os_posix_fallocate_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008901/*[clinic end generated code: output=8ae5f7837004d454 input=d7a2ef0ab2ca52fb]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008902{
8903 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008904 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008905
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008906 do {
8907 Py_BEGIN_ALLOW_THREADS
8908 result = posix_fallocate(fd, offset, length);
8909 Py_END_ALLOW_THREADS
8910 } while (result != 0 && errno == EINTR &&
8911 !(async_err = PyErr_CheckSignals()));
8912 if (result != 0)
8913 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008914 Py_RETURN_NONE;
8915}
Victor Stinnerec39e262014-09-30 12:35:58 +02008916#endif /* HAVE_POSIX_FALLOCATE) && !POSIX_FADVISE_AIX_BUG */
Larry Hastings2f936352014-08-05 14:04:04 +10008917
Ross Lagerwall7807c352011-03-17 20:20:30 +02008918
Victor Stinnerd6b17692014-09-30 12:20:05 +02008919#if defined(HAVE_POSIX_FADVISE) && !defined(POSIX_FADVISE_AIX_BUG)
Larry Hastings2f936352014-08-05 14:04:04 +10008920/*[clinic input]
8921os.posix_fadvise
8922
8923 fd: int
8924 offset: Py_off_t
8925 length: Py_off_t
8926 advice: int
8927 /
8928
8929Announce an intention to access data in a specific pattern.
8930
8931Announce an intention to access data in a specific pattern, thus allowing
8932the kernel to make optimizations.
8933The advice applies to the region of the file specified by fd starting at
8934offset and continuing for length bytes.
8935advice is one of POSIX_FADV_NORMAL, POSIX_FADV_SEQUENTIAL,
8936POSIX_FADV_RANDOM, POSIX_FADV_NOREUSE, POSIX_FADV_WILLNEED, or
8937POSIX_FADV_DONTNEED.
8938[clinic start generated code]*/
8939
Larry Hastings2f936352014-08-05 14:04:04 +10008940static PyObject *
8941os_posix_fadvise_impl(PyModuleDef *module, int fd, Py_off_t offset, Py_off_t length, int advice)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008942/*[clinic end generated code: output=0e3f09f651661257 input=0fbe554edc2f04b5]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008943{
8944 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008945 int async_err = 0;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008946
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00008947 do {
8948 Py_BEGIN_ALLOW_THREADS
8949 result = posix_fadvise(fd, offset, length, advice);
8950 Py_END_ALLOW_THREADS
8951 } while (result != 0 && errno == EINTR &&
8952 !(async_err = PyErr_CheckSignals()));
8953 if (result != 0)
8954 return (!async_err) ? posix_error() : NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +02008955 Py_RETURN_NONE;
8956}
Victor Stinnerec39e262014-09-30 12:35:58 +02008957#endif /* HAVE_POSIX_FADVISE && !POSIX_FADVISE_AIX_BUG */
Ross Lagerwall7807c352011-03-17 20:20:30 +02008958
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008959#ifdef HAVE_PUTENV
Guido van Rossumec4f4ac1997-06-02 22:20:51 +00008960
Fred Drake762e2061999-08-26 17:23:54 +00008961/* Save putenv() parameters as values here, so we can collect them when they
8962 * get re-set with another call for the same key. */
8963static PyObject *posix_putenv_garbage;
8964
Larry Hastings2f936352014-08-05 14:04:04 +10008965static void
8966posix_putenv_garbage_setitem(PyObject *name, PyObject *value)
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00008967{
Larry Hastings2f936352014-08-05 14:04:04 +10008968 /* Install the first arg and newstr in posix_putenv_garbage;
8969 * this will cause previous value to be collected. This has to
8970 * happen after the real putenv() call because the old value
8971 * was still accessible until then. */
8972 if (PyDict_SetItem(posix_putenv_garbage, name, value))
8973 /* really not much we can do; just leak */
8974 PyErr_Clear();
8975 else
8976 Py_DECREF(value);
8977}
8978
8979
Thomas Hellerf78f12a2007-11-08 19:33:05 +00008980#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10008981/*[clinic input]
8982os.putenv
8983
8984 name: unicode
8985 value: unicode
8986 /
8987
8988Change or add an environment variable.
8989[clinic start generated code]*/
8990
Larry Hastings2f936352014-08-05 14:04:04 +10008991static PyObject *
8992os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03008993/*[clinic end generated code: output=a2438cf95e5a0c1c input=ba586581c2e6105f]*/
Larry Hastings2f936352014-08-05 14:04:04 +10008994{
8995 wchar_t *env;
8996
8997 PyObject *unicode = PyUnicode_FromFormat("%U=%U", name, value);
8998 if (unicode == NULL) {
Victor Stinner84ae1182010-05-06 22:05:07 +00008999 PyErr_NoMemory();
Larry Hastings2f936352014-08-05 14:04:04 +10009000 return NULL;
Victor Stinner84ae1182010-05-06 22:05:07 +00009001 }
Larry Hastings2f936352014-08-05 14:04:04 +10009002 if (_MAX_ENV < PyUnicode_GET_LENGTH(unicode)) {
Victor Stinner65170952011-11-22 22:16:17 +01009003 PyErr_Format(PyExc_ValueError,
9004 "the environment variable is longer than %u characters",
9005 _MAX_ENV);
9006 goto error;
9007 }
9008
Larry Hastings2f936352014-08-05 14:04:04 +10009009 env = PyUnicode_AsUnicode(unicode);
9010 if (env == NULL)
Victor Stinnereb5657a2011-09-30 01:44:27 +02009011 goto error;
Larry Hastings2f936352014-08-05 14:04:04 +10009012 if (_wputenv(env)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009013 posix_error();
Victor Stinner84ae1182010-05-06 22:05:07 +00009014 goto error;
Victor Stinner8c62be82010-05-06 00:08:46 +00009015 }
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009016
Larry Hastings2f936352014-08-05 14:04:04 +10009017 posix_putenv_garbage_setitem(name, unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009018 Py_RETURN_NONE;
9019
9020error:
Larry Hastings2f936352014-08-05 14:04:04 +10009021 Py_DECREF(unicode);
Victor Stinner84ae1182010-05-06 22:05:07 +00009022 return NULL;
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009023}
Larry Hastings2f936352014-08-05 14:04:04 +10009024#else /* MS_WINDOWS */
9025/*[clinic input]
9026os.putenv
Guido van Rossumb6a47161997-09-15 22:54:34 +00009027
Larry Hastings2f936352014-08-05 14:04:04 +10009028 name: FSConverter
9029 value: FSConverter
9030 /
9031
9032Change or add an environment variable.
9033[clinic start generated code]*/
9034
Larry Hastings2f936352014-08-05 14:04:04 +10009035static PyObject *
9036os_putenv_impl(PyModuleDef *module, PyObject *name, PyObject *value)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009037/*[clinic end generated code: output=a2438cf95e5a0c1c input=a97bc6152f688d31]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009038{
9039 PyObject *bytes = NULL;
9040 char *env;
9041 char *name_string = PyBytes_AsString(name);
9042 char *value_string = PyBytes_AsString(value);
9043
9044 bytes = PyBytes_FromFormat("%s=%s", name_string, value_string);
9045 if (bytes == NULL) {
9046 PyErr_NoMemory();
9047 return NULL;
9048 }
9049
9050 env = PyBytes_AS_STRING(bytes);
9051 if (putenv(env)) {
9052 Py_DECREF(bytes);
9053 return posix_error();
9054 }
9055
9056 posix_putenv_garbage_setitem(name, bytes);
9057 Py_RETURN_NONE;
9058}
9059#endif /* MS_WINDOWS */
9060#endif /* HAVE_PUTENV */
9061
9062
9063#ifdef HAVE_UNSETENV
9064/*[clinic input]
9065os.unsetenv
9066 name: FSConverter
9067 /
9068
9069Delete an environment variable.
9070[clinic start generated code]*/
9071
Larry Hastings2f936352014-08-05 14:04:04 +10009072static PyObject *
9073os_unsetenv_impl(PyModuleDef *module, PyObject *name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009074/*[clinic end generated code: output=25994b57016a2dc9 input=2bb5288a599c7107]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009075{
Victor Stinner984890f2011-11-24 13:53:38 +01009076#ifndef HAVE_BROKEN_UNSETENV
Victor Stinner60b385e2011-11-22 22:01:28 +01009077 int err;
Victor Stinner984890f2011-11-24 13:53:38 +01009078#endif
Victor Stinner84ae1182010-05-06 22:05:07 +00009079
Victor Stinner984890f2011-11-24 13:53:38 +01009080#ifdef HAVE_BROKEN_UNSETENV
9081 unsetenv(PyBytes_AS_STRING(name));
9082#else
Victor Stinner65170952011-11-22 22:16:17 +01009083 err = unsetenv(PyBytes_AS_STRING(name));
Larry Hastings2f936352014-08-05 14:04:04 +10009084 if (err)
Victor Stinner60b385e2011-11-22 22:01:28 +01009085 return posix_error();
Victor Stinner984890f2011-11-24 13:53:38 +01009086#endif
Guido van Rossumc524d952001-10-19 01:31:59 +00009087
Victor Stinner8c62be82010-05-06 00:08:46 +00009088 /* Remove the key from posix_putenv_garbage;
9089 * this will cause it to be collected. This has to
9090 * happen after the real unsetenv() call because the
9091 * old value was still accessible until then.
9092 */
Victor Stinner65170952011-11-22 22:16:17 +01009093 if (PyDict_DelItem(posix_putenv_garbage, name)) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009094 /* really not much we can do; just leak */
9095 PyErr_Clear();
9096 }
Victor Stinner84ae1182010-05-06 22:05:07 +00009097 Py_RETURN_NONE;
Guido van Rossumc524d952001-10-19 01:31:59 +00009098}
Larry Hastings2f936352014-08-05 14:04:04 +10009099#endif /* HAVE_UNSETENV */
Guido van Rossumc524d952001-10-19 01:31:59 +00009100
Larry Hastings2f936352014-08-05 14:04:04 +10009101
9102/*[clinic input]
9103os.strerror
9104
9105 code: int
9106 /
9107
9108Translate an error code to a message string.
9109[clinic start generated code]*/
9110
Larry Hastings2f936352014-08-05 14:04:04 +10009111static PyObject *
9112os_strerror_impl(PyModuleDef *module, int code)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009113/*[clinic end generated code: output=0280c6af51e5c9fe input=75a8673d97915a91]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009114{
9115 char *message = strerror(code);
Victor Stinner8c62be82010-05-06 00:08:46 +00009116 if (message == NULL) {
9117 PyErr_SetString(PyExc_ValueError,
9118 "strerror() argument out of range");
9119 return NULL;
9120 }
Victor Stinner1b579672011-12-17 05:47:23 +01009121 return PyUnicode_DecodeLocale(message, "surrogateescape");
Guido van Rossumb6a47161997-09-15 22:54:34 +00009122}
Guido van Rossumb6a47161997-09-15 22:54:34 +00009123
Guido van Rossumf1af3fe1996-07-23 19:18:10 +00009124
Guido van Rossumc9641791998-08-04 15:26:23 +00009125#ifdef HAVE_SYS_WAIT_H
Fred Drake106c1a02002-04-23 15:58:02 +00009126#ifdef WCOREDUMP
Larry Hastings2f936352014-08-05 14:04:04 +10009127/*[clinic input]
9128os.WCOREDUMP -> bool
9129
9130 status: int
9131 /
9132
9133Return True if the process returning status was dumped to a core file.
9134[clinic start generated code]*/
9135
Larry Hastings2f936352014-08-05 14:04:04 +10009136static int
9137os_WCOREDUMP_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009138/*[clinic end generated code: output=134f70bbe63fbf41 input=8b05e7ab38528d04]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009139{
9140 WAIT_TYPE wait_status;
9141 WAIT_STATUS_INT(wait_status) = status;
9142 return WCOREDUMP(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009143}
9144#endif /* WCOREDUMP */
9145
Larry Hastings2f936352014-08-05 14:04:04 +10009146
Fred Drake106c1a02002-04-23 15:58:02 +00009147#ifdef WIFCONTINUED
Larry Hastings2f936352014-08-05 14:04:04 +10009148/*[clinic input]
9149os.WIFCONTINUED -> bool
9150
9151 status: int
9152
9153Return True if a particular process was continued from a job control stop.
9154
9155Return True if the process returning status was continued from a
9156job control stop.
9157[clinic start generated code]*/
9158
Larry Hastings2f936352014-08-05 14:04:04 +10009159static int
9160os_WIFCONTINUED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009161/*[clinic end generated code: output=9cdd26543ebb6dcd input=e777e7d38eb25bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009162{
9163 WAIT_TYPE wait_status;
9164 WAIT_STATUS_INT(wait_status) = status;
9165 return WIFCONTINUED(wait_status);
Fred Drake106c1a02002-04-23 15:58:02 +00009166}
9167#endif /* WIFCONTINUED */
9168
Larry Hastings2f936352014-08-05 14:04:04 +10009169
Guido van Rossumc9641791998-08-04 15:26:23 +00009170#ifdef WIFSTOPPED
Larry Hastings2f936352014-08-05 14:04:04 +10009171/*[clinic input]
9172os.WIFSTOPPED -> bool
9173
9174 status: int
9175
9176Return True if the process returning status was stopped.
9177[clinic start generated code]*/
9178
Larry Hastings2f936352014-08-05 14:04:04 +10009179static int
9180os_WIFSTOPPED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009181/*[clinic end generated code: output=73bf35e44994a724 input=043cb7f1289ef904]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009182{
9183 WAIT_TYPE wait_status;
9184 WAIT_STATUS_INT(wait_status) = status;
9185 return WIFSTOPPED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009186}
9187#endif /* WIFSTOPPED */
9188
Larry Hastings2f936352014-08-05 14:04:04 +10009189
Guido van Rossumc9641791998-08-04 15:26:23 +00009190#ifdef WIFSIGNALED
Larry Hastings2f936352014-08-05 14:04:04 +10009191/*[clinic input]
9192os.WIFSIGNALED -> bool
9193
9194 status: int
9195
9196Return True if the process returning status was terminated by a signal.
9197[clinic start generated code]*/
9198
Larry Hastings2f936352014-08-05 14:04:04 +10009199static int
9200os_WIFSIGNALED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009201/*[clinic end generated code: output=2697975771872420 input=d55ba7cc9ce5dc43]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009202{
9203 WAIT_TYPE wait_status;
9204 WAIT_STATUS_INT(wait_status) = status;
9205 return WIFSIGNALED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009206}
9207#endif /* WIFSIGNALED */
9208
Larry Hastings2f936352014-08-05 14:04:04 +10009209
Guido van Rossumc9641791998-08-04 15:26:23 +00009210#ifdef WIFEXITED
Larry Hastings2f936352014-08-05 14:04:04 +10009211/*[clinic input]
9212os.WIFEXITED -> bool
9213
9214 status: int
9215
9216Return True if the process returning status exited via the exit() system call.
9217[clinic start generated code]*/
9218
Larry Hastings2f936352014-08-05 14:04:04 +10009219static int
9220os_WIFEXITED_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009221/*[clinic end generated code: output=ca8f8c61f0b8532e input=d63775a6791586c0]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009222{
9223 WAIT_TYPE wait_status;
9224 WAIT_STATUS_INT(wait_status) = status;
9225 return WIFEXITED(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009226}
9227#endif /* WIFEXITED */
9228
Larry Hastings2f936352014-08-05 14:04:04 +10009229
Guido van Rossum54ecc3d1999-01-27 17:53:11 +00009230#ifdef WEXITSTATUS
Larry Hastings2f936352014-08-05 14:04:04 +10009231/*[clinic input]
9232os.WEXITSTATUS -> int
9233
9234 status: int
9235
9236Return the process return code from status.
9237[clinic start generated code]*/
9238
Larry Hastings2f936352014-08-05 14:04:04 +10009239static int
9240os_WEXITSTATUS_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009241/*[clinic end generated code: output=ea54da23d9e0f6af input=e1fb4944e377585b]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009242{
9243 WAIT_TYPE wait_status;
9244 WAIT_STATUS_INT(wait_status) = status;
9245 return WEXITSTATUS(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009246}
9247#endif /* WEXITSTATUS */
9248
Larry Hastings2f936352014-08-05 14:04:04 +10009249
Guido van Rossumc9641791998-08-04 15:26:23 +00009250#ifdef WTERMSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009251/*[clinic input]
9252os.WTERMSIG -> int
9253
9254 status: int
9255
9256Return the signal that terminated the process that provided the status value.
9257[clinic start generated code]*/
9258
Larry Hastings2f936352014-08-05 14:04:04 +10009259static int
9260os_WTERMSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009261/*[clinic end generated code: output=4d25367026cb852c input=727fd7f84ec3f243]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009262{
9263 WAIT_TYPE wait_status;
9264 WAIT_STATUS_INT(wait_status) = status;
9265 return WTERMSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009266}
9267#endif /* WTERMSIG */
9268
Larry Hastings2f936352014-08-05 14:04:04 +10009269
Guido van Rossumc9641791998-08-04 15:26:23 +00009270#ifdef WSTOPSIG
Larry Hastings2f936352014-08-05 14:04:04 +10009271/*[clinic input]
9272os.WSTOPSIG -> int
9273
9274 status: int
9275
9276Return the signal that stopped the process that provided the status value.
9277[clinic start generated code]*/
9278
Larry Hastings2f936352014-08-05 14:04:04 +10009279static int
9280os_WSTOPSIG_impl(PyModuleDef *module, int status)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009281/*[clinic end generated code: output=54eb9c13b001adb4 input=46ebf1d1b293c5c1]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009282{
9283 WAIT_TYPE wait_status;
9284 WAIT_STATUS_INT(wait_status) = status;
9285 return WSTOPSIG(wait_status);
Guido van Rossumc9641791998-08-04 15:26:23 +00009286}
9287#endif /* WSTOPSIG */
Guido van Rossumc9641791998-08-04 15:26:23 +00009288#endif /* HAVE_SYS_WAIT_H */
9289
9290
Thomas Wouters477c8d52006-05-27 19:21:47 +00009291#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossumd5753e11999-10-19 13:29:23 +00009292#ifdef _SCO_DS
9293/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
9294 needed definitions in sys/statvfs.h */
9295#define _SVID3
9296#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +00009297#include <sys/statvfs.h>
9298
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009299static PyObject*
9300_pystatvfs_fromstructstatvfs(struct statvfs st) {
Victor Stinner8c62be82010-05-06 00:08:46 +00009301 PyObject *v = PyStructSequence_New(&StatVFSResultType);
9302 if (v == NULL)
9303 return NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009304
9305#if !defined(HAVE_LARGEFILE_SUPPORT)
Victor Stinner8c62be82010-05-06 00:08:46 +00009306 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9307 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9308 PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
9309 PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
9310 PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
9311 PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
9312 PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
9313 PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
9314 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9315 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009316#else
Victor Stinner8c62be82010-05-06 00:08:46 +00009317 PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
9318 PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
9319 PyStructSequence_SET_ITEM(v, 2,
9320 PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
9321 PyStructSequence_SET_ITEM(v, 3,
9322 PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
9323 PyStructSequence_SET_ITEM(v, 4,
9324 PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
9325 PyStructSequence_SET_ITEM(v, 5,
9326 PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
9327 PyStructSequence_SET_ITEM(v, 6,
9328 PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
9329 PyStructSequence_SET_ITEM(v, 7,
9330 PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
9331 PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
9332 PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009333#endif
Victor Stinnerf0a7bac2013-10-30 18:55:24 +01009334 if (PyErr_Occurred()) {
9335 Py_DECREF(v);
9336 return NULL;
9337 }
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009338
Victor Stinner8c62be82010-05-06 00:08:46 +00009339 return v;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009340}
9341
Larry Hastings2f936352014-08-05 14:04:04 +10009342
9343/*[clinic input]
9344os.fstatvfs
9345 fd: int
9346 /
9347
9348Perform an fstatvfs system call on the given fd.
9349
9350Equivalent to statvfs(fd).
9351[clinic start generated code]*/
9352
Larry Hastings2f936352014-08-05 14:04:04 +10009353static PyObject *
9354os_fstatvfs_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009355/*[clinic end generated code: output=584a94a754497ac0 input=d8122243ac50975e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009356{
9357 int result;
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009358 int async_err = 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009359 struct statvfs st;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009360
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009361 do {
9362 Py_BEGIN_ALLOW_THREADS
9363 result = fstatvfs(fd, &st);
9364 Py_END_ALLOW_THREADS
9365 } while (result != 0 && errno == EINTR &&
9366 !(async_err = PyErr_CheckSignals()));
Larry Hastings2f936352014-08-05 14:04:04 +10009367 if (result != 0)
Charles-François Natali6e6c59b2015-02-07 13:27:50 +00009368 return (!async_err) ? posix_error() : NULL;
Guido van Rossum98bf58f2001-10-18 20:34:25 +00009369
Victor Stinner8c62be82010-05-06 00:08:46 +00009370 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009371}
Larry Hastings2f936352014-08-05 14:04:04 +10009372#endif /* defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H) */
Guido van Rossum94f6f721999-01-06 18:42:14 +00009373
9374
Thomas Wouters477c8d52006-05-27 19:21:47 +00009375#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
Guido van Rossum94f6f721999-01-06 18:42:14 +00009376#include <sys/statvfs.h>
Larry Hastings2f936352014-08-05 14:04:04 +10009377/*[clinic input]
9378os.statvfs
Guido van Rossum94f6f721999-01-06 18:42:14 +00009379
Larry Hastings2f936352014-08-05 14:04:04 +10009380 path: path_t(allow_fd='PATH_HAVE_FSTATVFS')
9381
9382Perform a statvfs system call on the given path.
9383
9384path may always be specified as a string.
9385On some platforms, path may also be specified as an open file descriptor.
9386 If this functionality is unavailable, using it raises an exception.
9387[clinic start generated code]*/
9388
Larry Hastings2f936352014-08-05 14:04:04 +10009389static PyObject *
9390os_statvfs_impl(PyModuleDef *module, path_t *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009391/*[clinic end generated code: output=5ced07a2cf931f41 input=3f5c35791c669bd9]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009392{
9393 int result;
9394 struct statvfs st;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009395
9396 Py_BEGIN_ALLOW_THREADS
9397#ifdef HAVE_FSTATVFS
Larry Hastings2f936352014-08-05 14:04:04 +10009398 if (path->fd != -1) {
Larry Hastings9cf065c2012-06-22 16:30:09 -07009399#ifdef __APPLE__
9400 /* handle weak-linking on Mac OS X 10.3 */
9401 if (fstatvfs == NULL) {
Larry Hastings2f936352014-08-05 14:04:04 +10009402 fd_specified("statvfs", path->fd);
9403 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -07009404 }
9405#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009406 result = fstatvfs(path->fd, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009407 }
9408 else
9409#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009410 result = statvfs(path->narrow, &st);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009411 Py_END_ALLOW_THREADS
9412
9413 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +10009414 return path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -07009415 }
9416
Larry Hastings2f936352014-08-05 14:04:04 +10009417 return _pystatvfs_fromstructstatvfs(st);
Guido van Rossum94f6f721999-01-06 18:42:14 +00009418}
Larry Hastings2f936352014-08-05 14:04:04 +10009419#endif /* defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H) */
9420
Guido van Rossum94f6f721999-01-06 18:42:14 +00009421
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009422#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +10009423/*[clinic input]
9424os._getdiskusage
9425
9426 path: Py_UNICODE
9427
9428Return disk usage statistics about the given path as a (total, free) tuple.
9429[clinic start generated code]*/
9430
Larry Hastings2f936352014-08-05 14:04:04 +10009431static PyObject *
9432os__getdiskusage_impl(PyModuleDef *module, Py_UNICODE *path)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009433/*[clinic end generated code: output=60a9cf33449db1dd input=6458133aed893c78]*/
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009434{
9435 BOOL retval;
9436 ULARGE_INTEGER _, total, free;
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009437
9438 Py_BEGIN_ALLOW_THREADS
Victor Stinner6139c1b2011-11-09 22:14:14 +01009439 retval = GetDiskFreeSpaceExW(path, &_, &total, &free);
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009440 Py_END_ALLOW_THREADS
9441 if (retval == 0)
9442 return PyErr_SetFromWindowsErr(0);
9443
9444 return Py_BuildValue("(LL)", total.QuadPart, free.QuadPart);
9445}
Larry Hastings2f936352014-08-05 14:04:04 +10009446#endif /* MS_WINDOWS */
Giampaolo Rodola'210e7ca2011-07-01 13:55:36 +02009447
9448
Fred Drakec9680921999-12-13 16:37:25 +00009449/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
9450 * It maps strings representing configuration variable names to
9451 * integer values, allowing those functions to be called with the
Thomas Wouters7e474022000-07-16 12:04:32 +00009452 * magic names instead of polluting the module's namespace with tons of
Fred Drake12c6e2d1999-12-14 21:25:03 +00009453 * rarely-used constants. There are three separate tables that use
9454 * these definitions.
Fred Drakebec628d1999-12-15 18:31:10 +00009455 *
9456 * This code is always included, even if none of the interfaces that
9457 * need it are included. The #if hackery needed to avoid it would be
9458 * sufficiently pervasive that it's not worth the loss of readability.
Fred Drakec9680921999-12-13 16:37:25 +00009459 */
9460struct constdef {
9461 char *name;
9462 long value;
9463};
9464
Fred Drake12c6e2d1999-12-14 21:25:03 +00009465static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009466conv_confname(PyObject *arg, int *valuep, struct constdef *table,
Guido van Rossum7d5baac2007-08-27 23:24:46 +00009467 size_t tablesize)
Fred Drake12c6e2d1999-12-14 21:25:03 +00009468{
Christian Heimes217cfd12007-12-02 14:31:20 +00009469 if (PyLong_Check(arg)) {
Stefan Krah0e803b32010-11-26 16:16:47 +00009470 *valuep = PyLong_AS_LONG(arg);
9471 return 1;
Fred Drake12c6e2d1999-12-14 21:25:03 +00009472 }
Guido van Rossumbce56a62007-05-10 18:04:33 +00009473 else {
Stefan Krah0e803b32010-11-26 16:16:47 +00009474 /* look up the value in the table using a binary search */
9475 size_t lo = 0;
9476 size_t mid;
9477 size_t hi = tablesize;
9478 int cmp;
9479 const char *confname;
9480 if (!PyUnicode_Check(arg)) {
9481 PyErr_SetString(PyExc_TypeError,
9482 "configuration names must be strings or integers");
9483 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009484 }
Stefan Krah0e803b32010-11-26 16:16:47 +00009485 confname = _PyUnicode_AsString(arg);
9486 if (confname == NULL)
9487 return 0;
9488 while (lo < hi) {
9489 mid = (lo + hi) / 2;
9490 cmp = strcmp(confname, table[mid].name);
9491 if (cmp < 0)
9492 hi = mid;
9493 else if (cmp > 0)
9494 lo = mid + 1;
9495 else {
9496 *valuep = table[mid].value;
9497 return 1;
9498 }
9499 }
9500 PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
9501 return 0;
Victor Stinner8c62be82010-05-06 00:08:46 +00009502 }
Fred Drake12c6e2d1999-12-14 21:25:03 +00009503}
9504
9505
9506#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
9507static struct constdef posix_constants_pathconf[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009508#ifdef _PC_ABI_AIO_XFER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009509 {"PC_ABI_AIO_XFER_MAX", _PC_ABI_AIO_XFER_MAX},
Fred Draked86ed291999-12-15 15:34:33 +00009510#endif
9511#ifdef _PC_ABI_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009512 {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009513#endif
Fred Drakec9680921999-12-13 16:37:25 +00009514#ifdef _PC_ASYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009515 {"PC_ASYNC_IO", _PC_ASYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009516#endif
9517#ifdef _PC_CHOWN_RESTRICTED
Victor Stinner8c62be82010-05-06 00:08:46 +00009518 {"PC_CHOWN_RESTRICTED", _PC_CHOWN_RESTRICTED},
Fred Drakec9680921999-12-13 16:37:25 +00009519#endif
9520#ifdef _PC_FILESIZEBITS
Victor Stinner8c62be82010-05-06 00:08:46 +00009521 {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
Fred Drakec9680921999-12-13 16:37:25 +00009522#endif
9523#ifdef _PC_LAST
Victor Stinner8c62be82010-05-06 00:08:46 +00009524 {"PC_LAST", _PC_LAST},
Fred Drakec9680921999-12-13 16:37:25 +00009525#endif
9526#ifdef _PC_LINK_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009527 {"PC_LINK_MAX", _PC_LINK_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009528#endif
9529#ifdef _PC_MAX_CANON
Victor Stinner8c62be82010-05-06 00:08:46 +00009530 {"PC_MAX_CANON", _PC_MAX_CANON},
Fred Drakec9680921999-12-13 16:37:25 +00009531#endif
9532#ifdef _PC_MAX_INPUT
Victor Stinner8c62be82010-05-06 00:08:46 +00009533 {"PC_MAX_INPUT", _PC_MAX_INPUT},
Fred Drakec9680921999-12-13 16:37:25 +00009534#endif
9535#ifdef _PC_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009536 {"PC_NAME_MAX", _PC_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009537#endif
9538#ifdef _PC_NO_TRUNC
Victor Stinner8c62be82010-05-06 00:08:46 +00009539 {"PC_NO_TRUNC", _PC_NO_TRUNC},
Fred Drakec9680921999-12-13 16:37:25 +00009540#endif
9541#ifdef _PC_PATH_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009542 {"PC_PATH_MAX", _PC_PATH_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009543#endif
9544#ifdef _PC_PIPE_BUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009545 {"PC_PIPE_BUF", _PC_PIPE_BUF},
Fred Drakec9680921999-12-13 16:37:25 +00009546#endif
9547#ifdef _PC_PRIO_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009548 {"PC_PRIO_IO", _PC_PRIO_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009549#endif
9550#ifdef _PC_SOCK_MAXBUF
Victor Stinner8c62be82010-05-06 00:08:46 +00009551 {"PC_SOCK_MAXBUF", _PC_SOCK_MAXBUF},
Fred Drakec9680921999-12-13 16:37:25 +00009552#endif
9553#ifdef _PC_SYNC_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009554 {"PC_SYNC_IO", _PC_SYNC_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009555#endif
9556#ifdef _PC_VDISABLE
Victor Stinner8c62be82010-05-06 00:08:46 +00009557 {"PC_VDISABLE", _PC_VDISABLE},
Fred Drakec9680921999-12-13 16:37:25 +00009558#endif
Jesus Cea7e9065c2010-10-25 13:02:04 +00009559#ifdef _PC_ACL_ENABLED
9560 {"PC_ACL_ENABLED", _PC_ACL_ENABLED},
9561#endif
9562#ifdef _PC_MIN_HOLE_SIZE
9563 {"PC_MIN_HOLE_SIZE", _PC_MIN_HOLE_SIZE},
9564#endif
9565#ifdef _PC_ALLOC_SIZE_MIN
9566 {"PC_ALLOC_SIZE_MIN", _PC_ALLOC_SIZE_MIN},
9567#endif
9568#ifdef _PC_REC_INCR_XFER_SIZE
9569 {"PC_REC_INCR_XFER_SIZE", _PC_REC_INCR_XFER_SIZE},
9570#endif
9571#ifdef _PC_REC_MAX_XFER_SIZE
9572 {"PC_REC_MAX_XFER_SIZE", _PC_REC_MAX_XFER_SIZE},
9573#endif
9574#ifdef _PC_REC_MIN_XFER_SIZE
9575 {"PC_REC_MIN_XFER_SIZE", _PC_REC_MIN_XFER_SIZE},
9576#endif
9577#ifdef _PC_REC_XFER_ALIGN
9578 {"PC_REC_XFER_ALIGN", _PC_REC_XFER_ALIGN},
9579#endif
9580#ifdef _PC_SYMLINK_MAX
9581 {"PC_SYMLINK_MAX", _PC_SYMLINK_MAX},
9582#endif
9583#ifdef _PC_XATTR_ENABLED
9584 {"PC_XATTR_ENABLED", _PC_XATTR_ENABLED},
9585#endif
9586#ifdef _PC_XATTR_EXISTS
9587 {"PC_XATTR_EXISTS", _PC_XATTR_EXISTS},
9588#endif
9589#ifdef _PC_TIMESTAMP_RESOLUTION
9590 {"PC_TIMESTAMP_RESOLUTION", _PC_TIMESTAMP_RESOLUTION},
9591#endif
Fred Drakec9680921999-12-13 16:37:25 +00009592};
9593
Fred Drakec9680921999-12-13 16:37:25 +00009594static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009595conv_path_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009596{
9597 return conv_confname(arg, valuep, posix_constants_pathconf,
9598 sizeof(posix_constants_pathconf)
9599 / sizeof(struct constdef));
9600}
9601#endif
9602
Larry Hastings2f936352014-08-05 14:04:04 +10009603
Fred Drakec9680921999-12-13 16:37:25 +00009604#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009605/*[clinic input]
9606os.fpathconf -> long
9607
9608 fd: int
9609 name: path_confname
9610 /
9611
9612Return the configuration limit name for the file descriptor fd.
9613
9614If there is no limit, return -1.
9615[clinic start generated code]*/
9616
Larry Hastings2f936352014-08-05 14:04:04 +10009617static long
9618os_fpathconf_impl(PyModuleDef *module, int fd, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009619/*[clinic end generated code: output=082b2922d4441de7 input=5942a024d3777810]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009620{
9621 long limit;
9622
9623 errno = 0;
9624 limit = fpathconf(fd, name);
9625 if (limit == -1 && errno != 0)
9626 posix_error();
9627
9628 return limit;
9629}
9630#endif /* HAVE_FPATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009631
9632
9633#ifdef HAVE_PATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009634/*[clinic input]
9635os.pathconf -> long
9636 path: path_t(allow_fd='PATH_HAVE_FPATHCONF')
9637 name: path_confname
9638
9639Return the configuration limit name for the file or directory path.
9640
9641If there is no limit, return -1.
9642On some platforms, path may also be specified as an open file descriptor.
9643 If this functionality is unavailable, using it raises an exception.
9644[clinic start generated code]*/
9645
Larry Hastings2f936352014-08-05 14:04:04 +10009646static long
9647os_pathconf_impl(PyModuleDef *module, path_t *path, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009648/*[clinic end generated code: output=3713029e9501f5ab input=bc3e2a985af27e5e]*/
Larry Hastings2f936352014-08-05 14:04:04 +10009649{
Victor Stinner8c62be82010-05-06 00:08:46 +00009650 long limit;
Fred Drakec9680921999-12-13 16:37:25 +00009651
Victor Stinner8c62be82010-05-06 00:08:46 +00009652 errno = 0;
Georg Brandl306336b2012-06-24 12:55:33 +02009653#ifdef HAVE_FPATHCONF
Larry Hastings2f936352014-08-05 14:04:04 +10009654 if (path->fd != -1)
9655 limit = fpathconf(path->fd, name);
Georg Brandl306336b2012-06-24 12:55:33 +02009656 else
9657#endif
Larry Hastings2f936352014-08-05 14:04:04 +10009658 limit = pathconf(path->narrow, name);
Victor Stinner8c62be82010-05-06 00:08:46 +00009659 if (limit == -1 && errno != 0) {
9660 if (errno == EINVAL)
Stefan Krah99439262010-11-26 12:58:05 +00009661 /* could be a path or name problem */
9662 posix_error();
Fred Drakec9680921999-12-13 16:37:25 +00009663 else
Larry Hastings2f936352014-08-05 14:04:04 +10009664 path_error(path);
Victor Stinner8c62be82010-05-06 00:08:46 +00009665 }
Larry Hastings2f936352014-08-05 14:04:04 +10009666
9667 return limit;
Fred Drakec9680921999-12-13 16:37:25 +00009668}
Larry Hastings2f936352014-08-05 14:04:04 +10009669#endif /* HAVE_PATHCONF */
Fred Drakec9680921999-12-13 16:37:25 +00009670
9671#ifdef HAVE_CONFSTR
9672static struct constdef posix_constants_confstr[] = {
Fred Draked86ed291999-12-15 15:34:33 +00009673#ifdef _CS_ARCHITECTURE
Victor Stinner8c62be82010-05-06 00:08:46 +00009674 {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
Fred Draked86ed291999-12-15 15:34:33 +00009675#endif
Mark Dickinson876d7c82010-04-16 12:47:52 +00009676#ifdef _CS_GNU_LIBC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009677 {"CS_GNU_LIBC_VERSION", _CS_GNU_LIBC_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009678#endif
9679#ifdef _CS_GNU_LIBPTHREAD_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009680 {"CS_GNU_LIBPTHREAD_VERSION", _CS_GNU_LIBPTHREAD_VERSION},
Mark Dickinson876d7c82010-04-16 12:47:52 +00009681#endif
Fred Draked86ed291999-12-15 15:34:33 +00009682#ifdef _CS_HOSTNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009683 {"CS_HOSTNAME", _CS_HOSTNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009684#endif
9685#ifdef _CS_HW_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009686 {"CS_HW_PROVIDER", _CS_HW_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009687#endif
9688#ifdef _CS_HW_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009689 {"CS_HW_SERIAL", _CS_HW_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009690#endif
9691#ifdef _CS_INITTAB_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009692 {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009693#endif
Fred Drakec9680921999-12-13 16:37:25 +00009694#ifdef _CS_LFS64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009695 {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009696#endif
9697#ifdef _CS_LFS64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009698 {"CS_LFS64_LDFLAGS", _CS_LFS64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009699#endif
9700#ifdef _CS_LFS64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009701 {"CS_LFS64_LIBS", _CS_LFS64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009702#endif
9703#ifdef _CS_LFS64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009704 {"CS_LFS64_LINTFLAGS", _CS_LFS64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009705#endif
9706#ifdef _CS_LFS_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009707 {"CS_LFS_CFLAGS", _CS_LFS_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009708#endif
9709#ifdef _CS_LFS_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009710 {"CS_LFS_LDFLAGS", _CS_LFS_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009711#endif
9712#ifdef _CS_LFS_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009713 {"CS_LFS_LIBS", _CS_LFS_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009714#endif
9715#ifdef _CS_LFS_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009716 {"CS_LFS_LINTFLAGS", _CS_LFS_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009717#endif
Fred Draked86ed291999-12-15 15:34:33 +00009718#ifdef _CS_MACHINE
Victor Stinner8c62be82010-05-06 00:08:46 +00009719 {"CS_MACHINE", _CS_MACHINE},
Fred Draked86ed291999-12-15 15:34:33 +00009720#endif
Fred Drakec9680921999-12-13 16:37:25 +00009721#ifdef _CS_PATH
Victor Stinner8c62be82010-05-06 00:08:46 +00009722 {"CS_PATH", _CS_PATH},
Fred Drakec9680921999-12-13 16:37:25 +00009723#endif
Fred Draked86ed291999-12-15 15:34:33 +00009724#ifdef _CS_RELEASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009725 {"CS_RELEASE", _CS_RELEASE},
Fred Draked86ed291999-12-15 15:34:33 +00009726#endif
9727#ifdef _CS_SRPC_DOMAIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009728 {"CS_SRPC_DOMAIN", _CS_SRPC_DOMAIN},
Fred Draked86ed291999-12-15 15:34:33 +00009729#endif
9730#ifdef _CS_SYSNAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009731 {"CS_SYSNAME", _CS_SYSNAME},
Fred Draked86ed291999-12-15 15:34:33 +00009732#endif
9733#ifdef _CS_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009734 {"CS_VERSION", _CS_VERSION},
Fred Draked86ed291999-12-15 15:34:33 +00009735#endif
Fred Drakec9680921999-12-13 16:37:25 +00009736#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009737 {"CS_XBS5_ILP32_OFF32_CFLAGS", _CS_XBS5_ILP32_OFF32_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009738#endif
9739#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009740 {"CS_XBS5_ILP32_OFF32_LDFLAGS", _CS_XBS5_ILP32_OFF32_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009741#endif
9742#ifdef _CS_XBS5_ILP32_OFF32_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009743 {"CS_XBS5_ILP32_OFF32_LIBS", _CS_XBS5_ILP32_OFF32_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009744#endif
9745#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009746 {"CS_XBS5_ILP32_OFF32_LINTFLAGS", _CS_XBS5_ILP32_OFF32_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009747#endif
9748#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009749 {"CS_XBS5_ILP32_OFFBIG_CFLAGS", _CS_XBS5_ILP32_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009750#endif
9751#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009752 {"CS_XBS5_ILP32_OFFBIG_LDFLAGS", _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009753#endif
9754#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009755 {"CS_XBS5_ILP32_OFFBIG_LIBS", _CS_XBS5_ILP32_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009756#endif
9757#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009758 {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS", _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009759#endif
9760#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009761 {"CS_XBS5_LP64_OFF64_CFLAGS", _CS_XBS5_LP64_OFF64_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009762#endif
9763#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009764 {"CS_XBS5_LP64_OFF64_LDFLAGS", _CS_XBS5_LP64_OFF64_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009765#endif
9766#ifdef _CS_XBS5_LP64_OFF64_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009767 {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009768#endif
9769#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009770 {"CS_XBS5_LP64_OFF64_LINTFLAGS", _CS_XBS5_LP64_OFF64_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009771#endif
9772#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009773 {"CS_XBS5_LPBIG_OFFBIG_CFLAGS", _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009774#endif
9775#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009776 {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS", _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009777#endif
9778#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
Victor Stinner8c62be82010-05-06 00:08:46 +00009779 {"CS_XBS5_LPBIG_OFFBIG_LIBS", _CS_XBS5_LPBIG_OFFBIG_LIBS},
Fred Drakec9680921999-12-13 16:37:25 +00009780#endif
9781#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
Victor Stinner8c62be82010-05-06 00:08:46 +00009782 {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS", _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
Fred Drakec9680921999-12-13 16:37:25 +00009783#endif
Fred Draked86ed291999-12-15 15:34:33 +00009784#ifdef _MIPS_CS_AVAIL_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009785 {"MIPS_CS_AVAIL_PROCESSORS", _MIPS_CS_AVAIL_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009786#endif
9787#ifdef _MIPS_CS_BASE
Victor Stinner8c62be82010-05-06 00:08:46 +00009788 {"MIPS_CS_BASE", _MIPS_CS_BASE},
Fred Draked86ed291999-12-15 15:34:33 +00009789#endif
9790#ifdef _MIPS_CS_HOSTID
Victor Stinner8c62be82010-05-06 00:08:46 +00009791 {"MIPS_CS_HOSTID", _MIPS_CS_HOSTID},
Fred Draked86ed291999-12-15 15:34:33 +00009792#endif
9793#ifdef _MIPS_CS_HW_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009794 {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009795#endif
9796#ifdef _MIPS_CS_NUM_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009797 {"MIPS_CS_NUM_PROCESSORS", _MIPS_CS_NUM_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009798#endif
9799#ifdef _MIPS_CS_OSREL_MAJ
Victor Stinner8c62be82010-05-06 00:08:46 +00009800 {"MIPS_CS_OSREL_MAJ", _MIPS_CS_OSREL_MAJ},
Fred Draked86ed291999-12-15 15:34:33 +00009801#endif
9802#ifdef _MIPS_CS_OSREL_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009803 {"MIPS_CS_OSREL_MIN", _MIPS_CS_OSREL_MIN},
Fred Draked86ed291999-12-15 15:34:33 +00009804#endif
9805#ifdef _MIPS_CS_OSREL_PATCH
Victor Stinner8c62be82010-05-06 00:08:46 +00009806 {"MIPS_CS_OSREL_PATCH", _MIPS_CS_OSREL_PATCH},
Fred Draked86ed291999-12-15 15:34:33 +00009807#endif
9808#ifdef _MIPS_CS_OS_NAME
Victor Stinner8c62be82010-05-06 00:08:46 +00009809 {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
Fred Draked86ed291999-12-15 15:34:33 +00009810#endif
9811#ifdef _MIPS_CS_OS_PROVIDER
Victor Stinner8c62be82010-05-06 00:08:46 +00009812 {"MIPS_CS_OS_PROVIDER", _MIPS_CS_OS_PROVIDER},
Fred Draked86ed291999-12-15 15:34:33 +00009813#endif
9814#ifdef _MIPS_CS_PROCESSORS
Victor Stinner8c62be82010-05-06 00:08:46 +00009815 {"MIPS_CS_PROCESSORS", _MIPS_CS_PROCESSORS},
Fred Draked86ed291999-12-15 15:34:33 +00009816#endif
9817#ifdef _MIPS_CS_SERIAL
Victor Stinner8c62be82010-05-06 00:08:46 +00009818 {"MIPS_CS_SERIAL", _MIPS_CS_SERIAL},
Fred Draked86ed291999-12-15 15:34:33 +00009819#endif
9820#ifdef _MIPS_CS_VENDOR
Victor Stinner8c62be82010-05-06 00:08:46 +00009821 {"MIPS_CS_VENDOR", _MIPS_CS_VENDOR},
Fred Draked86ed291999-12-15 15:34:33 +00009822#endif
Fred Drakec9680921999-12-13 16:37:25 +00009823};
9824
9825static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +00009826conv_confstr_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +00009827{
9828 return conv_confname(arg, valuep, posix_constants_confstr,
9829 sizeof(posix_constants_confstr)
9830 / sizeof(struct constdef));
9831}
9832
Larry Hastings2f936352014-08-05 14:04:04 +10009833
9834/*[clinic input]
9835os.confstr
9836
9837 name: confstr_confname
9838 /
9839
9840Return a string-valued system configuration variable.
9841[clinic start generated code]*/
9842
Larry Hastings2f936352014-08-05 14:04:04 +10009843static PyObject *
9844os_confstr_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +03009845/*[clinic end generated code: output=6ff79c9eed8c2daf input=18fb4d0567242e65]*/
Fred Drakec9680921999-12-13 16:37:25 +00009846{
9847 PyObject *result = NULL;
Victor Stinnercb043522010-09-10 23:49:04 +00009848 char buffer[255];
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009849 size_t len;
Fred Drakec9680921999-12-13 16:37:25 +00009850
Victor Stinnercb043522010-09-10 23:49:04 +00009851 errno = 0;
9852 len = confstr(name, buffer, sizeof(buffer));
9853 if (len == 0) {
9854 if (errno) {
9855 posix_error();
9856 return NULL;
Fred Drakec9680921999-12-13 16:37:25 +00009857 }
9858 else {
Victor Stinnercb043522010-09-10 23:49:04 +00009859 Py_RETURN_NONE;
Fred Drakec9680921999-12-13 16:37:25 +00009860 }
9861 }
Victor Stinnercb043522010-09-10 23:49:04 +00009862
Victor Stinnerdd3a6a52013-06-25 23:13:47 +02009863 if (len >= sizeof(buffer)) {
Victor Stinnercbc18f32014-12-05 22:51:51 +01009864 size_t len2;
Victor Stinnercb043522010-09-10 23:49:04 +00009865 char *buf = PyMem_Malloc(len);
9866 if (buf == NULL)
9867 return PyErr_NoMemory();
Victor Stinnercbc18f32014-12-05 22:51:51 +01009868 len2 = confstr(name, buf, len);
9869 assert(len == len2);
Victor Stinnercb043522010-09-10 23:49:04 +00009870 result = PyUnicode_DecodeFSDefaultAndSize(buf, len-1);
9871 PyMem_Free(buf);
9872 }
9873 else
9874 result = PyUnicode_DecodeFSDefaultAndSize(buffer, len-1);
Fred Drakec9680921999-12-13 16:37:25 +00009875 return result;
9876}
Larry Hastings2f936352014-08-05 14:04:04 +10009877#endif /* HAVE_CONFSTR */
Fred Drakec9680921999-12-13 16:37:25 +00009878
9879
9880#ifdef HAVE_SYSCONF
9881static struct constdef posix_constants_sysconf[] = {
9882#ifdef _SC_2_CHAR_TERM
Victor Stinner8c62be82010-05-06 00:08:46 +00009883 {"SC_2_CHAR_TERM", _SC_2_CHAR_TERM},
Fred Drakec9680921999-12-13 16:37:25 +00009884#endif
9885#ifdef _SC_2_C_BIND
Victor Stinner8c62be82010-05-06 00:08:46 +00009886 {"SC_2_C_BIND", _SC_2_C_BIND},
Fred Drakec9680921999-12-13 16:37:25 +00009887#endif
9888#ifdef _SC_2_C_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009889 {"SC_2_C_DEV", _SC_2_C_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009890#endif
9891#ifdef _SC_2_C_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009892 {"SC_2_C_VERSION", _SC_2_C_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009893#endif
9894#ifdef _SC_2_FORT_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009895 {"SC_2_FORT_DEV", _SC_2_FORT_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009896#endif
9897#ifdef _SC_2_FORT_RUN
Victor Stinner8c62be82010-05-06 00:08:46 +00009898 {"SC_2_FORT_RUN", _SC_2_FORT_RUN},
Fred Drakec9680921999-12-13 16:37:25 +00009899#endif
9900#ifdef _SC_2_LOCALEDEF
Victor Stinner8c62be82010-05-06 00:08:46 +00009901 {"SC_2_LOCALEDEF", _SC_2_LOCALEDEF},
Fred Drakec9680921999-12-13 16:37:25 +00009902#endif
9903#ifdef _SC_2_SW_DEV
Victor Stinner8c62be82010-05-06 00:08:46 +00009904 {"SC_2_SW_DEV", _SC_2_SW_DEV},
Fred Drakec9680921999-12-13 16:37:25 +00009905#endif
9906#ifdef _SC_2_UPE
Victor Stinner8c62be82010-05-06 00:08:46 +00009907 {"SC_2_UPE", _SC_2_UPE},
Fred Drakec9680921999-12-13 16:37:25 +00009908#endif
9909#ifdef _SC_2_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +00009910 {"SC_2_VERSION", _SC_2_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +00009911#endif
Fred Draked86ed291999-12-15 15:34:33 +00009912#ifdef _SC_ABI_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009913 {"SC_ABI_ASYNCHRONOUS_IO", _SC_ABI_ASYNCHRONOUS_IO},
Fred Draked86ed291999-12-15 15:34:33 +00009914#endif
9915#ifdef _SC_ACL
Victor Stinner8c62be82010-05-06 00:08:46 +00009916 {"SC_ACL", _SC_ACL},
Fred Draked86ed291999-12-15 15:34:33 +00009917#endif
Fred Drakec9680921999-12-13 16:37:25 +00009918#ifdef _SC_AIO_LISTIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009919 {"SC_AIO_LISTIO_MAX", _SC_AIO_LISTIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009920#endif
Fred Drakec9680921999-12-13 16:37:25 +00009921#ifdef _SC_AIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009922 {"SC_AIO_MAX", _SC_AIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009923#endif
9924#ifdef _SC_AIO_PRIO_DELTA_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009925 {"SC_AIO_PRIO_DELTA_MAX", _SC_AIO_PRIO_DELTA_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009926#endif
9927#ifdef _SC_ARG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009928 {"SC_ARG_MAX", _SC_ARG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009929#endif
9930#ifdef _SC_ASYNCHRONOUS_IO
Victor Stinner8c62be82010-05-06 00:08:46 +00009931 {"SC_ASYNCHRONOUS_IO", _SC_ASYNCHRONOUS_IO},
Fred Drakec9680921999-12-13 16:37:25 +00009932#endif
9933#ifdef _SC_ATEXIT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009934 {"SC_ATEXIT_MAX", _SC_ATEXIT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009935#endif
Fred Draked86ed291999-12-15 15:34:33 +00009936#ifdef _SC_AUDIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009937 {"SC_AUDIT", _SC_AUDIT},
Fred Draked86ed291999-12-15 15:34:33 +00009938#endif
Fred Drakec9680921999-12-13 16:37:25 +00009939#ifdef _SC_AVPHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +00009940 {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +00009941#endif
9942#ifdef _SC_BC_BASE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009943 {"SC_BC_BASE_MAX", _SC_BC_BASE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009944#endif
9945#ifdef _SC_BC_DIM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009946 {"SC_BC_DIM_MAX", _SC_BC_DIM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009947#endif
9948#ifdef _SC_BC_SCALE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009949 {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009950#endif
9951#ifdef _SC_BC_STRING_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009952 {"SC_BC_STRING_MAX", _SC_BC_STRING_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009953#endif
Fred Draked86ed291999-12-15 15:34:33 +00009954#ifdef _SC_CAP
Victor Stinner8c62be82010-05-06 00:08:46 +00009955 {"SC_CAP", _SC_CAP},
Fred Draked86ed291999-12-15 15:34:33 +00009956#endif
Fred Drakec9680921999-12-13 16:37:25 +00009957#ifdef _SC_CHARCLASS_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009958 {"SC_CHARCLASS_NAME_MAX", _SC_CHARCLASS_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009959#endif
9960#ifdef _SC_CHAR_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +00009961 {"SC_CHAR_BIT", _SC_CHAR_BIT},
Fred Drakec9680921999-12-13 16:37:25 +00009962#endif
9963#ifdef _SC_CHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009964 {"SC_CHAR_MAX", _SC_CHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009965#endif
9966#ifdef _SC_CHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +00009967 {"SC_CHAR_MIN", _SC_CHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +00009968#endif
9969#ifdef _SC_CHILD_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009970 {"SC_CHILD_MAX", _SC_CHILD_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009971#endif
9972#ifdef _SC_CLK_TCK
Victor Stinner8c62be82010-05-06 00:08:46 +00009973 {"SC_CLK_TCK", _SC_CLK_TCK},
Fred Drakec9680921999-12-13 16:37:25 +00009974#endif
9975#ifdef _SC_COHER_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009976 {"SC_COHER_BLKSZ", _SC_COHER_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009977#endif
9978#ifdef _SC_COLL_WEIGHTS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009979 {"SC_COLL_WEIGHTS_MAX", _SC_COLL_WEIGHTS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009980#endif
9981#ifdef _SC_DCACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +00009982 {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +00009983#endif
9984#ifdef _SC_DCACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009985 {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009986#endif
9987#ifdef _SC_DCACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009988 {"SC_DCACHE_LINESZ", _SC_DCACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +00009989#endif
9990#ifdef _SC_DCACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009991 {"SC_DCACHE_SZ", _SC_DCACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +00009992#endif
9993#ifdef _SC_DCACHE_TBLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +00009994 {"SC_DCACHE_TBLKSZ", _SC_DCACHE_TBLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +00009995#endif
9996#ifdef _SC_DELAYTIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +00009997 {"SC_DELAYTIMER_MAX", _SC_DELAYTIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +00009998#endif
9999#ifdef _SC_EQUIV_CLASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010000 {"SC_EQUIV_CLASS_MAX", _SC_EQUIV_CLASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010001#endif
10002#ifdef _SC_EXPR_NEST_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010003 {"SC_EXPR_NEST_MAX", _SC_EXPR_NEST_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010004#endif
10005#ifdef _SC_FSYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000010006 {"SC_FSYNC", _SC_FSYNC},
Fred Drakec9680921999-12-13 16:37:25 +000010007#endif
10008#ifdef _SC_GETGR_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010009 {"SC_GETGR_R_SIZE_MAX", _SC_GETGR_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010010#endif
10011#ifdef _SC_GETPW_R_SIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010012 {"SC_GETPW_R_SIZE_MAX", _SC_GETPW_R_SIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010013#endif
10014#ifdef _SC_ICACHE_ASSOC
Victor Stinner8c62be82010-05-06 00:08:46 +000010015 {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
Fred Drakec9680921999-12-13 16:37:25 +000010016#endif
10017#ifdef _SC_ICACHE_BLKSZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010018 {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
Fred Drakec9680921999-12-13 16:37:25 +000010019#endif
10020#ifdef _SC_ICACHE_LINESZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010021 {"SC_ICACHE_LINESZ", _SC_ICACHE_LINESZ},
Fred Drakec9680921999-12-13 16:37:25 +000010022#endif
10023#ifdef _SC_ICACHE_SZ
Victor Stinner8c62be82010-05-06 00:08:46 +000010024 {"SC_ICACHE_SZ", _SC_ICACHE_SZ},
Fred Drakec9680921999-12-13 16:37:25 +000010025#endif
Fred Draked86ed291999-12-15 15:34:33 +000010026#ifdef _SC_INF
Victor Stinner8c62be82010-05-06 00:08:46 +000010027 {"SC_INF", _SC_INF},
Fred Draked86ed291999-12-15 15:34:33 +000010028#endif
Fred Drakec9680921999-12-13 16:37:25 +000010029#ifdef _SC_INT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010030 {"SC_INT_MAX", _SC_INT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010031#endif
10032#ifdef _SC_INT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010033 {"SC_INT_MIN", _SC_INT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010034#endif
10035#ifdef _SC_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010036 {"SC_IOV_MAX", _SC_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010037#endif
Fred Draked86ed291999-12-15 15:34:33 +000010038#ifdef _SC_IP_SECOPTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010039 {"SC_IP_SECOPTS", _SC_IP_SECOPTS},
Fred Draked86ed291999-12-15 15:34:33 +000010040#endif
Fred Drakec9680921999-12-13 16:37:25 +000010041#ifdef _SC_JOB_CONTROL
Victor Stinner8c62be82010-05-06 00:08:46 +000010042 {"SC_JOB_CONTROL", _SC_JOB_CONTROL},
Fred Drakec9680921999-12-13 16:37:25 +000010043#endif
Fred Draked86ed291999-12-15 15:34:33 +000010044#ifdef _SC_KERN_POINTERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010045 {"SC_KERN_POINTERS", _SC_KERN_POINTERS},
Fred Draked86ed291999-12-15 15:34:33 +000010046#endif
10047#ifdef _SC_KERN_SIM
Victor Stinner8c62be82010-05-06 00:08:46 +000010048 {"SC_KERN_SIM", _SC_KERN_SIM},
Fred Draked86ed291999-12-15 15:34:33 +000010049#endif
Fred Drakec9680921999-12-13 16:37:25 +000010050#ifdef _SC_LINE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010051 {"SC_LINE_MAX", _SC_LINE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010052#endif
10053#ifdef _SC_LOGIN_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010054 {"SC_LOGIN_NAME_MAX", _SC_LOGIN_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010055#endif
10056#ifdef _SC_LOGNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010057 {"SC_LOGNAME_MAX", _SC_LOGNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010058#endif
10059#ifdef _SC_LONG_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010060 {"SC_LONG_BIT", _SC_LONG_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010061#endif
Fred Draked86ed291999-12-15 15:34:33 +000010062#ifdef _SC_MAC
Victor Stinner8c62be82010-05-06 00:08:46 +000010063 {"SC_MAC", _SC_MAC},
Fred Draked86ed291999-12-15 15:34:33 +000010064#endif
Fred Drakec9680921999-12-13 16:37:25 +000010065#ifdef _SC_MAPPED_FILES
Victor Stinner8c62be82010-05-06 00:08:46 +000010066 {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
Fred Drakec9680921999-12-13 16:37:25 +000010067#endif
10068#ifdef _SC_MAXPID
Victor Stinner8c62be82010-05-06 00:08:46 +000010069 {"SC_MAXPID", _SC_MAXPID},
Fred Drakec9680921999-12-13 16:37:25 +000010070#endif
10071#ifdef _SC_MB_LEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010072 {"SC_MB_LEN_MAX", _SC_MB_LEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010073#endif
10074#ifdef _SC_MEMLOCK
Victor Stinner8c62be82010-05-06 00:08:46 +000010075 {"SC_MEMLOCK", _SC_MEMLOCK},
Fred Drakec9680921999-12-13 16:37:25 +000010076#endif
10077#ifdef _SC_MEMLOCK_RANGE
Victor Stinner8c62be82010-05-06 00:08:46 +000010078 {"SC_MEMLOCK_RANGE", _SC_MEMLOCK_RANGE},
Fred Drakec9680921999-12-13 16:37:25 +000010079#endif
10080#ifdef _SC_MEMORY_PROTECTION
Victor Stinner8c62be82010-05-06 00:08:46 +000010081 {"SC_MEMORY_PROTECTION", _SC_MEMORY_PROTECTION},
Fred Drakec9680921999-12-13 16:37:25 +000010082#endif
10083#ifdef _SC_MESSAGE_PASSING
Victor Stinner8c62be82010-05-06 00:08:46 +000010084 {"SC_MESSAGE_PASSING", _SC_MESSAGE_PASSING},
Fred Drakec9680921999-12-13 16:37:25 +000010085#endif
Fred Draked86ed291999-12-15 15:34:33 +000010086#ifdef _SC_MMAP_FIXED_ALIGNMENT
Victor Stinner8c62be82010-05-06 00:08:46 +000010087 {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
Fred Draked86ed291999-12-15 15:34:33 +000010088#endif
Fred Drakec9680921999-12-13 16:37:25 +000010089#ifdef _SC_MQ_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010090 {"SC_MQ_OPEN_MAX", _SC_MQ_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010091#endif
10092#ifdef _SC_MQ_PRIO_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010093 {"SC_MQ_PRIO_MAX", _SC_MQ_PRIO_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010094#endif
Fred Draked86ed291999-12-15 15:34:33 +000010095#ifdef _SC_NACLS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010096 {"SC_NACLS_MAX", _SC_NACLS_MAX},
Fred Draked86ed291999-12-15 15:34:33 +000010097#endif
Fred Drakec9680921999-12-13 16:37:25 +000010098#ifdef _SC_NGROUPS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010099 {"SC_NGROUPS_MAX", _SC_NGROUPS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010100#endif
10101#ifdef _SC_NL_ARGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010102 {"SC_NL_ARGMAX", _SC_NL_ARGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010103#endif
10104#ifdef _SC_NL_LANGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010105 {"SC_NL_LANGMAX", _SC_NL_LANGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010106#endif
10107#ifdef _SC_NL_MSGMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010108 {"SC_NL_MSGMAX", _SC_NL_MSGMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010109#endif
10110#ifdef _SC_NL_NMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010111 {"SC_NL_NMAX", _SC_NL_NMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010112#endif
10113#ifdef _SC_NL_SETMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010114 {"SC_NL_SETMAX", _SC_NL_SETMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010115#endif
10116#ifdef _SC_NL_TEXTMAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010117 {"SC_NL_TEXTMAX", _SC_NL_TEXTMAX},
Fred Drakec9680921999-12-13 16:37:25 +000010118#endif
10119#ifdef _SC_NPROCESSORS_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010120 {"SC_NPROCESSORS_CONF", _SC_NPROCESSORS_CONF},
Fred Drakec9680921999-12-13 16:37:25 +000010121#endif
10122#ifdef _SC_NPROCESSORS_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010123 {"SC_NPROCESSORS_ONLN", _SC_NPROCESSORS_ONLN},
Fred Drakec9680921999-12-13 16:37:25 +000010124#endif
Fred Draked86ed291999-12-15 15:34:33 +000010125#ifdef _SC_NPROC_CONF
Victor Stinner8c62be82010-05-06 00:08:46 +000010126 {"SC_NPROC_CONF", _SC_NPROC_CONF},
Fred Draked86ed291999-12-15 15:34:33 +000010127#endif
10128#ifdef _SC_NPROC_ONLN
Victor Stinner8c62be82010-05-06 00:08:46 +000010129 {"SC_NPROC_ONLN", _SC_NPROC_ONLN},
Fred Draked86ed291999-12-15 15:34:33 +000010130#endif
Fred Drakec9680921999-12-13 16:37:25 +000010131#ifdef _SC_NZERO
Victor Stinner8c62be82010-05-06 00:08:46 +000010132 {"SC_NZERO", _SC_NZERO},
Fred Drakec9680921999-12-13 16:37:25 +000010133#endif
10134#ifdef _SC_OPEN_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010135 {"SC_OPEN_MAX", _SC_OPEN_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010136#endif
10137#ifdef _SC_PAGESIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010138 {"SC_PAGESIZE", _SC_PAGESIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010139#endif
10140#ifdef _SC_PAGE_SIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010141 {"SC_PAGE_SIZE", _SC_PAGE_SIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010142#endif
10143#ifdef _SC_PASS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010144 {"SC_PASS_MAX", _SC_PASS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010145#endif
10146#ifdef _SC_PHYS_PAGES
Victor Stinner8c62be82010-05-06 00:08:46 +000010147 {"SC_PHYS_PAGES", _SC_PHYS_PAGES},
Fred Drakec9680921999-12-13 16:37:25 +000010148#endif
10149#ifdef _SC_PII
Victor Stinner8c62be82010-05-06 00:08:46 +000010150 {"SC_PII", _SC_PII},
Fred Drakec9680921999-12-13 16:37:25 +000010151#endif
10152#ifdef _SC_PII_INTERNET
Victor Stinner8c62be82010-05-06 00:08:46 +000010153 {"SC_PII_INTERNET", _SC_PII_INTERNET},
Fred Drakec9680921999-12-13 16:37:25 +000010154#endif
10155#ifdef _SC_PII_INTERNET_DGRAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010156 {"SC_PII_INTERNET_DGRAM", _SC_PII_INTERNET_DGRAM},
Fred Drakec9680921999-12-13 16:37:25 +000010157#endif
10158#ifdef _SC_PII_INTERNET_STREAM
Victor Stinner8c62be82010-05-06 00:08:46 +000010159 {"SC_PII_INTERNET_STREAM", _SC_PII_INTERNET_STREAM},
Fred Drakec9680921999-12-13 16:37:25 +000010160#endif
10161#ifdef _SC_PII_OSI
Victor Stinner8c62be82010-05-06 00:08:46 +000010162 {"SC_PII_OSI", _SC_PII_OSI},
Fred Drakec9680921999-12-13 16:37:25 +000010163#endif
10164#ifdef _SC_PII_OSI_CLTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010165 {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
Fred Drakec9680921999-12-13 16:37:25 +000010166#endif
10167#ifdef _SC_PII_OSI_COTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010168 {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
Fred Drakec9680921999-12-13 16:37:25 +000010169#endif
10170#ifdef _SC_PII_OSI_M
Victor Stinner8c62be82010-05-06 00:08:46 +000010171 {"SC_PII_OSI_M", _SC_PII_OSI_M},
Fred Drakec9680921999-12-13 16:37:25 +000010172#endif
10173#ifdef _SC_PII_SOCKET
Victor Stinner8c62be82010-05-06 00:08:46 +000010174 {"SC_PII_SOCKET", _SC_PII_SOCKET},
Fred Drakec9680921999-12-13 16:37:25 +000010175#endif
10176#ifdef _SC_PII_XTI
Victor Stinner8c62be82010-05-06 00:08:46 +000010177 {"SC_PII_XTI", _SC_PII_XTI},
Fred Drakec9680921999-12-13 16:37:25 +000010178#endif
10179#ifdef _SC_POLL
Victor Stinner8c62be82010-05-06 00:08:46 +000010180 {"SC_POLL", _SC_POLL},
Fred Drakec9680921999-12-13 16:37:25 +000010181#endif
10182#ifdef _SC_PRIORITIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010183 {"SC_PRIORITIZED_IO", _SC_PRIORITIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010184#endif
10185#ifdef _SC_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010186 {"SC_PRIORITY_SCHEDULING", _SC_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010187#endif
10188#ifdef _SC_REALTIME_SIGNALS
Victor Stinner8c62be82010-05-06 00:08:46 +000010189 {"SC_REALTIME_SIGNALS", _SC_REALTIME_SIGNALS},
Fred Drakec9680921999-12-13 16:37:25 +000010190#endif
10191#ifdef _SC_RE_DUP_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010192 {"SC_RE_DUP_MAX", _SC_RE_DUP_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010193#endif
10194#ifdef _SC_RTSIG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010195 {"SC_RTSIG_MAX", _SC_RTSIG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010196#endif
10197#ifdef _SC_SAVED_IDS
Victor Stinner8c62be82010-05-06 00:08:46 +000010198 {"SC_SAVED_IDS", _SC_SAVED_IDS},
Fred Drakec9680921999-12-13 16:37:25 +000010199#endif
10200#ifdef _SC_SCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010201 {"SC_SCHAR_MAX", _SC_SCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010202#endif
10203#ifdef _SC_SCHAR_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010204 {"SC_SCHAR_MIN", _SC_SCHAR_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010205#endif
10206#ifdef _SC_SELECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010207 {"SC_SELECT", _SC_SELECT},
Fred Drakec9680921999-12-13 16:37:25 +000010208#endif
10209#ifdef _SC_SEMAPHORES
Victor Stinner8c62be82010-05-06 00:08:46 +000010210 {"SC_SEMAPHORES", _SC_SEMAPHORES},
Fred Drakec9680921999-12-13 16:37:25 +000010211#endif
10212#ifdef _SC_SEM_NSEMS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010213 {"SC_SEM_NSEMS_MAX", _SC_SEM_NSEMS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010214#endif
10215#ifdef _SC_SEM_VALUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010216 {"SC_SEM_VALUE_MAX", _SC_SEM_VALUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010217#endif
10218#ifdef _SC_SHARED_MEMORY_OBJECTS
Victor Stinner8c62be82010-05-06 00:08:46 +000010219 {"SC_SHARED_MEMORY_OBJECTS", _SC_SHARED_MEMORY_OBJECTS},
Fred Drakec9680921999-12-13 16:37:25 +000010220#endif
10221#ifdef _SC_SHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010222 {"SC_SHRT_MAX", _SC_SHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010223#endif
10224#ifdef _SC_SHRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010225 {"SC_SHRT_MIN", _SC_SHRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010226#endif
10227#ifdef _SC_SIGQUEUE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010228 {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010229#endif
10230#ifdef _SC_SIGRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010231 {"SC_SIGRT_MAX", _SC_SIGRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010232#endif
10233#ifdef _SC_SIGRT_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010234 {"SC_SIGRT_MIN", _SC_SIGRT_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010235#endif
Fred Draked86ed291999-12-15 15:34:33 +000010236#ifdef _SC_SOFTPOWER
Victor Stinner8c62be82010-05-06 00:08:46 +000010237 {"SC_SOFTPOWER", _SC_SOFTPOWER},
Fred Draked86ed291999-12-15 15:34:33 +000010238#endif
Fred Drakec9680921999-12-13 16:37:25 +000010239#ifdef _SC_SPLIT_CACHE
Victor Stinner8c62be82010-05-06 00:08:46 +000010240 {"SC_SPLIT_CACHE", _SC_SPLIT_CACHE},
Fred Drakec9680921999-12-13 16:37:25 +000010241#endif
10242#ifdef _SC_SSIZE_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010243 {"SC_SSIZE_MAX", _SC_SSIZE_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010244#endif
10245#ifdef _SC_STACK_PROT
Victor Stinner8c62be82010-05-06 00:08:46 +000010246 {"SC_STACK_PROT", _SC_STACK_PROT},
Fred Drakec9680921999-12-13 16:37:25 +000010247#endif
10248#ifdef _SC_STREAM_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010249 {"SC_STREAM_MAX", _SC_STREAM_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010250#endif
10251#ifdef _SC_SYNCHRONIZED_IO
Victor Stinner8c62be82010-05-06 00:08:46 +000010252 {"SC_SYNCHRONIZED_IO", _SC_SYNCHRONIZED_IO},
Fred Drakec9680921999-12-13 16:37:25 +000010253#endif
10254#ifdef _SC_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010255 {"SC_THREADS", _SC_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010256#endif
10257#ifdef _SC_THREAD_ATTR_STACKADDR
Victor Stinner8c62be82010-05-06 00:08:46 +000010258 {"SC_THREAD_ATTR_STACKADDR", _SC_THREAD_ATTR_STACKADDR},
Fred Drakec9680921999-12-13 16:37:25 +000010259#endif
10260#ifdef _SC_THREAD_ATTR_STACKSIZE
Victor Stinner8c62be82010-05-06 00:08:46 +000010261 {"SC_THREAD_ATTR_STACKSIZE", _SC_THREAD_ATTR_STACKSIZE},
Fred Drakec9680921999-12-13 16:37:25 +000010262#endif
10263#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010264 {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010265#endif
10266#ifdef _SC_THREAD_KEYS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010267 {"SC_THREAD_KEYS_MAX", _SC_THREAD_KEYS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010268#endif
10269#ifdef _SC_THREAD_PRIORITY_SCHEDULING
Victor Stinner8c62be82010-05-06 00:08:46 +000010270 {"SC_THREAD_PRIORITY_SCHEDULING", _SC_THREAD_PRIORITY_SCHEDULING},
Fred Drakec9680921999-12-13 16:37:25 +000010271#endif
10272#ifdef _SC_THREAD_PRIO_INHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010273 {"SC_THREAD_PRIO_INHERIT", _SC_THREAD_PRIO_INHERIT},
Fred Drakec9680921999-12-13 16:37:25 +000010274#endif
10275#ifdef _SC_THREAD_PRIO_PROTECT
Victor Stinner8c62be82010-05-06 00:08:46 +000010276 {"SC_THREAD_PRIO_PROTECT", _SC_THREAD_PRIO_PROTECT},
Fred Drakec9680921999-12-13 16:37:25 +000010277#endif
10278#ifdef _SC_THREAD_PROCESS_SHARED
Victor Stinner8c62be82010-05-06 00:08:46 +000010279 {"SC_THREAD_PROCESS_SHARED", _SC_THREAD_PROCESS_SHARED},
Fred Drakec9680921999-12-13 16:37:25 +000010280#endif
10281#ifdef _SC_THREAD_SAFE_FUNCTIONS
Victor Stinner8c62be82010-05-06 00:08:46 +000010282 {"SC_THREAD_SAFE_FUNCTIONS", _SC_THREAD_SAFE_FUNCTIONS},
Fred Drakec9680921999-12-13 16:37:25 +000010283#endif
10284#ifdef _SC_THREAD_STACK_MIN
Victor Stinner8c62be82010-05-06 00:08:46 +000010285 {"SC_THREAD_STACK_MIN", _SC_THREAD_STACK_MIN},
Fred Drakec9680921999-12-13 16:37:25 +000010286#endif
10287#ifdef _SC_THREAD_THREADS_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010288 {"SC_THREAD_THREADS_MAX", _SC_THREAD_THREADS_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010289#endif
10290#ifdef _SC_TIMERS
Victor Stinner8c62be82010-05-06 00:08:46 +000010291 {"SC_TIMERS", _SC_TIMERS},
Fred Drakec9680921999-12-13 16:37:25 +000010292#endif
10293#ifdef _SC_TIMER_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010294 {"SC_TIMER_MAX", _SC_TIMER_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010295#endif
10296#ifdef _SC_TTY_NAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010297 {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010298#endif
10299#ifdef _SC_TZNAME_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010300 {"SC_TZNAME_MAX", _SC_TZNAME_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010301#endif
10302#ifdef _SC_T_IOV_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010303 {"SC_T_IOV_MAX", _SC_T_IOV_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010304#endif
10305#ifdef _SC_UCHAR_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010306 {"SC_UCHAR_MAX", _SC_UCHAR_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010307#endif
10308#ifdef _SC_UINT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010309 {"SC_UINT_MAX", _SC_UINT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010310#endif
10311#ifdef _SC_UIO_MAXIOV
Victor Stinner8c62be82010-05-06 00:08:46 +000010312 {"SC_UIO_MAXIOV", _SC_UIO_MAXIOV},
Fred Drakec9680921999-12-13 16:37:25 +000010313#endif
10314#ifdef _SC_ULONG_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010315 {"SC_ULONG_MAX", _SC_ULONG_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010316#endif
10317#ifdef _SC_USHRT_MAX
Victor Stinner8c62be82010-05-06 00:08:46 +000010318 {"SC_USHRT_MAX", _SC_USHRT_MAX},
Fred Drakec9680921999-12-13 16:37:25 +000010319#endif
10320#ifdef _SC_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010321 {"SC_VERSION", _SC_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010322#endif
10323#ifdef _SC_WORD_BIT
Victor Stinner8c62be82010-05-06 00:08:46 +000010324 {"SC_WORD_BIT", _SC_WORD_BIT},
Fred Drakec9680921999-12-13 16:37:25 +000010325#endif
10326#ifdef _SC_XBS5_ILP32_OFF32
Victor Stinner8c62be82010-05-06 00:08:46 +000010327 {"SC_XBS5_ILP32_OFF32", _SC_XBS5_ILP32_OFF32},
Fred Drakec9680921999-12-13 16:37:25 +000010328#endif
10329#ifdef _SC_XBS5_ILP32_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010330 {"SC_XBS5_ILP32_OFFBIG", _SC_XBS5_ILP32_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010331#endif
10332#ifdef _SC_XBS5_LP64_OFF64
Victor Stinner8c62be82010-05-06 00:08:46 +000010333 {"SC_XBS5_LP64_OFF64", _SC_XBS5_LP64_OFF64},
Fred Drakec9680921999-12-13 16:37:25 +000010334#endif
10335#ifdef _SC_XBS5_LPBIG_OFFBIG
Victor Stinner8c62be82010-05-06 00:08:46 +000010336 {"SC_XBS5_LPBIG_OFFBIG", _SC_XBS5_LPBIG_OFFBIG},
Fred Drakec9680921999-12-13 16:37:25 +000010337#endif
10338#ifdef _SC_XOPEN_CRYPT
Victor Stinner8c62be82010-05-06 00:08:46 +000010339 {"SC_XOPEN_CRYPT", _SC_XOPEN_CRYPT},
Fred Drakec9680921999-12-13 16:37:25 +000010340#endif
10341#ifdef _SC_XOPEN_ENH_I18N
Victor Stinner8c62be82010-05-06 00:08:46 +000010342 {"SC_XOPEN_ENH_I18N", _SC_XOPEN_ENH_I18N},
Fred Drakec9680921999-12-13 16:37:25 +000010343#endif
10344#ifdef _SC_XOPEN_LEGACY
Victor Stinner8c62be82010-05-06 00:08:46 +000010345 {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
Fred Drakec9680921999-12-13 16:37:25 +000010346#endif
10347#ifdef _SC_XOPEN_REALTIME
Victor Stinner8c62be82010-05-06 00:08:46 +000010348 {"SC_XOPEN_REALTIME", _SC_XOPEN_REALTIME},
Fred Drakec9680921999-12-13 16:37:25 +000010349#endif
10350#ifdef _SC_XOPEN_REALTIME_THREADS
Victor Stinner8c62be82010-05-06 00:08:46 +000010351 {"SC_XOPEN_REALTIME_THREADS", _SC_XOPEN_REALTIME_THREADS},
Fred Drakec9680921999-12-13 16:37:25 +000010352#endif
10353#ifdef _SC_XOPEN_SHM
Victor Stinner8c62be82010-05-06 00:08:46 +000010354 {"SC_XOPEN_SHM", _SC_XOPEN_SHM},
Fred Drakec9680921999-12-13 16:37:25 +000010355#endif
10356#ifdef _SC_XOPEN_UNIX
Victor Stinner8c62be82010-05-06 00:08:46 +000010357 {"SC_XOPEN_UNIX", _SC_XOPEN_UNIX},
Fred Drakec9680921999-12-13 16:37:25 +000010358#endif
10359#ifdef _SC_XOPEN_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010360 {"SC_XOPEN_VERSION", _SC_XOPEN_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010361#endif
10362#ifdef _SC_XOPEN_XCU_VERSION
Victor Stinner8c62be82010-05-06 00:08:46 +000010363 {"SC_XOPEN_XCU_VERSION", _SC_XOPEN_XCU_VERSION},
Fred Drakec9680921999-12-13 16:37:25 +000010364#endif
10365#ifdef _SC_XOPEN_XPG2
Victor Stinner8c62be82010-05-06 00:08:46 +000010366 {"SC_XOPEN_XPG2", _SC_XOPEN_XPG2},
Fred Drakec9680921999-12-13 16:37:25 +000010367#endif
10368#ifdef _SC_XOPEN_XPG3
Victor Stinner8c62be82010-05-06 00:08:46 +000010369 {"SC_XOPEN_XPG3", _SC_XOPEN_XPG3},
Fred Drakec9680921999-12-13 16:37:25 +000010370#endif
10371#ifdef _SC_XOPEN_XPG4
Victor Stinner8c62be82010-05-06 00:08:46 +000010372 {"SC_XOPEN_XPG4", _SC_XOPEN_XPG4},
Fred Drakec9680921999-12-13 16:37:25 +000010373#endif
10374};
10375
10376static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010377conv_sysconf_confname(PyObject *arg, int *valuep)
Fred Drakec9680921999-12-13 16:37:25 +000010378{
10379 return conv_confname(arg, valuep, posix_constants_sysconf,
10380 sizeof(posix_constants_sysconf)
10381 / sizeof(struct constdef));
10382}
10383
Larry Hastings2f936352014-08-05 14:04:04 +100010384
10385/*[clinic input]
10386os.sysconf -> long
10387 name: sysconf_confname
10388 /
10389
10390Return an integer-valued system configuration variable.
10391[clinic start generated code]*/
10392
Larry Hastings2f936352014-08-05 14:04:04 +100010393static long
10394os_sysconf_impl(PyModuleDef *module, int name)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010395/*[clinic end generated code: output=ed567306f58d69c4 input=279e3430a33f29e4]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010396{
10397 long value;
10398
10399 errno = 0;
10400 value = sysconf(name);
10401 if (value == -1 && errno != 0)
10402 posix_error();
10403 return value;
10404}
10405#endif /* HAVE_SYSCONF */
Fred Drakec9680921999-12-13 16:37:25 +000010406
10407
Fred Drakebec628d1999-12-15 18:31:10 +000010408/* This code is used to ensure that the tables of configuration value names
Serhiy Storchaka56a6d852014-12-01 18:28:43 +020010409 * are in sorted order as required by conv_confname(), and also to build
Fred Drakebec628d1999-12-15 18:31:10 +000010410 * the exported dictionaries that are used to publish information about the
10411 * names available on the host platform.
10412 *
10413 * Sorting the table at runtime ensures that the table is properly ordered
10414 * when used, even for platforms we're not able to test on. It also makes
10415 * it easier to add additional entries to the tables.
Fred Draked86ed291999-12-15 15:34:33 +000010416 */
Fred Drakebec628d1999-12-15 18:31:10 +000010417
10418static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010419cmp_constdefs(const void *v1, const void *v2)
Fred Drakebec628d1999-12-15 18:31:10 +000010420{
10421 const struct constdef *c1 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010422 (const struct constdef *) v1;
Fred Drakebec628d1999-12-15 18:31:10 +000010423 const struct constdef *c2 =
Victor Stinner8c62be82010-05-06 00:08:46 +000010424 (const struct constdef *) v2;
Fred Drakebec628d1999-12-15 18:31:10 +000010425
10426 return strcmp(c1->name, c2->name);
10427}
10428
10429static int
Fredrik Lundhff7df9d2000-07-08 22:48:53 +000010430setup_confname_table(struct constdef *table, size_t tablesize,
Victor Stinner8c62be82010-05-06 00:08:46 +000010431 char *tablename, PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010432{
Fred Drakebec628d1999-12-15 18:31:10 +000010433 PyObject *d = NULL;
Barry Warsaw3155db32000-04-13 15:20:40 +000010434 size_t i;
Fred Drakebec628d1999-12-15 18:31:10 +000010435
10436 qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
10437 d = PyDict_New();
Barry Warsaw3155db32000-04-13 15:20:40 +000010438 if (d == NULL)
Victor Stinner8c62be82010-05-06 00:08:46 +000010439 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010440
Barry Warsaw3155db32000-04-13 15:20:40 +000010441 for (i=0; i < tablesize; ++i) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010442 PyObject *o = PyLong_FromLong(table[i].value);
10443 if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
10444 Py_XDECREF(o);
10445 Py_DECREF(d);
10446 return -1;
10447 }
10448 Py_DECREF(o);
Fred Draked86ed291999-12-15 15:34:33 +000010449 }
Fred Drake4d1e64b2002-04-15 19:40:07 +000010450 return PyModule_AddObject(module, tablename, d);
Fred Draked86ed291999-12-15 15:34:33 +000010451}
10452
Fred Drakebec628d1999-12-15 18:31:10 +000010453/* Return -1 on failure, 0 on success. */
10454static int
Fred Drake4d1e64b2002-04-15 19:40:07 +000010455setup_confname_tables(PyObject *module)
Fred Draked86ed291999-12-15 15:34:33 +000010456{
10457#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
Fred Drakebec628d1999-12-15 18:31:10 +000010458 if (setup_confname_table(posix_constants_pathconf,
Fred Draked86ed291999-12-15 15:34:33 +000010459 sizeof(posix_constants_pathconf)
10460 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010461 "pathconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010462 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010463#endif
10464#ifdef HAVE_CONFSTR
Fred Drakebec628d1999-12-15 18:31:10 +000010465 if (setup_confname_table(posix_constants_confstr,
Fred Draked86ed291999-12-15 15:34:33 +000010466 sizeof(posix_constants_confstr)
10467 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010468 "confstr_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010469 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010470#endif
10471#ifdef HAVE_SYSCONF
Fred Drakebec628d1999-12-15 18:31:10 +000010472 if (setup_confname_table(posix_constants_sysconf,
Fred Draked86ed291999-12-15 15:34:33 +000010473 sizeof(posix_constants_sysconf)
10474 / sizeof(struct constdef),
Fred Drake4d1e64b2002-04-15 19:40:07 +000010475 "sysconf_names", module))
Stefan Krah0e803b32010-11-26 16:16:47 +000010476 return -1;
Fred Draked86ed291999-12-15 15:34:33 +000010477#endif
Fred Drakebec628d1999-12-15 18:31:10 +000010478 return 0;
Fred Draked86ed291999-12-15 15:34:33 +000010479}
Fred Draked86ed291999-12-15 15:34:33 +000010480
10481
Larry Hastings2f936352014-08-05 14:04:04 +100010482/*[clinic input]
10483os.abort
10484
10485Abort the interpreter immediately.
10486
10487This function 'dumps core' or otherwise fails in the hardest way possible
10488on the hosting operating system. This function never returns.
10489[clinic start generated code]*/
10490
Larry Hastings2f936352014-08-05 14:04:04 +100010491static PyObject *
10492os_abort_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010493/*[clinic end generated code: output=486bb96647c299b3 input=cf2c7d98bc504047]*/
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010494{
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010495 abort();
10496 /*NOTREACHED*/
10497 Py_FatalError("abort() called from Python code didn't abort!");
10498 return NULL;
10499}
Fred Drakebec628d1999-12-15 18:31:10 +000010500
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000010501#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100010502/* AC 3.5: change to path_t? but that might change exceptions */
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010503PyDoc_STRVAR(win32_startfile__doc__,
Larry Hastings2f936352014-08-05 14:04:04 +100010504"startfile(filepath [, operation])\n\
10505\n\
10506Start a file with its associated application.\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010507\n\
Georg Brandlf4f44152006-02-18 22:29:33 +000010508When \"operation\" is not specified or \"open\", this acts like\n\
10509double-clicking the file in Explorer, or giving the file name as an\n\
10510argument to the DOS \"start\" command: the file is opened with whatever\n\
10511application (if any) its extension is associated.\n\
10512When another \"operation\" is given, it specifies what should be done with\n\
10513the file. A typical operation is \"print\".\n\
Tim Petersf58a7aa2000-09-22 10:05:54 +000010514\n\
10515startfile returns as soon as the associated application is launched.\n\
10516There is no option to wait for the application to close, and no way\n\
10517to retrieve the application's exit status.\n\
10518\n\
10519The filepath is relative to the current directory. If you want to use\n\
10520an absolute path, make sure the first character is not a slash (\"/\");\n\
Martin v. Löwis14f8b4c2002-06-13 20:33:02 +000010521the underlying Win32 ShellExecute function doesn't work if it is.");
Tim Petersf58a7aa2000-09-22 10:05:54 +000010522
Steve Dower7d0e0c92015-01-24 08:18:24 -080010523/* Grab ShellExecute dynamically from shell32 */
10524static int has_ShellExecute = -1;
10525static HINSTANCE (CALLBACK *Py_ShellExecuteA)(HWND, LPCSTR, LPCSTR, LPCSTR,
10526 LPCSTR, INT);
10527static HINSTANCE (CALLBACK *Py_ShellExecuteW)(HWND, LPCWSTR, LPCWSTR, LPCWSTR,
10528 LPCWSTR, INT);
10529static int
10530check_ShellExecute()
10531{
10532 HINSTANCE hShell32;
10533
10534 /* only recheck */
10535 if (-1 == has_ShellExecute) {
10536 Py_BEGIN_ALLOW_THREADS
10537 hShell32 = LoadLibraryW(L"SHELL32");
10538 Py_END_ALLOW_THREADS
10539 if (hShell32) {
10540 *(FARPROC*)&Py_ShellExecuteA = GetProcAddress(hShell32,
10541 "ShellExecuteA");
10542 *(FARPROC*)&Py_ShellExecuteW = GetProcAddress(hShell32,
10543 "ShellExecuteW");
10544 has_ShellExecute = Py_ShellExecuteA &&
10545 Py_ShellExecuteW;
10546 } else {
10547 has_ShellExecute = 0;
10548 }
10549 }
10550 return has_ShellExecute;
10551}
10552
10553
Tim Petersf58a7aa2000-09-22 10:05:54 +000010554static PyObject *
10555win32_startfile(PyObject *self, PyObject *args)
10556{
Victor Stinner8c62be82010-05-06 00:08:46 +000010557 PyObject *ofilepath;
10558 char *filepath;
10559 char *operation = NULL;
Victor Stinnereb5657a2011-09-30 01:44:27 +020010560 wchar_t *wpath, *woperation;
Victor Stinner8c62be82010-05-06 00:08:46 +000010561 HINSTANCE rc;
Hirokazu Yamamoto8223c242009-05-17 04:21:53 +000010562
Victor Stinnereb5657a2011-09-30 01:44:27 +020010563 PyObject *unipath, *uoperation = NULL;
Steve Dower7d0e0c92015-01-24 08:18:24 -080010564
10565 if(!check_ShellExecute()) {
10566 /* If the OS doesn't have ShellExecute, return a
10567 NotImplementedError. */
10568 return PyErr_Format(PyExc_NotImplementedError,
10569 "startfile not available on this platform");
10570 }
10571
Victor Stinner8c62be82010-05-06 00:08:46 +000010572 if (!PyArg_ParseTuple(args, "U|s:startfile",
10573 &unipath, &operation)) {
10574 PyErr_Clear();
10575 goto normal;
10576 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010577
Victor Stinner8c62be82010-05-06 00:08:46 +000010578 if (operation) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010579 uoperation = PyUnicode_DecodeASCII(operation,
Victor Stinner8c62be82010-05-06 00:08:46 +000010580 strlen(operation), NULL);
Victor Stinnereb5657a2011-09-30 01:44:27 +020010581 if (!uoperation) {
Victor Stinner8c62be82010-05-06 00:08:46 +000010582 PyErr_Clear();
10583 operation = NULL;
10584 goto normal;
10585 }
10586 }
Hirokazu Yamamoto892a37a2009-06-28 11:07:03 +000010587
Victor Stinnereb5657a2011-09-30 01:44:27 +020010588 wpath = PyUnicode_AsUnicode(unipath);
10589 if (wpath == NULL)
10590 goto normal;
10591 if (uoperation) {
10592 woperation = PyUnicode_AsUnicode(uoperation);
10593 if (woperation == NULL)
10594 goto normal;
10595 }
10596 else
10597 woperation = NULL;
10598
Victor Stinner8c62be82010-05-06 00:08:46 +000010599 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010600 rc = Py_ShellExecuteW((HWND)0, woperation, wpath,
10601 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010602 Py_END_ALLOW_THREADS
10603
Victor Stinnereb5657a2011-09-30 01:44:27 +020010604 Py_XDECREF(uoperation);
Victor Stinner8c62be82010-05-06 00:08:46 +000010605 if (rc <= (HINSTANCE)32) {
Victor Stinnereb5657a2011-09-30 01:44:27 +020010606 win32_error_object("startfile", unipath);
10607 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000010608 }
10609 Py_INCREF(Py_None);
10610 return Py_None;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000010611
10612normal:
Victor Stinner8c62be82010-05-06 00:08:46 +000010613 if (!PyArg_ParseTuple(args, "O&|s:startfile",
10614 PyUnicode_FSConverter, &ofilepath,
10615 &operation))
10616 return NULL;
Victor Stinner1ab6c2d2011-11-15 22:27:41 +010010617 if (win32_warn_bytes_api()) {
10618 Py_DECREF(ofilepath);
10619 return NULL;
10620 }
Victor Stinner8c62be82010-05-06 00:08:46 +000010621 filepath = PyBytes_AsString(ofilepath);
10622 Py_BEGIN_ALLOW_THREADS
Steve Dower7d0e0c92015-01-24 08:18:24 -080010623 rc = Py_ShellExecuteA((HWND)0, operation, filepath,
10624 NULL, NULL, SW_SHOWNORMAL);
Victor Stinner8c62be82010-05-06 00:08:46 +000010625 Py_END_ALLOW_THREADS
10626 if (rc <= (HINSTANCE)32) {
10627 PyObject *errval = win32_error("startfile", filepath);
10628 Py_DECREF(ofilepath);
10629 return errval;
10630 }
10631 Py_DECREF(ofilepath);
10632 Py_INCREF(Py_None);
10633 return Py_None;
Tim Petersf58a7aa2000-09-22 10:05:54 +000010634}
Larry Hastings2f936352014-08-05 14:04:04 +100010635#endif /* MS_WINDOWS */
10636
Fred Drake5ab8eaf1999-12-09 21:13:07 +000010637
Martin v. Löwis438b5342002-12-27 10:16:42 +000010638#ifdef HAVE_GETLOADAVG
Larry Hastings2f936352014-08-05 14:04:04 +100010639/*[clinic input]
10640os.getloadavg
10641
10642Return average recent system load information.
10643
10644Return the number of processes in the system run queue averaged over
10645the last 1, 5, and 15 minutes as a tuple of three floats.
10646Raises OSError if the load average was unobtainable.
10647[clinic start generated code]*/
10648
Larry Hastings2f936352014-08-05 14:04:04 +100010649static PyObject *
10650os_getloadavg_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010651/*[clinic end generated code: output=2b64c5b675d74c14 input=3d6d826b76d8a34e]*/
Martin v. Löwis438b5342002-12-27 10:16:42 +000010652{
10653 double loadavg[3];
Martin v. Löwis438b5342002-12-27 10:16:42 +000010654 if (getloadavg(loadavg, 3)!=3) {
Stefan Krah0e803b32010-11-26 16:16:47 +000010655 PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
10656 return NULL;
Martin v. Löwis438b5342002-12-27 10:16:42 +000010657 } else
Stefan Krah0e803b32010-11-26 16:16:47 +000010658 return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
Martin v. Löwis438b5342002-12-27 10:16:42 +000010659}
Larry Hastings2f936352014-08-05 14:04:04 +100010660#endif /* HAVE_GETLOADAVG */
Martin v. Löwis438b5342002-12-27 10:16:42 +000010661
Larry Hastings2f936352014-08-05 14:04:04 +100010662
10663/*[clinic input]
10664os.device_encoding
10665 fd: int
10666
10667Return a string describing the encoding of a terminal's file descriptor.
10668
10669The file descriptor must be attached to a terminal.
10670If the device is not a terminal, return None.
10671[clinic start generated code]*/
10672
Larry Hastings2f936352014-08-05 14:04:04 +100010673static PyObject *
10674os_device_encoding_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010675/*[clinic end generated code: output=34f14e33468419c1 input=9e1d4a42b66df312]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010676{
Brett Cannonefb00c02012-02-29 18:31:31 -050010677 return _Py_device_encoding(fd);
Martin v. Löwisd1cd4d42007-08-11 14:02:14 +000010678}
10679
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010680
Larry Hastings2f936352014-08-05 14:04:04 +100010681#ifdef HAVE_SETRESUID
10682/*[clinic input]
10683os.setresuid
10684
10685 ruid: uid_t
10686 euid: uid_t
10687 suid: uid_t
10688 /
10689
10690Set the current process's real, effective, and saved user ids.
10691[clinic start generated code]*/
10692
Larry Hastings2f936352014-08-05 14:04:04 +100010693static PyObject *
10694os_setresuid_impl(PyModuleDef *module, uid_t ruid, uid_t euid, uid_t suid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010695/*[clinic end generated code: output=92cc330812c6ed0f input=9e33cb79a82792f3]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010696{
Victor Stinner8c62be82010-05-06 00:08:46 +000010697 if (setresuid(ruid, euid, suid) < 0)
10698 return posix_error();
10699 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010700}
Larry Hastings2f936352014-08-05 14:04:04 +100010701#endif /* HAVE_SETRESUID */
10702
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010703
10704#ifdef HAVE_SETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010705/*[clinic input]
10706os.setresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010707
Larry Hastings2f936352014-08-05 14:04:04 +100010708 rgid: gid_t
10709 egid: gid_t
10710 sgid: gid_t
10711 /
10712
10713Set the current process's real, effective, and saved group ids.
10714[clinic start generated code]*/
10715
Larry Hastings2f936352014-08-05 14:04:04 +100010716static PyObject *
10717os_setresgid_impl(PyModuleDef *module, gid_t rgid, gid_t egid, gid_t sgid)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010718/*[clinic end generated code: output=e91dc4842a604429 input=33e9e0785ef426b1]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010719{
Victor Stinner8c62be82010-05-06 00:08:46 +000010720 if (setresgid(rgid, egid, sgid) < 0)
10721 return posix_error();
10722 Py_RETURN_NONE;
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010723}
Larry Hastings2f936352014-08-05 14:04:04 +100010724#endif /* HAVE_SETRESGID */
10725
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010726
10727#ifdef HAVE_GETRESUID
Larry Hastings2f936352014-08-05 14:04:04 +100010728/*[clinic input]
10729os.getresuid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010730
Larry Hastings2f936352014-08-05 14:04:04 +100010731Return a tuple of the current process's real, effective, and saved user ids.
10732[clinic start generated code]*/
10733
Larry Hastings2f936352014-08-05 14:04:04 +100010734static PyObject *
10735os_getresuid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010736/*[clinic end generated code: output=9ddef62faae8e477 input=41ccfa8e1f6517ad]*/
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010737{
Victor Stinner8c62be82010-05-06 00:08:46 +000010738 uid_t ruid, euid, suid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010739 if (getresuid(&ruid, &euid, &suid) < 0)
10740 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010741 return Py_BuildValue("(NNN)", _PyLong_FromUid(ruid),
10742 _PyLong_FromUid(euid),
10743 _PyLong_FromUid(suid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010744}
Larry Hastings2f936352014-08-05 14:04:04 +100010745#endif /* HAVE_GETRESUID */
10746
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010747
10748#ifdef HAVE_GETRESGID
Larry Hastings2f936352014-08-05 14:04:04 +100010749/*[clinic input]
10750os.getresgid
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010751
Larry Hastings2f936352014-08-05 14:04:04 +100010752Return a tuple of the current process's real, effective, and saved group ids.
10753[clinic start generated code]*/
10754
Larry Hastings2f936352014-08-05 14:04:04 +100010755static PyObject *
10756os_getresgid_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010757/*[clinic end generated code: output=e1a553cbcf16234c input=517e68db9ca32df6]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010758{
10759 gid_t rgid, egid, sgid;
Victor Stinner8c62be82010-05-06 00:08:46 +000010760 if (getresgid(&rgid, &egid, &sgid) < 0)
10761 return posix_error();
Serhiy Storchaka7cf55992013-02-10 21:56:49 +020010762 return Py_BuildValue("(NNN)", _PyLong_FromGid(rgid),
10763 _PyLong_FromGid(egid),
10764 _PyLong_FromGid(sgid));
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010765}
Larry Hastings2f936352014-08-05 14:04:04 +100010766#endif /* HAVE_GETRESGID */
10767
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000010768
Benjamin Peterson9428d532011-09-14 11:45:52 -040010769#ifdef USE_XATTRS
Larry Hastings2f936352014-08-05 14:04:04 +100010770/*[clinic input]
10771os.getxattr
Benjamin Peterson799bd802011-08-31 22:15:17 -040010772
Larry Hastings2f936352014-08-05 14:04:04 +100010773 path: path_t(allow_fd=True)
10774 attribute: path_t
10775 *
10776 follow_symlinks: bool = True
10777
10778Return the value of extended attribute attribute on path.
10779
10780path may be either a string or an open file descriptor.
10781If follow_symlinks is False, and the last element of the path is a symbolic
10782 link, getxattr will examine the symbolic link itself instead of the file
10783 the link points to.
10784
10785[clinic start generated code]*/
10786
Larry Hastings2f936352014-08-05 14:04:04 +100010787static PyObject *
10788os_getxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010789/*[clinic end generated code: output=d90086b314859f8b input=8c8ea3bab78d89c2]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010790{
10791 Py_ssize_t i;
10792 PyObject *buffer = NULL;
10793
10794 if (fd_and_follow_symlinks_invalid("getxattr", path->fd, follow_symlinks))
10795 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010796
Larry Hastings9cf065c2012-06-22 16:30:09 -070010797 for (i = 0; ; i++) {
10798 void *ptr;
10799 ssize_t result;
10800 static Py_ssize_t buffer_sizes[] = {128, XATTR_SIZE_MAX, 0};
10801 Py_ssize_t buffer_size = buffer_sizes[i];
10802 if (!buffer_size) {
Larry Hastings2f936352014-08-05 14:04:04 +100010803 path_error(path);
10804 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010805 }
10806 buffer = PyBytes_FromStringAndSize(NULL, buffer_size);
10807 if (!buffer)
Larry Hastings2f936352014-08-05 14:04:04 +100010808 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010809 ptr = PyBytes_AS_STRING(buffer);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010810
Larry Hastings9cf065c2012-06-22 16:30:09 -070010811 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010812 if (path->fd >= 0)
10813 result = fgetxattr(path->fd, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010814 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010815 result = getxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010816 else
Larry Hastings2f936352014-08-05 14:04:04 +100010817 result = lgetxattr(path->narrow, attribute->narrow, ptr, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010818 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010819
Larry Hastings9cf065c2012-06-22 16:30:09 -070010820 if (result < 0) {
10821 Py_DECREF(buffer);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010822 if (errno == ERANGE)
10823 continue;
Larry Hastings2f936352014-08-05 14:04:04 +100010824 path_error(path);
10825 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010826 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010827
Larry Hastings9cf065c2012-06-22 16:30:09 -070010828 if (result != buffer_size) {
10829 /* Can only shrink. */
10830 _PyBytes_Resize(&buffer, result);
10831 }
10832 break;
10833 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010834
Larry Hastings9cf065c2012-06-22 16:30:09 -070010835 return buffer;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010836}
10837
Larry Hastings2f936352014-08-05 14:04:04 +100010838
10839/*[clinic input]
10840os.setxattr
10841
10842 path: path_t(allow_fd=True)
10843 attribute: path_t
10844 value: Py_buffer
10845 flags: int = 0
10846 *
10847 follow_symlinks: bool = True
10848
10849Set extended attribute attribute on path to value.
10850
10851path may be either a string or an open file descriptor.
10852If follow_symlinks is False, and the last element of the path is a symbolic
10853 link, setxattr will modify the symbolic link itself instead of the file
10854 the link points to.
10855
10856[clinic start generated code]*/
10857
Benjamin Peterson799bd802011-08-31 22:15:17 -040010858static PyObject *
Larry Hastings2f936352014-08-05 14:04:04 +100010859os_setxattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, Py_buffer *value, int flags, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010860/*[clinic end generated code: output=e3defa5c4b1ad0ae input=f0d26833992015c2]*/
Benjamin Peterson799bd802011-08-31 22:15:17 -040010861{
Larry Hastings2f936352014-08-05 14:04:04 +100010862 ssize_t result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010863
Larry Hastings2f936352014-08-05 14:04:04 +100010864 if (fd_and_follow_symlinks_invalid("setxattr", path->fd, follow_symlinks))
Benjamin Peterson799bd802011-08-31 22:15:17 -040010865 return NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010866
Benjamin Peterson799bd802011-08-31 22:15:17 -040010867 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010868 if (path->fd > -1)
10869 result = fsetxattr(path->fd, attribute->narrow,
10870 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010871 else if (follow_symlinks)
Larry Hastings2f936352014-08-05 14:04:04 +100010872 result = setxattr(path->narrow, attribute->narrow,
10873 value->buf, value->len, flags);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010874 else
Larry Hastings2f936352014-08-05 14:04:04 +100010875 result = lsetxattr(path->narrow, attribute->narrow,
10876 value->buf, value->len, flags);
Benjamin Peterson799bd802011-08-31 22:15:17 -040010877 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010878
Larry Hastings9cf065c2012-06-22 16:30:09 -070010879 if (result) {
Larry Hastings2f936352014-08-05 14:04:04 +100010880 path_error(path);
10881 return NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010882 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010883
Larry Hastings2f936352014-08-05 14:04:04 +100010884 Py_RETURN_NONE;
10885}
10886
10887
10888/*[clinic input]
10889os.removexattr
10890
10891 path: path_t(allow_fd=True)
10892 attribute: path_t
10893 *
10894 follow_symlinks: bool = True
10895
10896Remove extended attribute attribute on path.
10897
10898path may be either a string or an open file descriptor.
10899If follow_symlinks is False, and the last element of the path is a symbolic
10900 link, removexattr will modify the symbolic link itself instead of the file
10901 the link points to.
10902
10903[clinic start generated code]*/
10904
Larry Hastings2f936352014-08-05 14:04:04 +100010905static PyObject *
10906os_removexattr_impl(PyModuleDef *module, path_t *path, path_t *attribute, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010907/*[clinic end generated code: output=4870ec90249af875 input=cdb54834161e3329]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010908{
10909 ssize_t result;
10910
10911 if (fd_and_follow_symlinks_invalid("removexattr", path->fd, follow_symlinks))
10912 return NULL;
10913
10914 Py_BEGIN_ALLOW_THREADS;
10915 if (path->fd > -1)
10916 result = fremovexattr(path->fd, attribute->narrow);
10917 else if (follow_symlinks)
10918 result = removexattr(path->narrow, attribute->narrow);
10919 else
10920 result = lremovexattr(path->narrow, attribute->narrow);
10921 Py_END_ALLOW_THREADS;
10922
10923 if (result) {
10924 return path_error(path);
10925 }
10926
10927 Py_RETURN_NONE;
10928}
10929
10930
10931/*[clinic input]
10932os.listxattr
10933
10934 path: path_t(allow_fd=True, nullable=True) = None
10935 *
10936 follow_symlinks: bool = True
10937
10938Return a list of extended attributes on path.
10939
10940path may be either None, a string, or an open file descriptor.
10941if path is None, listxattr will examine the current directory.
10942If follow_symlinks is False, and the last element of the path is a symbolic
10943 link, listxattr will examine the symbolic link itself instead of the file
10944 the link points to.
10945[clinic start generated code]*/
10946
Larry Hastings2f936352014-08-05 14:04:04 +100010947static PyObject *
10948os_listxattr_impl(PyModuleDef *module, path_t *path, int follow_symlinks)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030010949/*[clinic end generated code: output=a87ad6ce56e42a4f input=08cca53ac0b07c13]*/
Larry Hastings2f936352014-08-05 14:04:04 +100010950{
Larry Hastings9cf065c2012-06-22 16:30:09 -070010951 Py_ssize_t i;
10952 PyObject *result = NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100010953 const char *name;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010954 char *buffer = NULL;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010955
Larry Hastings2f936352014-08-05 14:04:04 +100010956 if (fd_and_follow_symlinks_invalid("listxattr", path->fd, follow_symlinks))
Larry Hastings9cf065c2012-06-22 16:30:09 -070010957 goto exit;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010958
Larry Hastings2f936352014-08-05 14:04:04 +100010959 name = path->narrow ? path->narrow : ".";
10960
Larry Hastings9cf065c2012-06-22 16:30:09 -070010961 for (i = 0; ; i++) {
10962 char *start, *trace, *end;
10963 ssize_t length;
10964 static Py_ssize_t buffer_sizes[] = { 256, XATTR_LIST_MAX, 0 };
10965 Py_ssize_t buffer_size = buffer_sizes[i];
10966 if (!buffer_size) {
Christian Heimes3b9493b2012-09-23 16:11:15 +020010967 /* ERANGE */
Larry Hastings2f936352014-08-05 14:04:04 +100010968 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010969 break;
10970 }
10971 buffer = PyMem_MALLOC(buffer_size);
10972 if (!buffer) {
10973 PyErr_NoMemory();
10974 break;
10975 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010976
Larry Hastings9cf065c2012-06-22 16:30:09 -070010977 Py_BEGIN_ALLOW_THREADS;
Larry Hastings2f936352014-08-05 14:04:04 +100010978 if (path->fd > -1)
10979 length = flistxattr(path->fd, buffer, buffer_size);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010980 else if (follow_symlinks)
10981 length = listxattr(name, buffer, buffer_size);
10982 else
10983 length = llistxattr(name, buffer, buffer_size);
10984 Py_END_ALLOW_THREADS;
Benjamin Peterson799bd802011-08-31 22:15:17 -040010985
Larry Hastings9cf065c2012-06-22 16:30:09 -070010986 if (length < 0) {
Antoine Pitrou7f987392013-05-13 19:46:29 +020010987 if (errno == ERANGE) {
10988 PyMem_FREE(buffer);
Benjamin Petersondedac522013-05-13 19:55:40 -050010989 buffer = NULL;
Larry Hastings9cf065c2012-06-22 16:30:09 -070010990 continue;
Antoine Pitrou7f987392013-05-13 19:46:29 +020010991 }
Larry Hastings2f936352014-08-05 14:04:04 +100010992 path_error(path);
Larry Hastings9cf065c2012-06-22 16:30:09 -070010993 break;
10994 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040010995
Larry Hastings9cf065c2012-06-22 16:30:09 -070010996 result = PyList_New(0);
10997 if (!result) {
10998 goto exit;
10999 }
Benjamin Peterson799bd802011-08-31 22:15:17 -040011000
Larry Hastings9cf065c2012-06-22 16:30:09 -070011001 end = buffer + length;
11002 for (trace = start = buffer; trace != end; trace++) {
11003 if (!*trace) {
11004 int error;
11005 PyObject *attribute = PyUnicode_DecodeFSDefaultAndSize(start,
11006 trace - start);
11007 if (!attribute) {
11008 Py_DECREF(result);
11009 result = NULL;
11010 goto exit;
11011 }
11012 error = PyList_Append(result, attribute);
11013 Py_DECREF(attribute);
11014 if (error) {
11015 Py_DECREF(result);
11016 result = NULL;
11017 goto exit;
11018 }
11019 start = trace + 1;
11020 }
11021 }
11022 break;
11023 }
11024exit:
Larry Hastings9cf065c2012-06-22 16:30:09 -070011025 if (buffer)
11026 PyMem_FREE(buffer);
11027 return result;
Benjamin Peterson799bd802011-08-31 22:15:17 -040011028}
Benjamin Peterson9428d532011-09-14 11:45:52 -040011029#endif /* USE_XATTRS */
Benjamin Peterson799bd802011-08-31 22:15:17 -040011030
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011031
Larry Hastings2f936352014-08-05 14:04:04 +100011032/*[clinic input]
11033os.urandom
11034
11035 size: Py_ssize_t
11036 /
11037
11038Return a bytes object containing random bytes suitable for cryptographic use.
11039[clinic start generated code]*/
11040
Larry Hastings2f936352014-08-05 14:04:04 +100011041static PyObject *
11042os_urandom_impl(PyModuleDef *module, Py_ssize_t size)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011043/*[clinic end generated code: output=e0011f021501f03b input=4067cdb1b6776c29]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011044{
11045 PyObject *bytes;
11046 int result;
11047
Georg Brandl2fb477c2012-02-21 00:33:36 +010011048 if (size < 0)
11049 return PyErr_Format(PyExc_ValueError,
11050 "negative argument not allowed");
Larry Hastings2f936352014-08-05 14:04:04 +100011051 bytes = PyBytes_FromStringAndSize(NULL, size);
11052 if (bytes == NULL)
Georg Brandl2fb477c2012-02-21 00:33:36 +010011053 return NULL;
11054
Larry Hastings2f936352014-08-05 14:04:04 +100011055 result = _PyOS_URandom(PyBytes_AS_STRING(bytes),
11056 PyBytes_GET_SIZE(bytes));
11057 if (result == -1) {
11058 Py_DECREF(bytes);
Georg Brandl2fb477c2012-02-21 00:33:36 +010011059 return NULL;
11060 }
Larry Hastings2f936352014-08-05 14:04:04 +100011061 return bytes;
Georg Brandl2fb477c2012-02-21 00:33:36 +010011062}
11063
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011064/* Terminal size querying */
11065
11066static PyTypeObject TerminalSizeType;
11067
11068PyDoc_STRVAR(TerminalSize_docstring,
11069 "A tuple of (columns, lines) for holding terminal window size");
11070
11071static PyStructSequence_Field TerminalSize_fields[] = {
11072 {"columns", "width of the terminal window in characters"},
11073 {"lines", "height of the terminal window in characters"},
11074 {NULL, NULL}
11075};
11076
11077static PyStructSequence_Desc TerminalSize_desc = {
11078 "os.terminal_size",
11079 TerminalSize_docstring,
11080 TerminalSize_fields,
11081 2,
11082};
11083
11084#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
Larry Hastings2f936352014-08-05 14:04:04 +100011085/* AC 3.5: fd should accept None */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011086PyDoc_STRVAR(termsize__doc__,
11087 "Return the size of the terminal window as (columns, lines).\n" \
11088 "\n" \
11089 "The optional argument fd (default standard output) specifies\n" \
11090 "which file descriptor should be queried.\n" \
11091 "\n" \
11092 "If the file descriptor is not connected to a terminal, an OSError\n" \
11093 "is thrown.\n" \
11094 "\n" \
11095 "This function will only be defined if an implementation is\n" \
11096 "available for this system.\n" \
11097 "\n" \
11098 "shutil.get_terminal_size is the high-level function which should \n" \
11099 "normally be used, os.get_terminal_size is the low-level implementation.");
11100
11101static PyObject*
11102get_terminal_size(PyObject *self, PyObject *args)
11103{
11104 int columns, lines;
11105 PyObject *termsize;
11106
11107 int fd = fileno(stdout);
11108 /* Under some conditions stdout may not be connected and
11109 * fileno(stdout) may point to an invalid file descriptor. For example
11110 * GUI apps don't have valid standard streams by default.
11111 *
11112 * If this happens, and the optional fd argument is not present,
11113 * the ioctl below will fail returning EBADF. This is what we want.
11114 */
11115
11116 if (!PyArg_ParseTuple(args, "|i", &fd))
11117 return NULL;
11118
11119#ifdef TERMSIZE_USE_IOCTL
11120 {
11121 struct winsize w;
11122 if (ioctl(fd, TIOCGWINSZ, &w))
11123 return PyErr_SetFromErrno(PyExc_OSError);
11124 columns = w.ws_col;
11125 lines = w.ws_row;
11126 }
11127#endif /* TERMSIZE_USE_IOCTL */
11128
11129#ifdef TERMSIZE_USE_CONIO
11130 {
11131 DWORD nhandle;
11132 HANDLE handle;
11133 CONSOLE_SCREEN_BUFFER_INFO csbi;
11134 switch (fd) {
11135 case 0: nhandle = STD_INPUT_HANDLE;
11136 break;
11137 case 1: nhandle = STD_OUTPUT_HANDLE;
11138 break;
11139 case 2: nhandle = STD_ERROR_HANDLE;
11140 break;
11141 default:
11142 return PyErr_Format(PyExc_ValueError, "bad file descriptor");
11143 }
11144 handle = GetStdHandle(nhandle);
11145 if (handle == NULL)
11146 return PyErr_Format(PyExc_OSError, "handle cannot be retrieved");
11147 if (handle == INVALID_HANDLE_VALUE)
11148 return PyErr_SetFromWindowsErr(0);
11149
11150 if (!GetConsoleScreenBufferInfo(handle, &csbi))
11151 return PyErr_SetFromWindowsErr(0);
11152
11153 columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
11154 lines = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;
11155 }
11156#endif /* TERMSIZE_USE_CONIO */
11157
11158 termsize = PyStructSequence_New(&TerminalSizeType);
11159 if (termsize == NULL)
11160 return NULL;
11161 PyStructSequence_SET_ITEM(termsize, 0, PyLong_FromLong(columns));
11162 PyStructSequence_SET_ITEM(termsize, 1, PyLong_FromLong(lines));
11163 if (PyErr_Occurred()) {
11164 Py_DECREF(termsize);
11165 return NULL;
11166 }
11167 return termsize;
11168}
11169#endif /* defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL) */
11170
Larry Hastings2f936352014-08-05 14:04:04 +100011171
11172/*[clinic input]
11173os.cpu_count
11174
11175Return the number of CPUs in the system; return None if indeterminable.
11176[clinic start generated code]*/
11177
Larry Hastings2f936352014-08-05 14:04:04 +100011178static PyObject *
11179os_cpu_count_impl(PyModuleDef *module)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011180/*[clinic end generated code: output=c59ee7f6bce832b8 input=d55e2f8f3823a628]*/
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011181{
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011182 int ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011183#ifdef MS_WINDOWS
11184 SYSTEM_INFO sysinfo;
11185 GetSystemInfo(&sysinfo);
11186 ncpu = sysinfo.dwNumberOfProcessors;
11187#elif defined(__hpux)
11188 ncpu = mpctl(MPC_GETNUMSPUS, NULL, NULL);
11189#elif defined(HAVE_SYSCONF) && defined(_SC_NPROCESSORS_ONLN)
11190 ncpu = sysconf(_SC_NPROCESSORS_ONLN);
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011191#elif defined(__DragonFly__) || \
11192 defined(__OpenBSD__) || \
11193 defined(__FreeBSD__) || \
Charles-Francois Natalid59087d2013-05-20 17:31:06 +020011194 defined(__NetBSD__) || \
11195 defined(__APPLE__)
Charles-Francois Natali7c4f8da2013-05-20 17:40:32 +020011196 int mib[2];
11197 size_t len = sizeof(ncpu);
11198 mib[0] = CTL_HW;
11199 mib[1] = HW_NCPU;
11200 if (sysctl(mib, 2, &ncpu, &len, NULL, 0) != 0)
11201 ncpu = 0;
Charles-Francois Natali44feda32013-05-20 14:40:46 +020011202#endif
11203 if (ncpu >= 1)
11204 return PyLong_FromLong(ncpu);
11205 else
11206 Py_RETURN_NONE;
11207}
11208
Victor Stinnerdaf45552013-08-28 00:53:59 +020011209
Larry Hastings2f936352014-08-05 14:04:04 +100011210/*[clinic input]
11211os.get_inheritable -> bool
11212
11213 fd: int
11214 /
11215
11216Get the close-on-exe flag of the specified file descriptor.
11217[clinic start generated code]*/
11218
Larry Hastings2f936352014-08-05 14:04:04 +100011219static int
11220os_get_inheritable_impl(PyModuleDef *module, int fd)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011221/*[clinic end generated code: output=36110bb36efaa21e input=89ac008dc9ab6b95]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011222{
Steve Dower8fc89802015-04-12 00:26:27 -040011223 int return_value;
11224 if (!_PyVerify_fd(fd)) {
Larry Hastings2f936352014-08-05 14:04:04 +100011225 posix_error();
11226 return -1;
11227 }
11228
Steve Dower8fc89802015-04-12 00:26:27 -040011229 _Py_BEGIN_SUPPRESS_IPH
11230 return_value = _Py_get_inheritable(fd);
11231 _Py_END_SUPPRESS_IPH
11232 return return_value;
Larry Hastings2f936352014-08-05 14:04:04 +100011233}
11234
11235
11236/*[clinic input]
11237os.set_inheritable
11238 fd: int
11239 inheritable: int
11240 /
11241
11242Set the inheritable flag of the specified file descriptor.
11243[clinic start generated code]*/
11244
Larry Hastings2f936352014-08-05 14:04:04 +100011245static PyObject *
11246os_set_inheritable_impl(PyModuleDef *module, int fd, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011247/*[clinic end generated code: output=2ac5c6ce8623f045 input=9ceaead87a1e2402]*/
Victor Stinnerdaf45552013-08-28 00:53:59 +020011248{
Steve Dower8fc89802015-04-12 00:26:27 -040011249 int result;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011250 if (!_PyVerify_fd(fd))
11251 return posix_error();
11252
Steve Dower8fc89802015-04-12 00:26:27 -040011253 _Py_BEGIN_SUPPRESS_IPH
11254 result = _Py_set_inheritable(fd, inheritable, NULL);
11255 _Py_END_SUPPRESS_IPH
11256 if (result < 0)
Victor Stinnerdaf45552013-08-28 00:53:59 +020011257 return NULL;
11258 Py_RETURN_NONE;
11259}
11260
11261
11262#ifdef MS_WINDOWS
Larry Hastings2f936352014-08-05 14:04:04 +100011263/*[clinic input]
11264os.get_handle_inheritable -> bool
11265 handle: Py_intptr_t
11266 /
Victor Stinnerdaf45552013-08-28 00:53:59 +020011267
Larry Hastings2f936352014-08-05 14:04:04 +100011268Get the close-on-exe flag of the specified file descriptor.
11269[clinic start generated code]*/
11270
Larry Hastings2f936352014-08-05 14:04:04 +100011271static int
11272os_get_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011273/*[clinic end generated code: output=3b7b3e1b43f312b6 input=5f7759443aae3dc5]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011274{
11275 DWORD flags;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011276
11277 if (!GetHandleInformation((HANDLE)handle, &flags)) {
11278 PyErr_SetFromWindowsErr(0);
Larry Hastings2f936352014-08-05 14:04:04 +100011279 return -1;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011280 }
11281
Larry Hastings2f936352014-08-05 14:04:04 +100011282 return flags & HANDLE_FLAG_INHERIT;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011283}
11284
Victor Stinnerdaf45552013-08-28 00:53:59 +020011285
Larry Hastings2f936352014-08-05 14:04:04 +100011286/*[clinic input]
11287os.set_handle_inheritable
11288 handle: Py_intptr_t
11289 inheritable: bool
11290 /
11291
11292Set the inheritable flag of the specified handle.
11293[clinic start generated code]*/
11294
Larry Hastings2f936352014-08-05 14:04:04 +100011295static PyObject *
11296os_set_handle_inheritable_impl(PyModuleDef *module, Py_intptr_t handle, int inheritable)
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030011297/*[clinic end generated code: output=627aa5b158b69338 input=e64b2b2730469def]*/
Larry Hastings2f936352014-08-05 14:04:04 +100011298{
11299 DWORD flags = inheritable ? HANDLE_FLAG_INHERIT : 0;
Victor Stinnerdaf45552013-08-28 00:53:59 +020011300 if (!SetHandleInformation((HANDLE)handle, HANDLE_FLAG_INHERIT, flags)) {
11301 PyErr_SetFromWindowsErr(0);
11302 return NULL;
11303 }
11304 Py_RETURN_NONE;
11305}
Larry Hastings2f936352014-08-05 14:04:04 +100011306#endif /* MS_WINDOWS */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010011307
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011308#ifndef MS_WINDOWS
11309PyDoc_STRVAR(get_blocking__doc__,
11310 "get_blocking(fd) -> bool\n" \
11311 "\n" \
11312 "Get the blocking mode of the file descriptor:\n" \
11313 "False if the O_NONBLOCK flag is set, True if the flag is cleared.");
11314
11315static PyObject*
11316posix_get_blocking(PyObject *self, PyObject *args)
11317{
11318 int fd;
11319 int blocking;
11320
11321 if (!PyArg_ParseTuple(args, "i:get_blocking", &fd))
11322 return NULL;
11323
11324 if (!_PyVerify_fd(fd))
11325 return posix_error();
11326
Steve Dower8fc89802015-04-12 00:26:27 -040011327 _Py_BEGIN_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011328 blocking = _Py_get_blocking(fd);
Steve Dower8fc89802015-04-12 00:26:27 -040011329 _Py_END_SUPPRESS_IPH
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011330 if (blocking < 0)
11331 return NULL;
11332 return PyBool_FromLong(blocking);
11333}
11334
11335PyDoc_STRVAR(set_blocking__doc__,
11336 "set_blocking(fd, blocking)\n" \
11337 "\n" \
11338 "Set the blocking mode of the specified file descriptor.\n" \
11339 "Set the O_NONBLOCK flag if blocking is False,\n" \
11340 "clear the O_NONBLOCK flag otherwise.");
11341
11342static PyObject*
11343posix_set_blocking(PyObject *self, PyObject *args)
11344{
Steve Dower8fc89802015-04-12 00:26:27 -040011345 int fd, blocking, result;
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011346
11347 if (!PyArg_ParseTuple(args, "ii:set_blocking", &fd, &blocking))
11348 return NULL;
11349
11350 if (!_PyVerify_fd(fd))
11351 return posix_error();
11352
Steve Dower8fc89802015-04-12 00:26:27 -040011353 _Py_BEGIN_SUPPRESS_IPH
11354 result = _Py_set_blocking(fd, blocking);
11355 _Py_END_SUPPRESS_IPH
11356 if (result < 0)
Victor Stinner1db9e7b2014-07-29 22:32:47 +020011357 return NULL;
11358 Py_RETURN_NONE;
11359}
11360#endif /* !MS_WINDOWS */
11361
11362
Victor Stinner6036e442015-03-08 01:58:04 +010011363PyDoc_STRVAR(posix_scandir__doc__,
11364"scandir(path='.') -> iterator of DirEntry objects for given path");
11365
11366static char *follow_symlinks_keywords[] = {"follow_symlinks", NULL};
11367
11368typedef struct {
11369 PyObject_HEAD
11370 PyObject *name;
11371 PyObject *path;
11372 PyObject *stat;
11373 PyObject *lstat;
11374#ifdef MS_WINDOWS
11375 struct _Py_stat_struct win32_lstat;
11376 __int64 win32_file_index;
11377 int got_file_index;
11378#else /* POSIX */
Victor Stinner35a97c02015-03-08 02:59:09 +010011379#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011380 unsigned char d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011381#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011382 ino_t d_ino;
11383#endif
11384} DirEntry;
11385
11386static void
11387DirEntry_dealloc(DirEntry *entry)
11388{
11389 Py_XDECREF(entry->name);
11390 Py_XDECREF(entry->path);
11391 Py_XDECREF(entry->stat);
11392 Py_XDECREF(entry->lstat);
11393 Py_TYPE(entry)->tp_free((PyObject *)entry);
11394}
11395
11396/* Forward reference */
11397static int
11398DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits);
11399
11400/* Set exception and return -1 on error, 0 for False, 1 for True */
11401static int
11402DirEntry_is_symlink(DirEntry *self)
11403{
11404#ifdef MS_WINDOWS
11405 return (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
Victor Stinner35a97c02015-03-08 02:59:09 +010011406#elif defined(HAVE_DIRENT_D_TYPE)
11407 /* POSIX */
Victor Stinner6036e442015-03-08 01:58:04 +010011408 if (self->d_type != DT_UNKNOWN)
11409 return self->d_type == DT_LNK;
11410 else
11411 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner35a97c02015-03-08 02:59:09 +010011412#else
11413 /* POSIX without d_type */
11414 return DirEntry_test_mode(self, 0, S_IFLNK);
Victor Stinner6036e442015-03-08 01:58:04 +010011415#endif
11416}
11417
11418static PyObject *
11419DirEntry_py_is_symlink(DirEntry *self)
11420{
11421 int result;
11422
11423 result = DirEntry_is_symlink(self);
11424 if (result == -1)
11425 return NULL;
11426 return PyBool_FromLong(result);
11427}
11428
11429static PyObject *
11430DirEntry_fetch_stat(DirEntry *self, int follow_symlinks)
11431{
11432 int result;
11433 struct _Py_stat_struct st;
11434
11435#ifdef MS_WINDOWS
11436 wchar_t *path;
11437
11438 path = PyUnicode_AsUnicode(self->path);
11439 if (!path)
11440 return NULL;
11441
11442 if (follow_symlinks)
11443 result = win32_stat_w(path, &st);
11444 else
11445 result = win32_lstat_w(path, &st);
11446
11447 if (result != 0) {
11448 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11449 0, self->path);
11450 }
11451#else /* POSIX */
11452 PyObject *bytes;
11453 char *path;
11454
11455 if (!PyUnicode_FSConverter(self->path, &bytes))
11456 return NULL;
11457 path = PyBytes_AS_STRING(bytes);
11458
11459 if (follow_symlinks)
11460 result = STAT(path, &st);
11461 else
11462 result = LSTAT(path, &st);
11463 Py_DECREF(bytes);
11464
11465 if (result != 0)
11466 return PyErr_SetFromErrnoWithFilenameObject(PyExc_OSError, self->path);
11467#endif
11468
11469 return _pystat_fromstructstat(&st);
11470}
11471
11472static PyObject *
11473DirEntry_get_lstat(DirEntry *self)
11474{
11475 if (!self->lstat) {
11476#ifdef MS_WINDOWS
11477 self->lstat = _pystat_fromstructstat(&self->win32_lstat);
11478#else /* POSIX */
11479 self->lstat = DirEntry_fetch_stat(self, 0);
11480#endif
11481 }
11482 Py_XINCREF(self->lstat);
11483 return self->lstat;
11484}
11485
11486static PyObject *
11487DirEntry_get_stat(DirEntry *self, int follow_symlinks)
11488{
11489 if (!follow_symlinks)
11490 return DirEntry_get_lstat(self);
11491
11492 if (!self->stat) {
11493 int result = DirEntry_is_symlink(self);
11494 if (result == -1)
11495 return NULL;
11496 else if (result)
11497 self->stat = DirEntry_fetch_stat(self, 1);
11498 else
11499 self->stat = DirEntry_get_lstat(self);
11500 }
11501
11502 Py_XINCREF(self->stat);
11503 return self->stat;
11504}
11505
11506static PyObject *
11507DirEntry_stat(DirEntry *self, PyObject *args, PyObject *kwargs)
11508{
11509 int follow_symlinks = 1;
11510
11511 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.stat",
11512 follow_symlinks_keywords, &follow_symlinks))
11513 return NULL;
11514
11515 return DirEntry_get_stat(self, follow_symlinks);
11516}
11517
11518/* Set exception and return -1 on error, 0 for False, 1 for True */
11519static int
11520DirEntry_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11521{
11522 PyObject *stat = NULL;
11523 PyObject *st_mode = NULL;
11524 long mode;
11525 int result;
Victor Stinner35a97c02015-03-08 02:59:09 +010011526#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011527 int is_symlink;
11528 int need_stat;
Victor Stinner35a97c02015-03-08 02:59:09 +010011529#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011530#ifdef MS_WINDOWS
11531 unsigned long dir_bits;
11532#endif
Victor Stinner35a97c02015-03-08 02:59:09 +010011533 _Py_IDENTIFIER(st_mode);
Victor Stinner6036e442015-03-08 01:58:04 +010011534
11535#ifdef MS_WINDOWS
11536 is_symlink = (self->win32_lstat.st_mode & S_IFMT) == S_IFLNK;
11537 need_stat = follow_symlinks && is_symlink;
Victor Stinner35a97c02015-03-08 02:59:09 +010011538#elif defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011539 is_symlink = self->d_type == DT_LNK;
11540 need_stat = self->d_type == DT_UNKNOWN || (follow_symlinks && is_symlink);
11541#endif
11542
Victor Stinner35a97c02015-03-08 02:59:09 +010011543#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011544 if (need_stat) {
Victor Stinner35a97c02015-03-08 02:59:09 +010011545#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011546 stat = DirEntry_get_stat(self, follow_symlinks);
11547 if (!stat) {
11548 if (PyErr_ExceptionMatches(PyExc_FileNotFoundError)) {
11549 /* If file doesn't exist (anymore), then return False
11550 (i.e., say it's not a file/directory) */
11551 PyErr_Clear();
11552 return 0;
11553 }
11554 goto error;
11555 }
11556 st_mode = _PyObject_GetAttrId(stat, &PyId_st_mode);
11557 if (!st_mode)
11558 goto error;
11559
11560 mode = PyLong_AsLong(st_mode);
11561 if (mode == -1 && PyErr_Occurred())
11562 goto error;
11563 Py_CLEAR(st_mode);
11564 Py_CLEAR(stat);
11565 result = (mode & S_IFMT) == mode_bits;
Victor Stinner35a97c02015-03-08 02:59:09 +010011566#if defined(MS_WINDOWS) || defined(HAVE_DIRENT_D_TYPE)
Victor Stinner6036e442015-03-08 01:58:04 +010011567 }
11568 else if (is_symlink) {
11569 assert(mode_bits != S_IFLNK);
11570 result = 0;
11571 }
11572 else {
11573 assert(mode_bits == S_IFDIR || mode_bits == S_IFREG);
11574#ifdef MS_WINDOWS
11575 dir_bits = self->win32_lstat.st_file_attributes & FILE_ATTRIBUTE_DIRECTORY;
11576 if (mode_bits == S_IFDIR)
11577 result = dir_bits != 0;
11578 else
11579 result = dir_bits == 0;
11580#else /* POSIX */
11581 if (mode_bits == S_IFDIR)
11582 result = self->d_type == DT_DIR;
11583 else
11584 result = self->d_type == DT_REG;
11585#endif
11586 }
Victor Stinner35a97c02015-03-08 02:59:09 +010011587#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011588
11589 return result;
11590
11591error:
11592 Py_XDECREF(st_mode);
11593 Py_XDECREF(stat);
11594 return -1;
11595}
11596
11597static PyObject *
11598DirEntry_py_test_mode(DirEntry *self, int follow_symlinks, unsigned short mode_bits)
11599{
11600 int result;
11601
11602 result = DirEntry_test_mode(self, follow_symlinks, mode_bits);
11603 if (result == -1)
11604 return NULL;
11605 return PyBool_FromLong(result);
11606}
11607
11608static PyObject *
11609DirEntry_is_dir(DirEntry *self, PyObject *args, PyObject *kwargs)
11610{
11611 int follow_symlinks = 1;
11612
11613 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_dir",
11614 follow_symlinks_keywords, &follow_symlinks))
11615 return NULL;
11616
11617 return DirEntry_py_test_mode(self, follow_symlinks, S_IFDIR);
11618}
11619
11620static PyObject *
11621DirEntry_is_file(DirEntry *self, PyObject *args, PyObject *kwargs)
11622{
11623 int follow_symlinks = 1;
11624
11625 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|$p:DirEntry.is_file",
11626 follow_symlinks_keywords, &follow_symlinks))
11627 return NULL;
11628
11629 return DirEntry_py_test_mode(self, follow_symlinks, S_IFREG);
11630}
11631
11632static PyObject *
11633DirEntry_inode(DirEntry *self)
11634{
11635#ifdef MS_WINDOWS
11636 if (!self->got_file_index) {
11637 wchar_t *path;
11638 struct _Py_stat_struct stat;
11639
11640 path = PyUnicode_AsUnicode(self->path);
11641 if (!path)
11642 return NULL;
11643
11644 if (win32_lstat_w(path, &stat) != 0) {
11645 return PyErr_SetExcFromWindowsErrWithFilenameObject(PyExc_OSError,
11646 0, self->path);
11647 }
11648
11649 self->win32_file_index = stat.st_ino;
11650 self->got_file_index = 1;
11651 }
11652 return PyLong_FromLongLong((PY_LONG_LONG)self->win32_file_index);
11653#else /* POSIX */
11654#ifdef HAVE_LARGEFILE_SUPPORT
11655 return PyLong_FromLongLong((PY_LONG_LONG)self->d_ino);
11656#else
11657 return PyLong_FromLong((long)self->d_ino);
11658#endif
11659#endif
11660}
11661
11662static PyObject *
11663DirEntry_repr(DirEntry *self)
11664{
11665 return PyUnicode_FromFormat("<DirEntry %R>", self->name);
11666}
11667
11668static PyMemberDef DirEntry_members[] = {
11669 {"name", T_OBJECT_EX, offsetof(DirEntry, name), READONLY,
11670 "the entry's base filename, relative to scandir() \"path\" argument"},
11671 {"path", T_OBJECT_EX, offsetof(DirEntry, path), READONLY,
11672 "the entry's full path name; equivalent to os.path.join(scandir_path, entry.name)"},
11673 {NULL}
11674};
11675
11676static PyMethodDef DirEntry_methods[] = {
11677 {"is_dir", (PyCFunction)DirEntry_is_dir, METH_VARARGS | METH_KEYWORDS,
11678 "return True if the entry is a directory; cached per entry"
11679 },
11680 {"is_file", (PyCFunction)DirEntry_is_file, METH_VARARGS | METH_KEYWORDS,
11681 "return True if the entry is a file; cached per entry"
11682 },
11683 {"is_symlink", (PyCFunction)DirEntry_py_is_symlink, METH_NOARGS,
11684 "return True if the entry is a symbolic link; cached per entry"
11685 },
11686 {"stat", (PyCFunction)DirEntry_stat, METH_VARARGS | METH_KEYWORDS,
11687 "return stat_result object for the entry; cached per entry"
11688 },
11689 {"inode", (PyCFunction)DirEntry_inode, METH_NOARGS,
11690 "return inode of the entry; cached per entry",
11691 },
11692 {NULL}
11693};
11694
Benjamin Peterson5646de42015-04-12 17:56:34 -040011695static PyTypeObject DirEntryType = {
Victor Stinner6036e442015-03-08 01:58:04 +010011696 PyVarObject_HEAD_INIT(NULL, 0)
11697 MODNAME ".DirEntry", /* tp_name */
11698 sizeof(DirEntry), /* tp_basicsize */
11699 0, /* tp_itemsize */
11700 /* methods */
11701 (destructor)DirEntry_dealloc, /* tp_dealloc */
11702 0, /* tp_print */
11703 0, /* tp_getattr */
11704 0, /* tp_setattr */
11705 0, /* tp_compare */
11706 (reprfunc)DirEntry_repr, /* tp_repr */
11707 0, /* tp_as_number */
11708 0, /* tp_as_sequence */
11709 0, /* tp_as_mapping */
11710 0, /* tp_hash */
11711 0, /* tp_call */
11712 0, /* tp_str */
11713 0, /* tp_getattro */
11714 0, /* tp_setattro */
11715 0, /* tp_as_buffer */
11716 Py_TPFLAGS_DEFAULT, /* tp_flags */
11717 0, /* tp_doc */
11718 0, /* tp_traverse */
11719 0, /* tp_clear */
11720 0, /* tp_richcompare */
11721 0, /* tp_weaklistoffset */
11722 0, /* tp_iter */
11723 0, /* tp_iternext */
11724 DirEntry_methods, /* tp_methods */
11725 DirEntry_members, /* tp_members */
11726};
11727
11728#ifdef MS_WINDOWS
11729
11730static wchar_t *
11731join_path_filenameW(wchar_t *path_wide, wchar_t* filename)
11732{
11733 Py_ssize_t path_len;
11734 Py_ssize_t size;
11735 wchar_t *result;
11736 wchar_t ch;
11737
11738 if (!path_wide) { /* Default arg: "." */
11739 path_wide = L".";
11740 path_len = 1;
11741 }
11742 else {
11743 path_len = wcslen(path_wide);
11744 }
11745
11746 /* The +1's are for the path separator and the NUL */
11747 size = path_len + 1 + wcslen(filename) + 1;
11748 result = PyMem_New(wchar_t, size);
11749 if (!result) {
11750 PyErr_NoMemory();
11751 return NULL;
11752 }
11753 wcscpy(result, path_wide);
11754 if (path_len > 0) {
11755 ch = result[path_len - 1];
11756 if (ch != SEP && ch != ALTSEP && ch != L':')
11757 result[path_len++] = SEP;
11758 wcscpy(result + path_len, filename);
11759 }
11760 return result;
11761}
11762
11763static PyObject *
11764DirEntry_from_find_data(path_t *path, WIN32_FIND_DATAW *dataW)
11765{
11766 DirEntry *entry;
11767 BY_HANDLE_FILE_INFORMATION file_info;
11768 ULONG reparse_tag;
11769 wchar_t *joined_path;
11770
11771 entry = PyObject_New(DirEntry, &DirEntryType);
11772 if (!entry)
11773 return NULL;
11774 entry->name = NULL;
11775 entry->path = NULL;
11776 entry->stat = NULL;
11777 entry->lstat = NULL;
11778 entry->got_file_index = 0;
11779
11780 entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
11781 if (!entry->name)
11782 goto error;
11783
11784 joined_path = join_path_filenameW(path->wide, dataW->cFileName);
11785 if (!joined_path)
11786 goto error;
11787
11788 entry->path = PyUnicode_FromWideChar(joined_path, -1);
11789 PyMem_Free(joined_path);
11790 if (!entry->path)
11791 goto error;
11792
11793 find_data_to_file_info_w(dataW, &file_info, &reparse_tag);
11794 _Py_attribute_data_to_stat(&file_info, reparse_tag, &entry->win32_lstat);
11795
11796 return (PyObject *)entry;
11797
11798error:
11799 Py_DECREF(entry);
11800 return NULL;
11801}
11802
11803#else /* POSIX */
11804
11805static char *
11806join_path_filename(char *path_narrow, char* filename, Py_ssize_t filename_len)
11807{
11808 Py_ssize_t path_len;
11809 Py_ssize_t size;
11810 char *result;
11811
11812 if (!path_narrow) { /* Default arg: "." */
11813 path_narrow = ".";
11814 path_len = 1;
11815 }
11816 else {
11817 path_len = strlen(path_narrow);
11818 }
11819
11820 if (filename_len == -1)
11821 filename_len = strlen(filename);
11822
11823 /* The +1's are for the path separator and the NUL */
11824 size = path_len + 1 + filename_len + 1;
11825 result = PyMem_New(char, size);
11826 if (!result) {
11827 PyErr_NoMemory();
11828 return NULL;
11829 }
11830 strcpy(result, path_narrow);
11831 if (path_len > 0 && result[path_len - 1] != '/')
11832 result[path_len++] = '/';
11833 strcpy(result + path_len, filename);
11834 return result;
11835}
11836
11837static PyObject *
11838DirEntry_from_posix_info(path_t *path, char *name, Py_ssize_t name_len,
Victor Stinner35a97c02015-03-08 02:59:09 +010011839 ino_t d_ino
11840#ifdef HAVE_DIRENT_D_TYPE
11841 , unsigned char d_type
11842#endif
11843 )
Victor Stinner6036e442015-03-08 01:58:04 +010011844{
11845 DirEntry *entry;
11846 char *joined_path;
11847
11848 entry = PyObject_New(DirEntry, &DirEntryType);
11849 if (!entry)
11850 return NULL;
11851 entry->name = NULL;
11852 entry->path = NULL;
11853 entry->stat = NULL;
11854 entry->lstat = NULL;
11855
11856 joined_path = join_path_filename(path->narrow, name, name_len);
11857 if (!joined_path)
11858 goto error;
11859
11860 if (!path->narrow || !PyBytes_Check(path->object)) {
11861 entry->name = PyUnicode_DecodeFSDefaultAndSize(name, name_len);
11862 entry->path = PyUnicode_DecodeFSDefault(joined_path);
11863 }
11864 else {
11865 entry->name = PyBytes_FromStringAndSize(name, name_len);
11866 entry->path = PyBytes_FromString(joined_path);
11867 }
11868 PyMem_Free(joined_path);
11869 if (!entry->name || !entry->path)
11870 goto error;
11871
Victor Stinner35a97c02015-03-08 02:59:09 +010011872#ifdef HAVE_DIRENT_D_TYPE
Victor Stinner6036e442015-03-08 01:58:04 +010011873 entry->d_type = d_type;
Victor Stinner35a97c02015-03-08 02:59:09 +010011874#endif
Victor Stinner6036e442015-03-08 01:58:04 +010011875 entry->d_ino = d_ino;
11876
11877 return (PyObject *)entry;
11878
11879error:
11880 Py_XDECREF(entry);
11881 return NULL;
11882}
11883
11884#endif
11885
11886
11887typedef struct {
11888 PyObject_HEAD
11889 path_t path;
11890#ifdef MS_WINDOWS
11891 HANDLE handle;
11892 WIN32_FIND_DATAW file_data;
11893 int first_time;
11894#else /* POSIX */
11895 DIR *dirp;
11896#endif
11897} ScandirIterator;
11898
11899#ifdef MS_WINDOWS
11900
11901static void
11902ScandirIterator_close(ScandirIterator *iterator)
11903{
11904 if (iterator->handle == INVALID_HANDLE_VALUE)
11905 return;
11906
11907 Py_BEGIN_ALLOW_THREADS
11908 FindClose(iterator->handle);
11909 Py_END_ALLOW_THREADS
11910 iterator->handle = INVALID_HANDLE_VALUE;
11911}
11912
11913static PyObject *
11914ScandirIterator_iternext(ScandirIterator *iterator)
11915{
11916 WIN32_FIND_DATAW *file_data = &iterator->file_data;
11917 BOOL success;
11918
11919 /* Happens if the iterator is iterated twice */
11920 if (iterator->handle == INVALID_HANDLE_VALUE) {
11921 PyErr_SetNone(PyExc_StopIteration);
11922 return NULL;
11923 }
11924
11925 while (1) {
11926 if (!iterator->first_time) {
11927 Py_BEGIN_ALLOW_THREADS
11928 success = FindNextFileW(iterator->handle, file_data);
11929 Py_END_ALLOW_THREADS
11930 if (!success) {
11931 if (GetLastError() != ERROR_NO_MORE_FILES)
11932 return path_error(&iterator->path);
11933 /* No more files found in directory, stop iterating */
11934 break;
11935 }
11936 }
11937 iterator->first_time = 0;
11938
11939 /* Skip over . and .. */
11940 if (wcscmp(file_data->cFileName, L".") != 0 &&
11941 wcscmp(file_data->cFileName, L"..") != 0)
11942 return DirEntry_from_find_data(&iterator->path, file_data);
11943
11944 /* Loop till we get a non-dot directory or finish iterating */
11945 }
11946
11947 ScandirIterator_close(iterator);
11948
11949 PyErr_SetNone(PyExc_StopIteration);
11950 return NULL;
11951}
11952
11953#else /* POSIX */
11954
11955static void
11956ScandirIterator_close(ScandirIterator *iterator)
11957{
11958 if (!iterator->dirp)
11959 return;
11960
11961 Py_BEGIN_ALLOW_THREADS
11962 closedir(iterator->dirp);
11963 Py_END_ALLOW_THREADS
11964 iterator->dirp = NULL;
11965 return;
11966}
11967
11968static PyObject *
11969ScandirIterator_iternext(ScandirIterator *iterator)
11970{
11971 struct dirent *direntp;
11972 Py_ssize_t name_len;
11973 int is_dot;
Victor Stinner6036e442015-03-08 01:58:04 +010011974
11975 /* Happens if the iterator is iterated twice */
11976 if (!iterator->dirp) {
11977 PyErr_SetNone(PyExc_StopIteration);
11978 return NULL;
11979 }
11980
11981 while (1) {
11982 errno = 0;
11983 Py_BEGIN_ALLOW_THREADS
11984 direntp = readdir(iterator->dirp);
11985 Py_END_ALLOW_THREADS
11986
11987 if (!direntp) {
11988 if (errno != 0)
11989 return path_error(&iterator->path);
11990 /* No more files found in directory, stop iterating */
11991 break;
11992 }
11993
11994 /* Skip over . and .. */
11995 name_len = NAMLEN(direntp);
11996 is_dot = direntp->d_name[0] == '.' &&
11997 (name_len == 1 || (direntp->d_name[1] == '.' && name_len == 2));
11998 if (!is_dot) {
Victor Stinner6036e442015-03-08 01:58:04 +010011999 return DirEntry_from_posix_info(&iterator->path, direntp->d_name,
Victor Stinner35a97c02015-03-08 02:59:09 +010012000 name_len, direntp->d_ino
12001#ifdef HAVE_DIRENT_D_TYPE
12002 , direntp->d_type
12003#endif
12004 );
Victor Stinner6036e442015-03-08 01:58:04 +010012005 }
12006
12007 /* Loop till we get a non-dot directory or finish iterating */
12008 }
12009
12010 ScandirIterator_close(iterator);
12011
12012 PyErr_SetNone(PyExc_StopIteration);
12013 return NULL;
12014}
12015
12016#endif
12017
12018static void
12019ScandirIterator_dealloc(ScandirIterator *iterator)
12020{
12021 ScandirIterator_close(iterator);
12022 Py_XDECREF(iterator->path.object);
12023 path_cleanup(&iterator->path);
12024 Py_TYPE(iterator)->tp_free((PyObject *)iterator);
12025}
12026
Benjamin Peterson5646de42015-04-12 17:56:34 -040012027static PyTypeObject ScandirIteratorType = {
Victor Stinner6036e442015-03-08 01:58:04 +010012028 PyVarObject_HEAD_INIT(NULL, 0)
12029 MODNAME ".ScandirIterator", /* tp_name */
12030 sizeof(ScandirIterator), /* tp_basicsize */
12031 0, /* tp_itemsize */
12032 /* methods */
12033 (destructor)ScandirIterator_dealloc, /* tp_dealloc */
12034 0, /* tp_print */
12035 0, /* tp_getattr */
12036 0, /* tp_setattr */
12037 0, /* tp_compare */
12038 0, /* tp_repr */
12039 0, /* tp_as_number */
12040 0, /* tp_as_sequence */
12041 0, /* tp_as_mapping */
12042 0, /* tp_hash */
12043 0, /* tp_call */
12044 0, /* tp_str */
12045 0, /* tp_getattro */
12046 0, /* tp_setattro */
12047 0, /* tp_as_buffer */
12048 Py_TPFLAGS_DEFAULT, /* tp_flags */
12049 0, /* tp_doc */
12050 0, /* tp_traverse */
12051 0, /* tp_clear */
12052 0, /* tp_richcompare */
12053 0, /* tp_weaklistoffset */
12054 PyObject_SelfIter, /* tp_iter */
12055 (iternextfunc)ScandirIterator_iternext, /* tp_iternext */
12056};
12057
12058static PyObject *
12059posix_scandir(PyObject *self, PyObject *args, PyObject *kwargs)
12060{
12061 ScandirIterator *iterator;
12062 static char *keywords[] = {"path", NULL};
12063#ifdef MS_WINDOWS
12064 wchar_t *path_strW;
12065#else
12066 char *path;
12067#endif
12068
12069 iterator = PyObject_New(ScandirIterator, &ScandirIteratorType);
12070 if (!iterator)
12071 return NULL;
12072 memset(&iterator->path, 0, sizeof(path_t));
12073 iterator->path.function_name = "scandir";
12074 iterator->path.nullable = 1;
12075
12076#ifdef MS_WINDOWS
12077 iterator->handle = INVALID_HANDLE_VALUE;
12078#else
12079 iterator->dirp = NULL;
12080#endif
12081
12082 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|O&:scandir", keywords,
12083 path_converter, &iterator->path))
12084 goto error;
12085
12086 /* path_converter doesn't keep path.object around, so do it
12087 manually for the lifetime of the iterator here (the refcount
12088 is decremented in ScandirIterator_dealloc)
12089 */
12090 Py_XINCREF(iterator->path.object);
12091
12092#ifdef MS_WINDOWS
12093 if (iterator->path.narrow) {
12094 PyErr_SetString(PyExc_TypeError,
12095 "os.scandir() doesn't support bytes path on Windows, use Unicode instead");
12096 goto error;
12097 }
12098 iterator->first_time = 1;
12099
12100 path_strW = join_path_filenameW(iterator->path.wide, L"*.*");
12101 if (!path_strW)
12102 goto error;
12103
12104 Py_BEGIN_ALLOW_THREADS
12105 iterator->handle = FindFirstFileW(path_strW, &iterator->file_data);
12106 Py_END_ALLOW_THREADS
12107
12108 PyMem_Free(path_strW);
12109
12110 if (iterator->handle == INVALID_HANDLE_VALUE) {
12111 path_error(&iterator->path);
12112 goto error;
12113 }
12114#else /* POSIX */
12115 if (iterator->path.narrow)
12116 path = iterator->path.narrow;
12117 else
12118 path = ".";
12119
12120 errno = 0;
12121 Py_BEGIN_ALLOW_THREADS
12122 iterator->dirp = opendir(path);
12123 Py_END_ALLOW_THREADS
12124
12125 if (!iterator->dirp) {
12126 path_error(&iterator->path);
12127 goto error;
12128 }
12129#endif
12130
12131 return (PyObject *)iterator;
12132
12133error:
12134 Py_DECREF(iterator);
12135 return NULL;
12136}
12137
12138
Serhiy Storchakaa4c6bad2015-04-04 23:35:52 +030012139#include "clinic/posixmodule.c.h"
12140
Larry Hastings7726ac92014-01-31 22:03:12 -080012141/*[clinic input]
12142dump buffer
12143[clinic start generated code]*/
Serhiy Storchaka1009bf12015-04-03 23:53:51 +030012144/*[clinic end generated code: output=da39a3ee5e6b4b0d input=524ce2e021e4eba6]*/
Larry Hastings7726ac92014-01-31 22:03:12 -080012145
Larry Hastings31826802013-10-19 00:09:25 -070012146
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012147static PyMethodDef posix_methods[] = {
Larry Hastings31826802013-10-19 00:09:25 -070012148
12149 OS_STAT_METHODDEF
12150 OS_ACCESS_METHODDEF
12151 OS_TTYNAME_METHODDEF
Larry Hastings2f936352014-08-05 14:04:04 +100012152 OS_CHDIR_METHODDEF
12153 OS_CHFLAGS_METHODDEF
12154 OS_CHMOD_METHODDEF
12155 OS_FCHMOD_METHODDEF
12156 OS_LCHMOD_METHODDEF
12157 OS_CHOWN_METHODDEF
12158 OS_FCHOWN_METHODDEF
12159 OS_LCHOWN_METHODDEF
12160 OS_LCHFLAGS_METHODDEF
12161 OS_CHROOT_METHODDEF
12162 OS_CTERMID_METHODDEF
12163 OS_GETCWD_METHODDEF
12164 OS_GETCWDB_METHODDEF
12165 OS_LINK_METHODDEF
12166 OS_LISTDIR_METHODDEF
12167 OS_LSTAT_METHODDEF
12168 OS_MKDIR_METHODDEF
12169 OS_NICE_METHODDEF
12170 OS_GETPRIORITY_METHODDEF
12171 OS_SETPRIORITY_METHODDEF
Guido van Rossumb6775db1994-08-01 11:34:53 +000012172#ifdef HAVE_READLINK
Larry Hastings9cf065c2012-06-22 16:30:09 -070012173 {"readlink", (PyCFunction)posix_readlink,
12174 METH_VARARGS | METH_KEYWORDS,
12175 readlink__doc__},
Guido van Rossum6a3eb5f1994-08-18 15:42:46 +000012176#endif /* HAVE_READLINK */
Brian Curtind40e6f72010-07-08 21:39:08 +000012177#if !defined(HAVE_READLINK) && defined(MS_WINDOWS)
Larry Hastings9cf065c2012-06-22 16:30:09 -070012178 {"readlink", (PyCFunction)win_readlink,
12179 METH_VARARGS | METH_KEYWORDS,
12180 readlink__doc__},
Brian Curtind40e6f72010-07-08 21:39:08 +000012181#endif /* !defined(HAVE_READLINK) && defined(MS_WINDOWS) */
Larry Hastings2f936352014-08-05 14:04:04 +100012182 OS_RENAME_METHODDEF
12183 OS_REPLACE_METHODDEF
12184 OS_RMDIR_METHODDEF
Victor Stinner8c62be82010-05-06 00:08:46 +000012185 {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
Larry Hastings2f936352014-08-05 14:04:04 +100012186 OS_SYMLINK_METHODDEF
12187 OS_SYSTEM_METHODDEF
12188 OS_UMASK_METHODDEF
12189 OS_UNAME_METHODDEF
12190 OS_UNLINK_METHODDEF
12191 OS_REMOVE_METHODDEF
12192 OS_UTIME_METHODDEF
12193 OS_TIMES_METHODDEF
12194 OS__EXIT_METHODDEF
12195 OS_EXECV_METHODDEF
12196 OS_EXECVE_METHODDEF
12197 OS_SPAWNV_METHODDEF
12198 OS_SPAWNVE_METHODDEF
12199 OS_FORK1_METHODDEF
12200 OS_FORK_METHODDEF
12201 OS_SCHED_GET_PRIORITY_MAX_METHODDEF
12202 OS_SCHED_GET_PRIORITY_MIN_METHODDEF
12203 OS_SCHED_GETPARAM_METHODDEF
12204 OS_SCHED_GETSCHEDULER_METHODDEF
12205 OS_SCHED_RR_GET_INTERVAL_METHODDEF
12206 OS_SCHED_SETPARAM_METHODDEF
12207 OS_SCHED_SETSCHEDULER_METHODDEF
12208 OS_SCHED_YIELD_METHODDEF
12209 OS_SCHED_SETAFFINITY_METHODDEF
12210 OS_SCHED_GETAFFINITY_METHODDEF
12211 OS_OPENPTY_METHODDEF
12212 OS_FORKPTY_METHODDEF
12213 OS_GETEGID_METHODDEF
12214 OS_GETEUID_METHODDEF
12215 OS_GETGID_METHODDEF
Ross Lagerwallb0ae53d2011-06-10 07:30:30 +020012216#ifdef HAVE_GETGROUPLIST
12217 {"getgrouplist", posix_getgrouplist, METH_VARARGS, posix_getgrouplist__doc__},
12218#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012219 OS_GETGROUPS_METHODDEF
12220 OS_GETPID_METHODDEF
12221 OS_GETPGRP_METHODDEF
12222 OS_GETPPID_METHODDEF
12223 OS_GETUID_METHODDEF
12224 OS_GETLOGIN_METHODDEF
12225 OS_KILL_METHODDEF
12226 OS_KILLPG_METHODDEF
12227 OS_PLOCK_METHODDEF
Thomas Heller8b7a9572007-08-31 06:44:36 +000012228#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012229 {"startfile", win32_startfile, METH_VARARGS, win32_startfile__doc__},
Thomas Heller8b7a9572007-08-31 06:44:36 +000012230#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012231 OS_SETUID_METHODDEF
12232 OS_SETEUID_METHODDEF
12233 OS_SETREUID_METHODDEF
12234 OS_SETGID_METHODDEF
12235 OS_SETEGID_METHODDEF
12236 OS_SETREGID_METHODDEF
12237 OS_SETGROUPS_METHODDEF
Antoine Pitroub7572f02009-12-02 20:46:48 +000012238#ifdef HAVE_INITGROUPS
Victor Stinner8c62be82010-05-06 00:08:46 +000012239 {"initgroups", posix_initgroups, METH_VARARGS, posix_initgroups__doc__},
Antoine Pitroub7572f02009-12-02 20:46:48 +000012240#endif /* HAVE_INITGROUPS */
Larry Hastings2f936352014-08-05 14:04:04 +100012241 OS_GETPGID_METHODDEF
12242 OS_SETPGRP_METHODDEF
12243 OS_WAIT_METHODDEF
12244 OS_WAIT3_METHODDEF
12245 OS_WAIT4_METHODDEF
12246 OS_WAITID_METHODDEF
12247 OS_WAITPID_METHODDEF
12248 OS_GETSID_METHODDEF
12249 OS_SETSID_METHODDEF
12250 OS_SETPGID_METHODDEF
12251 OS_TCGETPGRP_METHODDEF
12252 OS_TCSETPGRP_METHODDEF
12253 OS_OPEN_METHODDEF
12254 OS_CLOSE_METHODDEF
12255 OS_CLOSERANGE_METHODDEF
12256 OS_DEVICE_ENCODING_METHODDEF
12257 OS_DUP_METHODDEF
12258 OS_DUP2_METHODDEF
12259 OS_LOCKF_METHODDEF
12260 OS_LSEEK_METHODDEF
12261 OS_READ_METHODDEF
12262 OS_READV_METHODDEF
12263 OS_PREAD_METHODDEF
12264 OS_WRITE_METHODDEF
12265 OS_WRITEV_METHODDEF
12266 OS_PWRITE_METHODDEF
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012267#ifdef HAVE_SENDFILE
12268 {"sendfile", (PyCFunction)posix_sendfile, METH_VARARGS | METH_KEYWORDS,
12269 posix_sendfile__doc__},
12270#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012271 OS_FSTAT_METHODDEF
12272 OS_ISATTY_METHODDEF
12273 OS_PIPE_METHODDEF
12274 OS_PIPE2_METHODDEF
12275 OS_MKFIFO_METHODDEF
12276 OS_MKNOD_METHODDEF
12277 OS_MAJOR_METHODDEF
12278 OS_MINOR_METHODDEF
12279 OS_MAKEDEV_METHODDEF
12280 OS_FTRUNCATE_METHODDEF
12281 OS_TRUNCATE_METHODDEF
12282 OS_POSIX_FALLOCATE_METHODDEF
12283 OS_POSIX_FADVISE_METHODDEF
12284 OS_PUTENV_METHODDEF
12285 OS_UNSETENV_METHODDEF
12286 OS_STRERROR_METHODDEF
12287 OS_FCHDIR_METHODDEF
12288 OS_FSYNC_METHODDEF
12289 OS_SYNC_METHODDEF
12290 OS_FDATASYNC_METHODDEF
12291 OS_WCOREDUMP_METHODDEF
12292 OS_WIFCONTINUED_METHODDEF
12293 OS_WIFSTOPPED_METHODDEF
12294 OS_WIFSIGNALED_METHODDEF
12295 OS_WIFEXITED_METHODDEF
12296 OS_WEXITSTATUS_METHODDEF
12297 OS_WTERMSIG_METHODDEF
12298 OS_WSTOPSIG_METHODDEF
12299 OS_FSTATVFS_METHODDEF
12300 OS_STATVFS_METHODDEF
12301 OS_CONFSTR_METHODDEF
12302 OS_SYSCONF_METHODDEF
12303 OS_FPATHCONF_METHODDEF
12304 OS_PATHCONF_METHODDEF
12305 OS_ABORT_METHODDEF
Martin v. Löwis6238d2b2002-06-30 15:26:10 +000012306#ifdef MS_WINDOWS
Victor Stinner8c62be82010-05-06 00:08:46 +000012307 {"_getfullpathname", posix__getfullpathname, METH_VARARGS, NULL},
Brian Curtin95d028f2011-06-09 09:10:38 -050012308 {"_isdir", posix__isdir, METH_VARARGS, posix__isdir__doc__},
Mark Hammondef8b6542001-05-13 08:04:26 +000012309#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012310 OS__GETDISKUSAGE_METHODDEF
12311 OS__GETFINALPATHNAME_METHODDEF
12312 OS__GETVOLUMEPATHNAME_METHODDEF
12313 OS_GETLOADAVG_METHODDEF
12314 OS_URANDOM_METHODDEF
12315 OS_SETRESUID_METHODDEF
12316 OS_SETRESGID_METHODDEF
12317 OS_GETRESUID_METHODDEF
12318 OS_GETRESGID_METHODDEF
Martin v. Löwis7aed61a2009-11-27 14:09:49 +000012319
Larry Hastings2f936352014-08-05 14:04:04 +100012320 OS_GETXATTR_METHODDEF
12321 OS_SETXATTR_METHODDEF
12322 OS_REMOVEXATTR_METHODDEF
12323 OS_LISTXATTR_METHODDEF
12324
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012325#if defined(TERMSIZE_USE_CONIO) || defined(TERMSIZE_USE_IOCTL)
12326 {"get_terminal_size", get_terminal_size, METH_VARARGS, termsize__doc__},
12327#endif
Larry Hastings2f936352014-08-05 14:04:04 +100012328 OS_CPU_COUNT_METHODDEF
12329 OS_GET_INHERITABLE_METHODDEF
12330 OS_SET_INHERITABLE_METHODDEF
12331 OS_GET_HANDLE_INHERITABLE_METHODDEF
12332 OS_SET_HANDLE_INHERITABLE_METHODDEF
Victor Stinner1db9e7b2014-07-29 22:32:47 +020012333#ifndef MS_WINDOWS
12334 {"get_blocking", posix_get_blocking, METH_VARARGS, get_blocking__doc__},
12335 {"set_blocking", posix_set_blocking, METH_VARARGS, set_blocking__doc__},
12336#endif
Victor Stinner6036e442015-03-08 01:58:04 +010012337 {"scandir", (PyCFunction)posix_scandir,
12338 METH_VARARGS | METH_KEYWORDS,
12339 posix_scandir__doc__},
Victor Stinner8c62be82010-05-06 00:08:46 +000012340 {NULL, NULL} /* Sentinel */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000012341};
12342
12343
Brian Curtin52173d42010-12-02 18:29:18 +000012344#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012345static int
Brian Curtin52173d42010-12-02 18:29:18 +000012346enable_symlink()
12347{
12348 HANDLE tok;
12349 TOKEN_PRIVILEGES tok_priv;
12350 LUID luid;
12351 int meth_idx = 0;
12352
12353 if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &tok))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012354 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012355
12356 if (!LookupPrivilegeValue(NULL, SE_CREATE_SYMBOLIC_LINK_NAME, &luid))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012357 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012358
12359 tok_priv.PrivilegeCount = 1;
12360 tok_priv.Privileges[0].Luid = luid;
12361 tok_priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
12362
12363 if (!AdjustTokenPrivileges(tok, FALSE, &tok_priv,
12364 sizeof(TOKEN_PRIVILEGES),
12365 (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL))
Brian Curtin3b4499c2010-12-28 14:31:47 +000012366 return 0;
Brian Curtin52173d42010-12-02 18:29:18 +000012367
Brian Curtin3b4499c2010-12-28 14:31:47 +000012368 /* ERROR_NOT_ALL_ASSIGNED returned when the privilege can't be assigned. */
12369 return GetLastError() == ERROR_NOT_ALL_ASSIGNED ? 0 : 1;
Brian Curtin52173d42010-12-02 18:29:18 +000012370}
12371#endif /* defined(HAVE_SYMLINK) && defined(MS_WINDOWS) */
12372
Barry Warsaw4a342091996-12-19 23:50:02 +000012373static int
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012374all_ins(PyObject *m)
Barry Warsaw4a342091996-12-19 23:50:02 +000012375{
Guido van Rossum94f6f721999-01-06 18:42:14 +000012376#ifdef F_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012377 if (PyModule_AddIntMacro(m, F_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012378#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012379#ifdef R_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012380 if (PyModule_AddIntMacro(m, R_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012381#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012382#ifdef W_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012383 if (PyModule_AddIntMacro(m, W_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012384#endif
Guido van Rossum94f6f721999-01-06 18:42:14 +000012385#ifdef X_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012386 if (PyModule_AddIntMacro(m, X_OK)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012387#endif
Fred Drakec9680921999-12-13 16:37:25 +000012388#ifdef NGROUPS_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012389 if (PyModule_AddIntMacro(m, NGROUPS_MAX)) return -1;
Fred Drakec9680921999-12-13 16:37:25 +000012390#endif
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012391#ifdef TMP_MAX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012392 if (PyModule_AddIntMacro(m, TMP_MAX)) return -1;
Fred Drake5ab8eaf1999-12-09 21:13:07 +000012393#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012394#ifdef WCONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012395 if (PyModule_AddIntMacro(m, WCONTINUED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012396#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012397#ifdef WNOHANG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012398 if (PyModule_AddIntMacro(m, WNOHANG)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012399#endif
Fred Drake106c1a02002-04-23 15:58:02 +000012400#ifdef WUNTRACED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012401 if (PyModule_AddIntMacro(m, WUNTRACED)) return -1;
Fred Drake106c1a02002-04-23 15:58:02 +000012402#endif
Barry Warsaw4a342091996-12-19 23:50:02 +000012403#ifdef O_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012404 if (PyModule_AddIntMacro(m, O_RDONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012405#endif
12406#ifdef O_WRONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012407 if (PyModule_AddIntMacro(m, O_WRONLY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012408#endif
12409#ifdef O_RDWR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012410 if (PyModule_AddIntMacro(m, O_RDWR)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012411#endif
12412#ifdef O_NDELAY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012413 if (PyModule_AddIntMacro(m, O_NDELAY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012414#endif
12415#ifdef O_NONBLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012416 if (PyModule_AddIntMacro(m, O_NONBLOCK)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012417#endif
12418#ifdef O_APPEND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012419 if (PyModule_AddIntMacro(m, O_APPEND)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012420#endif
12421#ifdef O_DSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012422 if (PyModule_AddIntMacro(m, O_DSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012423#endif
12424#ifdef O_RSYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012425 if (PyModule_AddIntMacro(m, O_RSYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012426#endif
12427#ifdef O_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012428 if (PyModule_AddIntMacro(m, O_SYNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012429#endif
12430#ifdef O_NOCTTY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012431 if (PyModule_AddIntMacro(m, O_NOCTTY)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012432#endif
12433#ifdef O_CREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012434 if (PyModule_AddIntMacro(m, O_CREAT)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012435#endif
12436#ifdef O_EXCL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012437 if (PyModule_AddIntMacro(m, O_EXCL)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012438#endif
12439#ifdef O_TRUNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012440 if (PyModule_AddIntMacro(m, O_TRUNC)) return -1;
Barry Warsaw4a342091996-12-19 23:50:02 +000012441#endif
Guido van Rossum98d9d091997-08-08 21:48:51 +000012442#ifdef O_BINARY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012443 if (PyModule_AddIntMacro(m, O_BINARY)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012444#endif
12445#ifdef O_TEXT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012446 if (PyModule_AddIntMacro(m, O_TEXT)) return -1;
Guido van Rossum98d9d091997-08-08 21:48:51 +000012447#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012448#ifdef O_XATTR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012449 if (PyModule_AddIntMacro(m, O_XATTR)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012450#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012451#ifdef O_LARGEFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012452 if (PyModule_AddIntMacro(m, O_LARGEFILE)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012453#endif
Skip Montanaro5ff14922005-05-16 02:42:22 +000012454#ifdef O_SHLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012455 if (PyModule_AddIntMacro(m, O_SHLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012456#endif
12457#ifdef O_EXLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012458 if (PyModule_AddIntMacro(m, O_EXLOCK)) return -1;
Skip Montanaro5ff14922005-05-16 02:42:22 +000012459#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012460#ifdef O_EXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012461 if (PyModule_AddIntMacro(m, O_EXEC)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012462#endif
12463#ifdef O_SEARCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012464 if (PyModule_AddIntMacro(m, O_SEARCH)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012465#endif
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012466#ifdef O_PATH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012467 if (PyModule_AddIntMacro(m, O_PATH)) return -1;
Benjamin Peterson3b965a22013-03-13 10:27:41 -050012468#endif
Jesus Ceacf381202012-04-24 20:44:40 +020012469#ifdef O_TTY_INIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012470 if (PyModule_AddIntMacro(m, O_TTY_INIT)) return -1;
Jesus Ceacf381202012-04-24 20:44:40 +020012471#endif
Christian Heimes177b3f92013-08-16 14:35:09 +020012472#ifdef O_TMPFILE
12473 if (PyModule_AddIntMacro(m, O_TMPFILE)) return -1;
12474#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012475#ifdef PRIO_PROCESS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012476 if (PyModule_AddIntMacro(m, PRIO_PROCESS)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012477#endif
12478#ifdef PRIO_PGRP
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012479 if (PyModule_AddIntMacro(m, PRIO_PGRP)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012480#endif
12481#ifdef PRIO_USER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012482 if (PyModule_AddIntMacro(m, PRIO_USER)) return -1;
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012483#endif
Charles-François Natali1e045b12011-05-22 20:42:32 +020012484#ifdef O_CLOEXEC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012485 if (PyModule_AddIntMacro(m, O_CLOEXEC)) return -1;
Charles-François Natali1e045b12011-05-22 20:42:32 +020012486#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012487#ifdef O_ACCMODE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012488 if (PyModule_AddIntMacro(m, O_ACCMODE)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012489#endif
Giampaolo Rodolà18e8bcb2011-02-25 20:57:54 +000012490
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012491
Jesus Cea94363612012-06-22 18:32:07 +020012492#ifdef SEEK_HOLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012493 if (PyModule_AddIntMacro(m, SEEK_HOLE)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012494#endif
12495#ifdef SEEK_DATA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012496 if (PyModule_AddIntMacro(m, SEEK_DATA)) return -1;
Jesus Cea94363612012-06-22 18:32:07 +020012497#endif
12498
Tim Peters5aa91602002-01-30 05:46:57 +000012499/* MS Windows */
12500#ifdef O_NOINHERIT
Victor Stinner8c62be82010-05-06 00:08:46 +000012501 /* Don't inherit in child processes. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012502 if (PyModule_AddIntMacro(m, O_NOINHERIT)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012503#endif
12504#ifdef _O_SHORT_LIVED
Victor Stinner8c62be82010-05-06 00:08:46 +000012505 /* Optimize for short life (keep in memory). */
12506 /* MS forgot to define this one with a non-underscore form too. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012507 if (PyModule_AddIntConstant(m, "O_SHORT_LIVED", _O_SHORT_LIVED)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012508#endif
12509#ifdef O_TEMPORARY
Victor Stinner8c62be82010-05-06 00:08:46 +000012510 /* Automatically delete when last handle is closed. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012511 if (PyModule_AddIntMacro(m, O_TEMPORARY)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012512#endif
12513#ifdef O_RANDOM
Victor Stinner8c62be82010-05-06 00:08:46 +000012514 /* Optimize for random access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012515 if (PyModule_AddIntMacro(m, O_RANDOM)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012516#endif
12517#ifdef O_SEQUENTIAL
Victor Stinner8c62be82010-05-06 00:08:46 +000012518 /* Optimize for sequential access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012519 if (PyModule_AddIntMacro(m, O_SEQUENTIAL)) return -1;
Tim Peters5aa91602002-01-30 05:46:57 +000012520#endif
12521
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012522/* GNU extensions. */
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012523#ifdef O_ASYNC
Victor Stinner8c62be82010-05-06 00:08:46 +000012524 /* Send a SIGIO signal whenever input or output
12525 becomes available on file descriptor */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012526 if (PyModule_AddIntMacro(m, O_ASYNC)) return -1;
Alexandre Vassalottibee32532008-05-16 18:15:12 +000012527#endif
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012528#ifdef O_DIRECT
Victor Stinner8c62be82010-05-06 00:08:46 +000012529 /* Direct disk access. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012530 if (PyModule_AddIntMacro(m, O_DIRECT)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012531#endif
12532#ifdef O_DIRECTORY
Victor Stinner8c62be82010-05-06 00:08:46 +000012533 /* Must be a directory. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012534 if (PyModule_AddIntMacro(m, O_DIRECTORY)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012535#endif
12536#ifdef O_NOFOLLOW
Victor Stinner8c62be82010-05-06 00:08:46 +000012537 /* Do not follow links. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012538 if (PyModule_AddIntMacro(m, O_NOFOLLOW)) return -1;
Martin v. Löwis4fe3c272001-10-18 22:05:36 +000012539#endif
Jesus Cea1d642d22012-04-24 20:59:17 +020012540#ifdef O_NOLINKS
12541 /* Fails if link count of the named file is greater than 1 */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012542 if (PyModule_AddIntMacro(m, O_NOLINKS)) return -1;
Jesus Cea1d642d22012-04-24 20:59:17 +020012543#endif
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012544#ifdef O_NOATIME
Victor Stinner8c62be82010-05-06 00:08:46 +000012545 /* Do not update the access time. */
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012546 if (PyModule_AddIntMacro(m, O_NOATIME)) return -1;
Guido van Rossum0d3fb8a2007-11-26 23:23:18 +000012547#endif
Guido van Rossumd48f2521997-12-05 22:19:34 +000012548
Victor Stinner8c62be82010-05-06 00:08:46 +000012549 /* These come from sysexits.h */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012550#ifdef EX_OK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012551 if (PyModule_AddIntMacro(m, EX_OK)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012552#endif /* EX_OK */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012553#ifdef EX_USAGE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012554 if (PyModule_AddIntMacro(m, EX_USAGE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012555#endif /* EX_USAGE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012556#ifdef EX_DATAERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012557 if (PyModule_AddIntMacro(m, EX_DATAERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012558#endif /* EX_DATAERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012559#ifdef EX_NOINPUT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012560 if (PyModule_AddIntMacro(m, EX_NOINPUT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012561#endif /* EX_NOINPUT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012562#ifdef EX_NOUSER
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012563 if (PyModule_AddIntMacro(m, EX_NOUSER)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012564#endif /* EX_NOUSER */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012565#ifdef EX_NOHOST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012566 if (PyModule_AddIntMacro(m, EX_NOHOST)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012567#endif /* EX_NOHOST */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012568#ifdef EX_UNAVAILABLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012569 if (PyModule_AddIntMacro(m, EX_UNAVAILABLE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012570#endif /* EX_UNAVAILABLE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012571#ifdef EX_SOFTWARE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012572 if (PyModule_AddIntMacro(m, EX_SOFTWARE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012573#endif /* EX_SOFTWARE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012574#ifdef EX_OSERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012575 if (PyModule_AddIntMacro(m, EX_OSERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012576#endif /* EX_OSERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012577#ifdef EX_OSFILE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012578 if (PyModule_AddIntMacro(m, EX_OSFILE)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012579#endif /* EX_OSFILE */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012580#ifdef EX_CANTCREAT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012581 if (PyModule_AddIntMacro(m, EX_CANTCREAT)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012582#endif /* EX_CANTCREAT */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012583#ifdef EX_IOERR
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012584 if (PyModule_AddIntMacro(m, EX_IOERR)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012585#endif /* EX_IOERR */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012586#ifdef EX_TEMPFAIL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012587 if (PyModule_AddIntMacro(m, EX_TEMPFAIL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012588#endif /* EX_TEMPFAIL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012589#ifdef EX_PROTOCOL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012590 if (PyModule_AddIntMacro(m, EX_PROTOCOL)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012591#endif /* EX_PROTOCOL */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012592#ifdef EX_NOPERM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012593 if (PyModule_AddIntMacro(m, EX_NOPERM)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012594#endif /* EX_NOPERM */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012595#ifdef EX_CONFIG
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012596 if (PyModule_AddIntMacro(m, EX_CONFIG)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012597#endif /* EX_CONFIG */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012598#ifdef EX_NOTFOUND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012599 if (PyModule_AddIntMacro(m, EX_NOTFOUND)) return -1;
Neal Norwitz8e914d92003-01-10 15:29:16 +000012600#endif /* EX_NOTFOUND */
Barry Warsaw5676bd12003-01-07 20:57:09 +000012601
Amaury Forgeot d'Arc66d00ad2010-09-10 18:11:45 +000012602 /* statvfs */
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012603#ifdef ST_RDONLY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012604 if (PyModule_AddIntMacro(m, ST_RDONLY)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012605#endif /* ST_RDONLY */
12606#ifdef ST_NOSUID
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012607 if (PyModule_AddIntMacro(m, ST_NOSUID)) return -1;
Andrew M. Kuchling4ea04a32010-08-18 22:30:34 +000012608#endif /* ST_NOSUID */
12609
doko@ubuntu.comca616a22013-12-08 15:23:07 +010012610 /* GNU extensions */
12611#ifdef ST_NODEV
12612 if (PyModule_AddIntMacro(m, ST_NODEV)) return -1;
12613#endif /* ST_NODEV */
12614#ifdef ST_NOEXEC
12615 if (PyModule_AddIntMacro(m, ST_NOEXEC)) return -1;
12616#endif /* ST_NOEXEC */
12617#ifdef ST_SYNCHRONOUS
12618 if (PyModule_AddIntMacro(m, ST_SYNCHRONOUS)) return -1;
12619#endif /* ST_SYNCHRONOUS */
12620#ifdef ST_MANDLOCK
12621 if (PyModule_AddIntMacro(m, ST_MANDLOCK)) return -1;
12622#endif /* ST_MANDLOCK */
12623#ifdef ST_WRITE
12624 if (PyModule_AddIntMacro(m, ST_WRITE)) return -1;
12625#endif /* ST_WRITE */
12626#ifdef ST_APPEND
12627 if (PyModule_AddIntMacro(m, ST_APPEND)) return -1;
12628#endif /* ST_APPEND */
12629#ifdef ST_NOATIME
12630 if (PyModule_AddIntMacro(m, ST_NOATIME)) return -1;
12631#endif /* ST_NOATIME */
12632#ifdef ST_NODIRATIME
12633 if (PyModule_AddIntMacro(m, ST_NODIRATIME)) return -1;
12634#endif /* ST_NODIRATIME */
12635#ifdef ST_RELATIME
12636 if (PyModule_AddIntMacro(m, ST_RELATIME)) return -1;
12637#endif /* ST_RELATIME */
12638
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012639 /* FreeBSD sendfile() constants */
12640#ifdef SF_NODISKIO
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012641 if (PyModule_AddIntMacro(m, SF_NODISKIO)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012642#endif
12643#ifdef SF_MNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012644 if (PyModule_AddIntMacro(m, SF_MNOWAIT)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012645#endif
12646#ifdef SF_SYNC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012647 if (PyModule_AddIntMacro(m, SF_SYNC)) return -1;
Giampaolo Rodolàc9c2c8b2011-02-25 14:39:16 +000012648#endif
12649
Ross Lagerwall7807c352011-03-17 20:20:30 +020012650 /* constants for posix_fadvise */
12651#ifdef POSIX_FADV_NORMAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012652 if (PyModule_AddIntMacro(m, POSIX_FADV_NORMAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012653#endif
12654#ifdef POSIX_FADV_SEQUENTIAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012655 if (PyModule_AddIntMacro(m, POSIX_FADV_SEQUENTIAL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012656#endif
12657#ifdef POSIX_FADV_RANDOM
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012658 if (PyModule_AddIntMacro(m, POSIX_FADV_RANDOM)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012659#endif
12660#ifdef POSIX_FADV_NOREUSE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012661 if (PyModule_AddIntMacro(m, POSIX_FADV_NOREUSE)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012662#endif
12663#ifdef POSIX_FADV_WILLNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012664 if (PyModule_AddIntMacro(m, POSIX_FADV_WILLNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012665#endif
12666#ifdef POSIX_FADV_DONTNEED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012667 if (PyModule_AddIntMacro(m, POSIX_FADV_DONTNEED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012668#endif
12669
12670 /* constants for waitid */
12671#if defined(HAVE_SYS_WAIT_H) && defined(HAVE_WAITID)
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012672 if (PyModule_AddIntMacro(m, P_PID)) return -1;
12673 if (PyModule_AddIntMacro(m, P_PGID)) return -1;
12674 if (PyModule_AddIntMacro(m, P_ALL)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012675#endif
12676#ifdef WEXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012677 if (PyModule_AddIntMacro(m, WEXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012678#endif
12679#ifdef WNOWAIT
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012680 if (PyModule_AddIntMacro(m, WNOWAIT)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012681#endif
12682#ifdef WSTOPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012683 if (PyModule_AddIntMacro(m, WSTOPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012684#endif
12685#ifdef CLD_EXITED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012686 if (PyModule_AddIntMacro(m, CLD_EXITED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012687#endif
12688#ifdef CLD_DUMPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012689 if (PyModule_AddIntMacro(m, CLD_DUMPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012690#endif
12691#ifdef CLD_TRAPPED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012692 if (PyModule_AddIntMacro(m, CLD_TRAPPED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012693#endif
12694#ifdef CLD_CONTINUED
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012695 if (PyModule_AddIntMacro(m, CLD_CONTINUED)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012696#endif
12697
12698 /* constants for lockf */
12699#ifdef F_LOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012700 if (PyModule_AddIntMacro(m, F_LOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012701#endif
12702#ifdef F_TLOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012703 if (PyModule_AddIntMacro(m, F_TLOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012704#endif
12705#ifdef F_ULOCK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012706 if (PyModule_AddIntMacro(m, F_ULOCK)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012707#endif
12708#ifdef F_TEST
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012709 if (PyModule_AddIntMacro(m, F_TEST)) return -1;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012710#endif
12711
Guido van Rossum246bc171999-02-01 23:54:31 +000012712#ifdef HAVE_SPAWNV
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012713 if (PyModule_AddIntConstant(m, "P_WAIT", _P_WAIT)) return -1;
12714 if (PyModule_AddIntConstant(m, "P_NOWAIT", _P_NOWAIT)) return -1;
12715 if (PyModule_AddIntConstant(m, "P_OVERLAY", _OLD_P_OVERLAY)) return -1;
12716 if (PyModule_AddIntConstant(m, "P_NOWAITO", _P_NOWAITO)) return -1;
12717 if (PyModule_AddIntConstant(m, "P_DETACH", _P_DETACH)) return -1;
Guido van Rossum246bc171999-02-01 23:54:31 +000012718#endif
12719
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012720#ifdef HAVE_SCHED_H
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012721 if (PyModule_AddIntMacro(m, SCHED_OTHER)) return -1;
12722 if (PyModule_AddIntMacro(m, SCHED_FIFO)) return -1;
12723 if (PyModule_AddIntMacro(m, SCHED_RR)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012724#ifdef SCHED_SPORADIC
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012725 if (PyModule_AddIntMacro(m, SCHED_SPORADIC) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012726#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012727#ifdef SCHED_BATCH
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012728 if (PyModule_AddIntMacro(m, SCHED_BATCH)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012729#endif
12730#ifdef SCHED_IDLE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012731 if (PyModule_AddIntMacro(m, SCHED_IDLE)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012732#endif
12733#ifdef SCHED_RESET_ON_FORK
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012734 if (PyModule_AddIntMacro(m, SCHED_RESET_ON_FORK)) return -1;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012735#endif
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012736#ifdef SCHED_SYS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012737 if (PyModule_AddIntMacro(m, SCHED_SYS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012738#endif
12739#ifdef SCHED_IA
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012740 if (PyModule_AddIntMacro(m, SCHED_IA)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012741#endif
12742#ifdef SCHED_FSS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012743 if (PyModule_AddIntMacro(m, SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012744#endif
12745#ifdef SCHED_FX
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012746 if (PyModule_AddIntConstant(m, "SCHED_FX", SCHED_FSS)) return -1;
Jesus Ceaf2cb4e82011-09-09 23:55:42 +020012747#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012748#endif
12749
Benjamin Peterson9428d532011-09-14 11:45:52 -040012750#ifdef USE_XATTRS
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012751 if (PyModule_AddIntMacro(m, XATTR_CREATE)) return -1;
12752 if (PyModule_AddIntMacro(m, XATTR_REPLACE)) return -1;
12753 if (PyModule_AddIntMacro(m, XATTR_SIZE_MAX)) return -1;
Benjamin Peterson799bd802011-08-31 22:15:17 -040012754#endif
12755
Victor Stinner8b905bd2011-10-25 13:34:04 +020012756#ifdef RTLD_LAZY
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012757 if (PyModule_AddIntMacro(m, RTLD_LAZY)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012758#endif
12759#ifdef RTLD_NOW
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012760 if (PyModule_AddIntMacro(m, RTLD_NOW)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012761#endif
12762#ifdef RTLD_GLOBAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012763 if (PyModule_AddIntMacro(m, RTLD_GLOBAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012764#endif
12765#ifdef RTLD_LOCAL
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012766 if (PyModule_AddIntMacro(m, RTLD_LOCAL)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012767#endif
12768#ifdef RTLD_NODELETE
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012769 if (PyModule_AddIntMacro(m, RTLD_NODELETE)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012770#endif
12771#ifdef RTLD_NOLOAD
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012772 if (PyModule_AddIntMacro(m, RTLD_NOLOAD)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012773#endif
12774#ifdef RTLD_DEEPBIND
Charles-Francois Natali74ca8862013-05-20 19:13:19 +020012775 if (PyModule_AddIntMacro(m, RTLD_DEEPBIND)) return -1;
Victor Stinner8b905bd2011-10-25 13:34:04 +020012776#endif
12777
Victor Stinner8c62be82010-05-06 00:08:46 +000012778 return 0;
Barry Warsaw4a342091996-12-19 23:50:02 +000012779}
12780
12781
Martin v. Löwis1a214512008-06-11 05:26:20 +000012782static struct PyModuleDef posixmodule = {
Victor Stinner8c62be82010-05-06 00:08:46 +000012783 PyModuleDef_HEAD_INIT,
12784 MODNAME,
12785 posix__doc__,
12786 -1,
12787 posix_methods,
12788 NULL,
12789 NULL,
12790 NULL,
12791 NULL
Martin v. Löwis1a214512008-06-11 05:26:20 +000012792};
12793
12794
Larry Hastings9cf065c2012-06-22 16:30:09 -070012795static char *have_functions[] = {
12796
12797#ifdef HAVE_FACCESSAT
12798 "HAVE_FACCESSAT",
12799#endif
12800
12801#ifdef HAVE_FCHDIR
12802 "HAVE_FCHDIR",
12803#endif
12804
12805#ifdef HAVE_FCHMOD
12806 "HAVE_FCHMOD",
12807#endif
12808
12809#ifdef HAVE_FCHMODAT
12810 "HAVE_FCHMODAT",
12811#endif
12812
12813#ifdef HAVE_FCHOWN
12814 "HAVE_FCHOWN",
12815#endif
12816
Larry Hastings00964ed2013-08-12 13:49:30 -040012817#ifdef HAVE_FCHOWNAT
12818 "HAVE_FCHOWNAT",
12819#endif
12820
Larry Hastings9cf065c2012-06-22 16:30:09 -070012821#ifdef HAVE_FEXECVE
12822 "HAVE_FEXECVE",
12823#endif
12824
12825#ifdef HAVE_FDOPENDIR
12826 "HAVE_FDOPENDIR",
12827#endif
12828
Georg Brandl306336b2012-06-24 12:55:33 +020012829#ifdef HAVE_FPATHCONF
12830 "HAVE_FPATHCONF",
12831#endif
12832
Larry Hastings9cf065c2012-06-22 16:30:09 -070012833#ifdef HAVE_FSTATAT
12834 "HAVE_FSTATAT",
12835#endif
12836
12837#ifdef HAVE_FSTATVFS
12838 "HAVE_FSTATVFS",
12839#endif
12840
Steve Dowerfe0a41a2015-03-20 19:50:46 -070012841#if defined HAVE_FTRUNCATE || defined MS_WINDOWS
Georg Brandl306336b2012-06-24 12:55:33 +020012842 "HAVE_FTRUNCATE",
12843#endif
12844
Larry Hastings9cf065c2012-06-22 16:30:09 -070012845#ifdef HAVE_FUTIMENS
12846 "HAVE_FUTIMENS",
12847#endif
12848
12849#ifdef HAVE_FUTIMES
12850 "HAVE_FUTIMES",
12851#endif
12852
12853#ifdef HAVE_FUTIMESAT
12854 "HAVE_FUTIMESAT",
12855#endif
12856
12857#ifdef HAVE_LINKAT
12858 "HAVE_LINKAT",
12859#endif
12860
12861#ifdef HAVE_LCHFLAGS
12862 "HAVE_LCHFLAGS",
12863#endif
12864
12865#ifdef HAVE_LCHMOD
12866 "HAVE_LCHMOD",
12867#endif
12868
12869#ifdef HAVE_LCHOWN
12870 "HAVE_LCHOWN",
12871#endif
12872
12873#ifdef HAVE_LSTAT
12874 "HAVE_LSTAT",
12875#endif
12876
12877#ifdef HAVE_LUTIMES
12878 "HAVE_LUTIMES",
12879#endif
12880
12881#ifdef HAVE_MKDIRAT
12882 "HAVE_MKDIRAT",
12883#endif
12884
12885#ifdef HAVE_MKFIFOAT
12886 "HAVE_MKFIFOAT",
12887#endif
12888
12889#ifdef HAVE_MKNODAT
12890 "HAVE_MKNODAT",
12891#endif
12892
12893#ifdef HAVE_OPENAT
12894 "HAVE_OPENAT",
12895#endif
12896
12897#ifdef HAVE_READLINKAT
12898 "HAVE_READLINKAT",
12899#endif
12900
12901#ifdef HAVE_RENAMEAT
12902 "HAVE_RENAMEAT",
12903#endif
12904
12905#ifdef HAVE_SYMLINKAT
12906 "HAVE_SYMLINKAT",
12907#endif
12908
12909#ifdef HAVE_UNLINKAT
12910 "HAVE_UNLINKAT",
12911#endif
12912
12913#ifdef HAVE_UTIMENSAT
12914 "HAVE_UTIMENSAT",
12915#endif
12916
12917#ifdef MS_WINDOWS
12918 "MS_WINDOWS",
12919#endif
12920
12921 NULL
12922};
12923
12924
Mark Hammondfe51c6d2002-08-02 02:27:13 +000012925PyMODINIT_FUNC
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000012926INITFUNC(void)
Guido van Rossumb6775db1994-08-01 11:34:53 +000012927{
Victor Stinner8c62be82010-05-06 00:08:46 +000012928 PyObject *m, *v;
Larry Hastings9cf065c2012-06-22 16:30:09 -070012929 PyObject *list;
12930 char **trace;
Tim Peters5aa91602002-01-30 05:46:57 +000012931
Brian Curtin52173d42010-12-02 18:29:18 +000012932#if defined(HAVE_SYMLINK) && defined(MS_WINDOWS)
Brian Curtin3b4499c2010-12-28 14:31:47 +000012933 win32_can_symlink = enable_symlink();
Brian Curtin52173d42010-12-02 18:29:18 +000012934#endif
12935
Victor Stinner8c62be82010-05-06 00:08:46 +000012936 m = PyModule_Create(&posixmodule);
12937 if (m == NULL)
12938 return NULL;
Tim Peters5aa91602002-01-30 05:46:57 +000012939
Victor Stinner8c62be82010-05-06 00:08:46 +000012940 /* Initialize environ dictionary */
12941 v = convertenviron();
12942 Py_XINCREF(v);
12943 if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
12944 return NULL;
12945 Py_DECREF(v);
Fred Drakec9680921999-12-13 16:37:25 +000012946
Victor Stinner8c62be82010-05-06 00:08:46 +000012947 if (all_ins(m))
12948 return NULL;
Barry Warsaw4a342091996-12-19 23:50:02 +000012949
Victor Stinner8c62be82010-05-06 00:08:46 +000012950 if (setup_confname_tables(m))
12951 return NULL;
Fred Drakebec628d1999-12-15 18:31:10 +000012952
Victor Stinner8c62be82010-05-06 00:08:46 +000012953 Py_INCREF(PyExc_OSError);
12954 PyModule_AddObject(m, "error", PyExc_OSError);
Fred Drake762e2061999-08-26 17:23:54 +000012955
Guido van Rossumb3d39562000-01-31 18:41:26 +000012956#ifdef HAVE_PUTENV
Victor Stinner8c62be82010-05-06 00:08:46 +000012957 if (posix_putenv_garbage == NULL)
12958 posix_putenv_garbage = PyDict_New();
Guido van Rossumb3d39562000-01-31 18:41:26 +000012959#endif
Guido van Rossum98bf58f2001-10-18 20:34:25 +000012960
Victor Stinner8c62be82010-05-06 00:08:46 +000012961 if (!initialized) {
Ross Lagerwall7807c352011-03-17 20:20:30 +020012962#if defined(HAVE_WAITID) && !defined(__APPLE__)
12963 waitid_result_desc.name = MODNAME ".waitid_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012964 if (PyStructSequence_InitType2(&WaitidResultType, &waitid_result_desc) < 0)
12965 return NULL;
Ross Lagerwall7807c352011-03-17 20:20:30 +020012966#endif
12967
Christian Heimes25827622013-10-12 01:27:08 +020012968 stat_result_desc.name = "os.stat_result"; /* see issue #19209 */
Victor Stinner8c62be82010-05-06 00:08:46 +000012969 stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
12970 stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
12971 stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
Victor Stinner1c8f0592013-07-22 22:24:54 +020012972 if (PyStructSequence_InitType2(&StatResultType, &stat_result_desc) < 0)
12973 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000012974 structseq_new = StatResultType.tp_new;
12975 StatResultType.tp_new = statresult_new;
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000012976
Christian Heimes25827622013-10-12 01:27:08 +020012977 statvfs_result_desc.name = "os.statvfs_result"; /* see issue #19209 */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012978 if (PyStructSequence_InitType2(&StatVFSResultType,
12979 &statvfs_result_desc) < 0)
12980 return NULL;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012981#ifdef NEED_TICKS_PER_SECOND
12982# if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
Victor Stinner8c62be82010-05-06 00:08:46 +000012983 ticks_per_second = sysconf(_SC_CLK_TCK);
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012984# elif defined(HZ)
Victor Stinner8c62be82010-05-06 00:08:46 +000012985 ticks_per_second = HZ;
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012986# else
Victor Stinner8c62be82010-05-06 00:08:46 +000012987 ticks_per_second = 60; /* magic fallback value; may be bogus */
Martin v. Löwis05bfe1f2008-12-29 18:21:47 +000012988# endif
12989#endif
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012990
Benjamin Peterson0163c9a2011-08-02 18:11:38 -050012991#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012992 sched_param_desc.name = MODNAME ".sched_param";
Victor Stinner1c8f0592013-07-22 22:24:54 +020012993 if (PyStructSequence_InitType2(&SchedParamType, &sched_param_desc) < 0)
12994 return NULL;
Larry Hastings2f936352014-08-05 14:04:04 +100012995 SchedParamType.tp_new = os_sched_param;
Benjamin Peterson94b580d2011-08-02 17:30:04 -050012996#endif
Antoine Pitroubcf2b592012-02-08 23:28:36 +010012997
12998 /* initialize TerminalSize_info */
Victor Stinner1c8f0592013-07-22 22:24:54 +020012999 if (PyStructSequence_InitType2(&TerminalSizeType,
13000 &TerminalSize_desc) < 0)
13001 return NULL;
Victor Stinner6036e442015-03-08 01:58:04 +010013002
13003 /* initialize scandir types */
13004 if (PyType_Ready(&ScandirIteratorType) < 0)
13005 return NULL;
13006 if (PyType_Ready(&DirEntryType) < 0)
13007 return NULL;
Victor Stinner8c62be82010-05-06 00:08:46 +000013008 }
Ross Lagerwall7807c352011-03-17 20:20:30 +020013009#if defined(HAVE_WAITID) && !defined(__APPLE__)
13010 Py_INCREF((PyObject*) &WaitidResultType);
13011 PyModule_AddObject(m, "waitid_result", (PyObject*) &WaitidResultType);
13012#endif
Victor Stinner8c62be82010-05-06 00:08:46 +000013013 Py_INCREF((PyObject*) &StatResultType);
13014 PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
13015 Py_INCREF((PyObject*) &StatVFSResultType);
13016 PyModule_AddObject(m, "statvfs_result",
13017 (PyObject*) &StatVFSResultType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013018
13019#if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER)
Benjamin Peterson94b580d2011-08-02 17:30:04 -050013020 Py_INCREF(&SchedParamType);
13021 PyModule_AddObject(m, "sched_param", (PyObject *)&SchedParamType);
Benjamin Petersone3298dd2011-08-02 18:40:46 -050013022#endif
Thomas Wouters477c8d52006-05-27 19:21:47 +000013023
Larry Hastings605a62d2012-06-24 04:33:36 -070013024 times_result_desc.name = MODNAME ".times_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013025 if (PyStructSequence_InitType2(&TimesResultType, &times_result_desc) < 0)
13026 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013027 PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType);
13028
13029 uname_result_desc.name = MODNAME ".uname_result";
Victor Stinner1c8f0592013-07-22 22:24:54 +020013030 if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) < 0)
13031 return NULL;
Larry Hastings605a62d2012-06-24 04:33:36 -070013032 PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType);
13033
Thomas Wouters477c8d52006-05-27 19:21:47 +000013034#ifdef __APPLE__
Victor Stinner8c62be82010-05-06 00:08:46 +000013035 /*
13036 * Step 2 of weak-linking support on Mac OS X.
13037 *
13038 * The code below removes functions that are not available on the
13039 * currently active platform.
13040 *
13041 * This block allow one to use a python binary that was build on
Larry Hastings9cf065c2012-06-22 16:30:09 -070013042 * OSX 10.4 on OSX 10.3, without losing access to new APIs on
Victor Stinner8c62be82010-05-06 00:08:46 +000013043 * OSX 10.4.
13044 */
Thomas Wouters477c8d52006-05-27 19:21:47 +000013045#ifdef HAVE_FSTATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013046 if (fstatvfs == NULL) {
13047 if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
13048 return NULL;
13049 }
13050 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013051#endif /* HAVE_FSTATVFS */
13052
13053#ifdef HAVE_STATVFS
Victor Stinner8c62be82010-05-06 00:08:46 +000013054 if (statvfs == NULL) {
13055 if (PyObject_DelAttrString(m, "statvfs") == -1) {
13056 return NULL;
13057 }
13058 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013059#endif /* HAVE_STATVFS */
13060
13061# ifdef HAVE_LCHOWN
Victor Stinner8c62be82010-05-06 00:08:46 +000013062 if (lchown == NULL) {
13063 if (PyObject_DelAttrString(m, "lchown") == -1) {
13064 return NULL;
13065 }
13066 }
Thomas Wouters477c8d52006-05-27 19:21:47 +000013067#endif /* HAVE_LCHOWN */
13068
13069
13070#endif /* __APPLE__ */
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013071
Antoine Pitrou9d20e0e2012-09-12 18:01:36 +020013072 Py_INCREF(&TerminalSizeType);
Antoine Pitroubcf2b592012-02-08 23:28:36 +010013073 PyModule_AddObject(m, "terminal_size", (PyObject*) &TerminalSizeType);
13074
Larry Hastings6fe20b32012-04-19 15:07:49 -070013075 billion = PyLong_FromLong(1000000000);
13076 if (!billion)
13077 return NULL;
13078
Larry Hastings9cf065c2012-06-22 16:30:09 -070013079 /* suppress "function not used" warnings */
13080 {
13081 int ignored;
13082 fd_specified("", -1);
13083 follow_symlinks_specified("", 1);
13084 dir_fd_and_follow_symlinks_invalid("chmod", DEFAULT_DIR_FD, 1);
13085 dir_fd_converter(Py_None, &ignored);
13086 dir_fd_unavailable(Py_None, &ignored);
13087 }
13088
13089 /*
13090 * provide list of locally available functions
13091 * so os.py can populate support_* lists
13092 */
13093 list = PyList_New(0);
13094 if (!list)
13095 return NULL;
13096 for (trace = have_functions; *trace; trace++) {
13097 PyObject *unicode = PyUnicode_DecodeASCII(*trace, strlen(*trace), NULL);
13098 if (!unicode)
13099 return NULL;
13100 if (PyList_Append(list, unicode))
13101 return NULL;
13102 Py_DECREF(unicode);
13103 }
13104 PyModule_AddObject(m, "_have_functions", list);
13105
13106 initialized = 1;
13107
Victor Stinner8c62be82010-05-06 00:08:46 +000013108 return m;
Guido van Rossumb6775db1994-08-01 11:34:53 +000013109}
Thomas Wouters49fd7fa2006-04-21 10:40:58 +000013110
13111#ifdef __cplusplus
13112}
13113#endif